Quellcode durchsuchen

Merge branch 'one-way-passwords'

* one-way-passwords:
  * Clear out the old PASS1 record once a PASS2 is set, but don't share this change
  * Share out the password in the hashed form
  * Fix conversion algorithm for password
  * Cleanse the buffer used for the temporary salted pass
  * Set the first character of the salted pass to +
  * Misc cleanup of pass_match code
  * Use the salt from their current password when comparing the given password
  * Dynamically lookup the name of the old pass type
  * Fix compile error, tmppass_set -> pass1_set
  * New userfile pass algorithm
  * Rename TMPPASS to PASS1 and USERENTRY_PASS to PASS2
Bryan Drewery vor 17 Jahren
Ursprung
Commit
f28d20789a
6 geänderte Dateien mit 55 neuen und 97 gelöschten Zeilen
  1. 2 0
      doc/UPDATES
  2. 16 63
      src/crypt.c
  3. 1 2
      src/crypt.h
  4. 15 10
      src/userent.c
  5. 20 21
      src/userrec.c
  6. 1 1
      src/users.h

+ 2 - 0
doc/UPDATES

@@ -1,3 +1,5 @@
+* New userfile pass algorithm
+
 1.2.17 - http://wraith.botpack.net/milestone/1.2.17
 * Binary pass prompt has been changed to be more clear.
 * Fix uname checking on NetBSD and OpenBSD

+ 16 - 63
src/crypt.c

@@ -133,13 +133,7 @@ void encrypt_cmd_pass(char *in, char *out)
   free(tmp);
 }
 
-static char *user_key(struct userrec *u)
-{
-  /* FIXME: fix after 1.2.3 */
-  return u->handle;
-}
-
-char *encrypt_pass(struct userrec *u, char *in)
+char *encrypt_pass(struct userrec *u, char *in, const char *saltin)
 {
   char *tmp = NULL, buf[101] = "", *ret = NULL;
   size_t ret_size = 0;
@@ -147,69 +141,28 @@ char *encrypt_pass(struct userrec *u, char *in)
   if (strlen(in) > MAXPASSLEN)
     in[MAXPASSLEN] = 0;
 
-  const char salt2[] = SALT2;
-  simple_snprintf(buf, sizeof(buf), STR("%s-%s"), salt2, in);
-
-  tmp = encrypt_string(user_key(u), buf);
-  OPENSSL_cleanse(buf, sizeof(buf));
-  ret_size = strlen(tmp) + 1 + 1;
-  ret = (char *) my_calloc(1, ret_size);
-
-  simple_snprintf(ret, ret_size, STR("+%s"), tmp);
-  free(tmp);
-
-  return ret;
-}
-
-char *decrypt_pass(struct userrec *u)
-{
-  char *tmp = NULL, *p = NULL, *ret = NULL, *pass = NULL;
-  
-  pass = (char *) get_user(&USERENTRY_PASS, u);
-  if (pass && pass[0] == '+') {
-    tmp = decrypt_string(user_key(u), &pass[1]);
-    if ((p = strchr(tmp, '-')))
-      ret = strdup(++p); 
-    OPENSSL_cleanse(tmp, strlen(tmp));
-    free(tmp);
+  /* Create a 5 byte salt */
+  char salt[6] = "";
+  if (saltin) {
+    strlcpy(salt, saltin, sizeof(salt));
+  } else {
+    make_rand_str(salt, sizeof(salt) - 1);
   }
-  if (!ret)
-    ret = (char *) my_calloc(1, 1);
 
-  return ret;
-}
-
-/*
-static char *passkey()
-{
-  static char key[SHA1_HASH_LENGTH + 1] = "";
+  /* SHA1 the salt+password */
+  simple_snprintf(buf, sizeof(buf), STR("%s%s"), salt, in);
+  tmp = SHA1(buf);
 
-  if (key[0])
-    return key;
-
-  char *tmp = my_calloc(1, 512);
+  ret_size = 1 + (sizeof(salt) - 1) + 1 + SHA_HASH_LENGTH + 1;
+  ret = (char *) my_calloc(1, ret_size);
+  simple_snprintf(ret, ret_size, STR("+%s$%s"), salt, tmp);
 
-  simple_snprintf(tmp, sizeof(tmp), "%s-%s.%s!%s", settings.salt1, settings.salt2, settings.packname, settings.bdhash);
-  key = SHA1(tmp);
-  free(tmp);
-  egg_bzero(tmp, 512);
+  /* Wipe cleartext pass from sha1 buffers/tmp */
+  SHA1(NULL);
 
-  return key;
+  return ret;
 }
 
-void encrypt_pass_new(char *s1, char *s2)
-{
-  char *tmp = NULL;
-
-  if (strlen(s1) > MAXPASSLEN)
-    s1[MAXPASSLEN] = 0;
-  tmp = encrypt_string(s1, passkey);
-  strcpy(s2, "+");
-  strlcat(s2, tmp, MAXPASSLEN + 1);
-  s2[MAXPASSLEN] = 0;
-  free(tmp);
-}
-*/
 int lfprintf (FILE *stream, const char *format, ...)
 {
   va_list va;

+ 1 - 2
src/crypt.h

@@ -25,8 +25,7 @@ unsigned char *decrypt_binary(const char *, unsigned char *, size_t *);
 char *encrypt_string(const char *, char *);
 char *decrypt_string(const char *, char *);
 void encrypt_cmd_pass(char *, char *);
-char *encrypt_pass(struct userrec *, char *);
-char *decrypt_pass(struct userrec *);
+char *encrypt_pass(struct userrec *, char *, const char* = NULL);
 char *cryptit (char *);
 char *decryptit (char *);
 int lfprintf (FILE *, const char *, ...) __attribute__((format(printf, 2, 3)));

+ 15 - 10
src/userent.c

@@ -52,7 +52,7 @@ void init_userent()
   add_entry_type(&USERENTRY_ARCH);
   add_entry_type(&USERENTRY_OSVER);
   add_entry_type(&USERENTRY_PASS);
-  add_entry_type(&USERENTRY_TMPPASS);
+  add_entry_type(&USERENTRY_PASS1);
   add_entry_type(&USERENTRY_SECPASS);
   add_entry_type(&USERENTRY_HOSTS);
   add_entry_type(&USERENTRY_STATS);
@@ -589,10 +589,16 @@ static bool pass_set(struct userrec *u, struct user_entry *e, void *buf)
     else
       newpass = encrypt_pass(u, pass);
     e->u.extra = strdup(newpass);
-    free(newpass);
   }
   if (!noshare)
-    shareout("c %s %s %s\n", e->type->name, u->handle, pass ? pass : "");
+    shareout("c %s %s %s\n", e->type->name, u->handle, newpass ? newpass : "");
+  if (newpass)
+    free(newpass);
+
+  /* clear old records */
+  noshare = 1;
+  set_user(&USERENTRY_PASS1, u, NULL);
+  noshare = 0;
   return 1;
 }
 
@@ -606,11 +612,10 @@ struct user_entry_type USERENTRY_PASS =
   def_get,
   pass_set,
   NULL,
-  "PASS1"
+  "PASS2"
 };
 
-/* FIXME: remove after 1.2.3 */
-static bool tmppass_set(struct userrec *u, struct user_entry *e, void *buf)
+static bool pass1_set(struct userrec *u, struct user_entry *e, void *buf)
 {
   register char *pass = (char *) buf;
 
@@ -632,11 +637,11 @@ static bool tmppass_set(struct userrec *u, struct user_entry *e, void *buf)
       e->u.extra = encrypt_string(u->handle, pass);
   }
   if (!noshare)
-    shareout("c TMPPASS %s %s\n", u->handle, pass ? pass : "");
+    shareout("c %s %s %s\n", e->type->name, u->handle, pass ? pass : "");
   return 1;
 }
 
-struct user_entry_type USERENTRY_TMPPASS =
+struct user_entry_type USERENTRY_PASS1 =
 {
   0,
   def_gotshare,
@@ -644,9 +649,9 @@ struct user_entry_type USERENTRY_TMPPASS =
   def_write_userfile,
   def_kill,
   def_get,
-  tmppass_set,
+  pass1_set,
   NULL,
-  "TMPPASS"
+  "PASS1"
 };
 
 

+ 20 - 21
src/userrec.c

@@ -291,26 +291,28 @@ bool user_has_host(const char *handle, struct userrec *u, char *host)
 
 void convert_password(struct userrec *u)
 {
-  char *oldpass = (char *) get_user(&USERENTRY_TMPPASS, u);
+  char *oldpass = (char *) get_user(&USERENTRY_PASS1, u);
 
   if (oldpass && oldpass[0]) {
-    char *pass = NULL;
+    char *pass = NULL, *passp = NULL;
     /* need to convert into new password format and remove old */
 
     /* --------- this changes to reflect how to decrypt old password --------- */
-    pass = decrypt_string(u->handle, oldpass);
+    passp = pass = decrypt_string(u->handle, &oldpass[1]);
+    /* Advance pass over the salt */
+    pass += 17;
     /* ----------------------------------------------------------------------- */
 
     if (strlen(pass) > MAXPASSLEN)
       pass[MAXPASSLEN] = 0;
 
     set_user(&USERENTRY_PASS, u, pass);
-    OPENSSL_cleanse(pass, strlen(pass));
-    free(pass);
+    OPENSSL_cleanse(passp, strlen(passp));
+    free(passp);
 
     /* clear old record */
     noshare = 1;
-    set_user(&USERENTRY_TMPPASS, u, NULL);
+    set_user(&USERENTRY_PASS1, u, NULL);
     noshare = 0;
   }
   
@@ -326,23 +328,23 @@ int u_pass_match(struct userrec *u, char *in)
 
   convert_password(u);
 
-  char *cmp = (char *) get_user(&USERENTRY_PASS, u), pass[MAXPASSLEN + 1] = "";
+  const char *cmp = (const char *) get_user(&USERENTRY_PASS, u);
 
-  strlcpy(pass, in, sizeof(pass));
-
-  if (!cmp && (!pass[0] || (pass[0] == '-')))
+  if (!cmp && (!in[0] || (in[0] == '-')))
     return 1;
-  if (!cmp || !pass[0] || (pass[0] == '-'))
+  if (!cmp || !in[0] || (in[0] == '-'))
     return 0;
   if (u->bot) {
-    if (!strcmp(cmp, pass))
+    if (!strcmp(cmp, in))
       return 1;
   } else {
-    char *newpass = NULL;
+    char pass[MAXPASSLEN + 1] = "";
 
-    if (strlen(pass) > MAXPASSLEN)
-      pass[MAXPASSLEN] = 0;
-    newpass = encrypt_pass(u, pass);
+    strlcpy(pass, in, sizeof(pass));
+
+    /* Pass the salted pass in so the same salt can be used */
+    char* newpass = encrypt_pass(u, in, &cmp[1]);
+    OPENSSL_cleanse(pass, sizeof(pass));
     if (!strcmp(cmp, newpass)) {
       free(newpass);
       return 1;
@@ -543,14 +545,11 @@ int change_handle(struct userrec *u, char *newh)
   if (!noshare)
     shareout("h %s %s\n", u->handle, newh);
 
-  char s[HANDLEN + 1] = "", *pass = NULL;
+  char s[HANDLEN + 1] = "";
 
-  pass = decrypt_pass(u);
   strlcpy(s, u->handle, sizeof s);
   strlcpy(u->handle, newh, sizeof u->handle);
-  set_user(&USERENTRY_PASS, u, pass);
-  OPENSSL_cleanse(pass, strlen(pass));
-  free(pass);
+
   for (int i = 0; i < dcc_total; i++)
     if (dcc[i].type && dcc[i].type != &DCC_BOT && !egg_strcasecmp(dcc[i].nick, s)) {
       strlcpy(dcc[i].nick, newh, sizeof dcc[i].nick);

+ 1 - 1
src/users.h

@@ -47,7 +47,7 @@ extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
  USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS,
  USERENTRY_PASS, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_MODIFIED,
  USERENTRY_SET, USERENTRY_SECPASS, USERENTRY_USERNAME, USERENTRY_NODENAME, USERENTRY_OS,
- USERENTRY_TMPPASS, USERENTRY_ARCH, USERENTRY_OSVER;
+ USERENTRY_PASS1, USERENTRY_ARCH, USERENTRY_OSVER;
 
 struct laston_info {
   time_t laston;