CLIENT_LONG_PASSWORD

February 23, 2012

Today a little history lesson.

I was on a quest to find the origin of this line in include/mysql_com.h:

#define CLIENT_LONG_PASSWORD    1       /* new more secure passwords */

“new” ? “more secure” ?

These CLIENT_* flags are used between client and server to negotiate what capabilities they support. It allows the server to add new features to the protocol and let’s the client add support for it along the way. MySQL 5.5.x has 21 of these flags.

But back to CLIENT_LONG_PASSWORD and its wonderful comment. What would one expect if someone reads “new” and “more secure”?

new

Well, let’s check the file history:

$ bzr blame include/mysql_com.h
2            bk@work | #define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
$ bzr log -c 2
revno: 2
committer: bk@work.mysql.com
timestamp: Mon 2000-07-31 21:29:14 +0200

Hmm, 2000? MySQL is older than that. To the archives!

mysql-4.1.1-alpha/include/mysql_com.h:#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
mysql-4.1.0-alpha/include/mysql_com.h:#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
mysql-3.23.49/include/mysql_com.h:#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
mysql-3.22.32/include/mysql_com.h:#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
mysql-3.21.33b/include/mysql_com.h:#define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */

First non-match: 3.20.x. The whole feature of capabilities was added in 3.21.x and CLIENT_LONG_PASSWORD was its first use-case.

$ ls -ls mysql-3.21.33b/include/mysql_com.h
16 -rw-r--r--  1 jan  staff  5173 Jul  8  1998 mysql-3.21.33b/include/mysql_com.h

Since 14 years this is new.

more secure

More secure it says. Well, this flag is used by the function check_scramble() to flip some more bits (if set, old_ver == FALSE):

my_bool check_scramble(const char *scramble, const char *message,
                   ulong *hash_pass, my_bool old_ver)
{
  struct rand_struct rand;
  ulong hash_message[2];
  char buff[16],*to,extra;                  /* Big enough for check */
  const char *pos;

  hash_password(hash_message,message);
  if (old_ver)
    old_randominit(&rand,hash_pass[0] ^ hash_message[0]);
  else
    randominit(&rand,hash_pass[0] ^ hash_message[0],
           hash_pass[1] ^ hash_message[1]);
  to=buff;
  for (pos=scramble ; *pos ; pos++)
    *to++=(char) (floor(rnd(&rand)*31)+64);
  if (old_ver)
    extra=0;
  else
    extra=(char) (floor(rnd(&rand)*31));
  to=buff;
  while (*scramble)
  {
    if (*scramble++ != (char) (*to++ ^ extra))
      return 1;                                     /* Wrong password */
  }
  return 0;
}

That is the OLD_PASSWORD() which had a VERY_OLD_PASSWORD() variant it seems. Both of them are broken and shouldn’t be used anymore.

essence

Luckily this flag lost its meaning a long time ago. Since 4.1.x it is assumed that it is always set and since the same release there is a SHA1-based hashing for your passwords. No one gets harmed.

Perhaps someone should update the comment of that flag though.

mysql-protocol

Comments

Enable javascript to load comments.