From abe555356a3129e468459288ca411d31857b4389 Mon Sep 17 00:00:00 2001
From: unknown <peter@mysql.com>
Date: Sun, 6 Oct 2002 13:42:16 +0400
Subject: One more commit to do the merge of new 4.1 tree

client/mysqladmin.c:
  Handle new password.c prototypes
include/mysql_com.h:
  New prototypes
libmysql/Makefile.shared:
  Client need sha1 compiled in now
libmysql/password.c:
  Replace copy with symlink
mysql-test/r/func_crypt.result:
  Fix test results to handle new password function
mysql-test/t/func_crypt.test:
  New tests for new password function
sql/item_create.cc:
  add old_password() function
sql/item_create.h:
  add old_password() function
sql/item_strfunc.cc:
  add old_password() function
  changes to new password.c functions prototypes
sql/item_strfunc.h:
  add old_password function
  handle new prototypes
sql/lex.h:
  add OLD_PASSWORD function
sql/password.c:
  Continue to work on new password handling
sql/sql_acl.cc:
  Handle new passwords
sql/sql_yacc.yy:
  Changes for new prototypes
---
 sql/password.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

(limited to 'sql/password.c')

diff --git a/sql/password.c b/sql/password.c
index 1875bb0ef04..ba7dc17c671 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -46,7 +46,6 @@
 #define PVERSION41_CHAR '*'
 
 
-extern my_bool opt_old_passwords; /* If prior 4.1 functions to be used */
 
 
 
@@ -95,14 +94,17 @@ void hash_password(ulong *result, const char *password)
 }
 
 
-void make_scrambled_password(char *to,const char *password)
+
+
+
+void make_scrambled_password(char *to,const char *password,my_bool force_old_scramble)
 { 
   ulong hash_res[2];  /* Used for pre 4.1 password hashing */
   static uint salt=0; /* Salt for 4.1 version password */
   unsigned char* slt=(unsigned char*)&salt;
   SHA1_CONTEXT context; 
   uint8 digest[SHA1_HASH_SIZE];
-  if (opt_old_passwords) /* Pre 4.1 password encryption */
+  if (force_old_scramble) /* Pre 4.1 password encryption */
   {
     hash_password(hash_res,password);
     sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
@@ -125,23 +127,33 @@ void make_scrambled_password(char *to,const char *password)
       sha1_input(&context,(int8*)&password[0],1);	
     }
     sha1_result(&context,digest);
+    /* Hash one more time */
+    sha1_reset(&context);
+    sha1_input(&context,digest,SHA1_HASH_SIZE);
+    sha1_result(&context,digest);
     /* Print resulting hash into the password*/
     sprintf(&(to[5]),
       "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
       digest[0],digest[1],digest[2],digest[3],digest[4],digest[5],digest[6],
       digest[7],digest[8],digest[9],digest[10],digest[11],digest[12],digest[13],
-      digest[14],digest[15],digest[16],digest[17],digest[18],digest[19]); 
-      
+      digest[14],digest[15],digest[16],digest[17],digest[18],digest[19]);         
   }
 }
 
-uint get_password_length()
+uint get_password_length(my_bool force_old_scramble)
 {
-  if (opt_old_passwords)
+  if (force_old_scramble)
     return 16;
   else return SHA1_HASH_SIZE*2+4+1;
 }
 
+uint8 get_password_version(const char* password)
+{
+  if (password==NULL) return 0;
+  if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR;
+  return 0;
+}
+
 
 inline uint char_val(char X)
 {
@@ -151,15 +163,27 @@ inline uint char_val(char X)
 }
 
 /*
-** This code assumes that len(password) is divideable with 8 and that
-** res is big enough (2 in mysql)
+** This code detects new version password by leading char. 
+** Old password has to be divisible by 8 length
+** do not forget to increase array length if you need longer passwords
 */
 
 void get_salt_from_password(ulong *res,const char *password)
 {
-  res[0]=res[1]=0;
+  bzero(res,5*sizeof(res[0]));
   if (password)
   {
+    if (password[0]==PVERSION41_CHAR) // if new password
+    {
+      uint val=0;
+      uint i;
+      password++; // skip version identifier.
+      //get hashing salt from password and store in in the start of array
+      
+      for (i=0 ; i < 4 ; i++)
+	val=(val << 4)+char_val(*password++);
+      *res++=val; 
+    }
     while (*password)
     {
       ulong val=0;
@@ -167,13 +191,14 @@ void get_salt_from_password(ulong *res,const char *password)
       for (i=0 ; i < 8 ; i++)
 	val=(val << 4)+char_val(*password++);
       *res++=val;
-    }
+    }    
   }
   return;
 }
 
 void make_password_from_salt(char *to, ulong *hash_res)
 {
+  // warning this does not work for new passwords yet
   sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
 }
 
-- 
cgit v1.2.1