add a new command, md5crypt.
This commit is contained in:
parent
06adfc82ff
commit
4928cfdad2
7 changed files with 234 additions and 86 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2000-10-21 OKUJI Yoshinori <okuji@gnu.org>
|
||||||
|
|
||||||
|
* stage2/md5.c (check_md5_password): Removed.
|
||||||
|
(md5_password): New function. Mostly copied from
|
||||||
|
check_md5_password.
|
||||||
|
(md5_init): Made static.
|
||||||
|
(md5_update): Likewise.
|
||||||
|
(md5_final): Likewise.
|
||||||
|
* stage2/md5.h (check_md5_password): Changed to just a macro.
|
||||||
|
(md5_password): Declared.
|
||||||
|
(make_md5_password): New macro.
|
||||||
|
* stage2/char_io.c [!STAGE1_5] (grub_strstr): Rewriten, because
|
||||||
|
it was too buggy.
|
||||||
|
* stage2/builtins.c [USE_MD5_PASSWORDS] (md5crypt_func): New
|
||||||
|
function.
|
||||||
|
[USE_MD5_PASSWORDS] (builtin_md5crypt): New variable.
|
||||||
|
(builtin_table) [USE_MD5_PASSWORDS]: Added a pointer to
|
||||||
|
BUILTIN_MD5CRYPT.
|
||||||
|
* docs/tutorial.texi (Security): Added a paragraph about
|
||||||
|
md5crypt.
|
||||||
|
|
||||||
2000-10-21 OKUJI Yoshinori <okuji@gnu.org>
|
2000-10-21 OKUJI Yoshinori <okuji@gnu.org>
|
||||||
|
|
||||||
* docs/user-ref.texi: Fixed several typos and some inappropriate
|
* docs/user-ref.texi: Fixed several typos and some inappropriate
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -11,6 +11,7 @@ New in 1.0 - XXXX-XX-XX:
|
||||||
is given. This command can now also be used to protect specific menu
|
is given. This command can now also be used to protect specific menu
|
||||||
items with their own passwords.
|
items with their own passwords.
|
||||||
* New command, "displayapm".
|
* New command, "displayapm".
|
||||||
|
* New command, "md5crypt".
|
||||||
|
|
||||||
New in 0.5.96 - 2000-10-04:
|
New in 0.5.96 - 2000-10-04:
|
||||||
* New commands, "reboot" and "halt".
|
* New commands, "reboot" and "halt".
|
||||||
|
|
|
@ -984,8 +984,22 @@ password --md5 PASSWORD
|
||||||
|
|
||||||
If this is specified, GRUB disallows any interactive control, until you
|
If this is specified, GRUB disallows any interactive control, until you
|
||||||
press the key @key{p} and enter @samp{PASSWORD}. The option
|
press the key @key{p} and enter @samp{PASSWORD}. The option
|
||||||
@option{--md5} tells GRUB that @samp{PASSWORD} is in md5 format. If it
|
@option{--md5} tells GRUB that @samp{PASSWORD} is in MD5 format. If it
|
||||||
is omitted grub assumes the @samp{PASSWORD} is in clear text.
|
is omitted, GRUB assumes the @samp{PASSWORD} is in clear text.
|
||||||
|
|
||||||
|
You can encrypt your password with the command @command{md5crypt}. For
|
||||||
|
example, run the grub shell (@pxref{Invoking the grub shell}), and enter
|
||||||
|
your password:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
grub> md5crypt
|
||||||
|
Password: **********
|
||||||
|
Encrypted: $1$U$JK7xFegdxWH6VuppCUSIb.
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Then, cut and paste the encrypted password to your configuration file.
|
||||||
|
|
||||||
Also, you can specify an optional argument to @command{password}. See
|
Also, you can specify an optional argument to @command{password}. See
|
||||||
this example:
|
this example:
|
||||||
|
|
|
@ -2370,6 +2370,67 @@ static struct builtin builtin_map =
|
||||||
" OS resides at a non-first drive."
|
" OS resides at a non-first drive."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_MD5_PASSWORDS
|
||||||
|
/* md5crypt */
|
||||||
|
static int
|
||||||
|
md5crypt_func (char *arg, int flags)
|
||||||
|
{
|
||||||
|
char crypted[36];
|
||||||
|
char key[32];
|
||||||
|
int saltlen;
|
||||||
|
int i;
|
||||||
|
const char *const seedchars =
|
||||||
|
"./0123456789ABCDEFGHIJKLMNOPQRST"
|
||||||
|
"UVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
/* First create a salt. */
|
||||||
|
|
||||||
|
/* The magical prefix. */
|
||||||
|
grub_memset (crypted, 0, sizeof (crypted));
|
||||||
|
grub_memmove (crypted, "$1$", 3);
|
||||||
|
|
||||||
|
/* Create the length of a salt. */
|
||||||
|
saltlen = currticks ();
|
||||||
|
saltlen &= 7;
|
||||||
|
saltlen++;
|
||||||
|
|
||||||
|
/* Generate a salt. */
|
||||||
|
for (i = 0; i < saltlen; i++)
|
||||||
|
{
|
||||||
|
/* FIXME: This should be more random. */
|
||||||
|
crypted[3 + i] = seedchars[(currticks () >> i) & 0x3f];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A salt must be terminated with `$', if it is less than 8 chars. */
|
||||||
|
if (saltlen != 8)
|
||||||
|
crypted[3 + i] = '$';
|
||||||
|
|
||||||
|
#ifdef DEBUG_MD5CRYPT
|
||||||
|
grub_printf ("salt = %s\n", crypted);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get a password. */
|
||||||
|
grub_memset (key, 0, sizeof (key));
|
||||||
|
get_cmdline ("Password: ", key, sizeof (key) - 1, '*', 0);
|
||||||
|
|
||||||
|
/* Crypt the key. */
|
||||||
|
make_md5_password (key, crypted);
|
||||||
|
|
||||||
|
grub_printf ("Encrypted: %s\n", crypted);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct builtin builtin_md5crypt =
|
||||||
|
{
|
||||||
|
"md5crypt",
|
||||||
|
md5crypt_func,
|
||||||
|
BUILTIN_CMDLINE,
|
||||||
|
"md5crypt",
|
||||||
|
"Generate a password in MD5 format."
|
||||||
|
};
|
||||||
|
#endif /* USE_MD5_PASSWORDS */
|
||||||
|
|
||||||
|
|
||||||
/* module */
|
/* module */
|
||||||
static int
|
static int
|
||||||
|
@ -4118,6 +4179,9 @@ struct builtin *builtin_table[] =
|
||||||
&builtin_lock,
|
&builtin_lock,
|
||||||
&builtin_makeactive,
|
&builtin_makeactive,
|
||||||
&builtin_map,
|
&builtin_map,
|
||||||
|
#ifdef USE_MD5_PASSWORDS
|
||||||
|
&builtin_md5crypt,
|
||||||
|
#endif /* USE_MD5_PASSWORDS */
|
||||||
&builtin_module,
|
&builtin_module,
|
||||||
&builtin_modulenounzip,
|
&builtin_modulenounzip,
|
||||||
&builtin_partnew,
|
&builtin_partnew,
|
||||||
|
|
|
@ -1282,17 +1282,20 @@ nul_terminate (char *str)
|
||||||
char *
|
char *
|
||||||
grub_strstr (const char *s1, const char *s2)
|
grub_strstr (const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
const char *ptr, *tmp;
|
|
||||||
|
|
||||||
while (*s1)
|
while (*s1)
|
||||||
{
|
{
|
||||||
|
const char *ptr, *tmp;
|
||||||
|
|
||||||
ptr = s1;
|
ptr = s1;
|
||||||
tmp = s2;
|
tmp = s2;
|
||||||
|
|
||||||
while (*s1 && *s1++ == *tmp++);
|
while (*tmp && *ptr == *tmp)
|
||||||
|
ptr++, tmp++;
|
||||||
|
|
||||||
if (tmp > s2 && !*(tmp - 1))
|
if (tmp > s2 && ! *tmp)
|
||||||
return (char *) ptr;
|
return (char *) s1;
|
||||||
|
|
||||||
|
s1++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
169
stage2/md5.c
169
stage2/md5.c
|
@ -23,17 +23,17 @@
|
||||||
|
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
#ifndef TEST
|
#ifndef TEST
|
||||||
#include <shared.h>
|
# include <shared.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include <string.h>
|
# include <string.h>
|
||||||
#define USE_MD5_PASSWORDS
|
# define USE_MD5_PASSWORDS
|
||||||
#define USE_MD5
|
# define USE_MD5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MD5_PASSWORDS
|
#ifdef USE_MD5_PASSWORDS
|
||||||
#define USE_MD5
|
# define USE_MD5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MD5
|
#ifdef USE_MD5
|
||||||
|
@ -53,7 +53,8 @@ typedef unsigned int UINT4;
|
||||||
*/
|
*/
|
||||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
|
||||||
|
|
||||||
static UINT4 initstate[4] = {
|
static UINT4 initstate[4] =
|
||||||
|
{
|
||||||
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
|
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,7 +63,8 @@ static char s2[4] = { 5, 9, 14, 20 };
|
||||||
static char s3[4] = { 4, 11, 16, 23 };
|
static char s3[4] = { 4, 11, 16, 23 };
|
||||||
static char s4[4] = { 6, 10, 15, 21 };
|
static char s4[4] = { 6, 10, 15, 21 };
|
||||||
|
|
||||||
static UINT4 T[64] = {
|
static UINT4 T[64] =
|
||||||
|
{
|
||||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||||
|
@ -88,11 +90,12 @@ static UINT4 state[4];
|
||||||
static unsigned int length;
|
static unsigned int length;
|
||||||
static unsigned char buffer[64];
|
static unsigned char buffer[64];
|
||||||
|
|
||||||
static void md5_transform (const unsigned char block[64])
|
static void
|
||||||
|
md5_transform (const unsigned char block[64])
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
UINT4 a,b,c,d,tmp;
|
UINT4 a,b,c,d,tmp;
|
||||||
const UINT4 *x = (UINT4*) block;
|
const UINT4 *x = (UINT4 *) block;
|
||||||
|
|
||||||
a = state[0];
|
a = state[0];
|
||||||
b = state[1];
|
b = state[1];
|
||||||
|
@ -102,7 +105,7 @@ static void md5_transform (const unsigned char block[64])
|
||||||
/* Round 1 */
|
/* Round 1 */
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
tmp = a + F(b, c, d) + le32_to_cpu(x[i]) + T[i];
|
tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i];
|
||||||
tmp = ROTATE_LEFT (tmp, s1[i & 3]);
|
tmp = ROTATE_LEFT (tmp, s1[i & 3]);
|
||||||
tmp += b;
|
tmp += b;
|
||||||
a = d; d = c; c = b; b = tmp;
|
a = d; d = c; c = b; b = tmp;
|
||||||
|
@ -110,7 +113,7 @@ static void md5_transform (const unsigned char block[64])
|
||||||
/* Round 2 */
|
/* Round 2 */
|
||||||
for (i = 0, j = 1; i < 16; i++, j += 5)
|
for (i = 0, j = 1; i < 16; i++, j += 5)
|
||||||
{
|
{
|
||||||
tmp = a + G(b, c, d) + le32_to_cpu(x[j & 15]) + T[i+16];
|
tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16];
|
||||||
tmp = ROTATE_LEFT (tmp, s2[i & 3]);
|
tmp = ROTATE_LEFT (tmp, s2[i & 3]);
|
||||||
tmp += b;
|
tmp += b;
|
||||||
a = d; d = c; c = b; b = tmp;
|
a = d; d = c; c = b; b = tmp;
|
||||||
|
@ -118,7 +121,7 @@ static void md5_transform (const unsigned char block[64])
|
||||||
/* Round 3 */
|
/* Round 3 */
|
||||||
for (i = 0, j = 5; i < 16; i++, j += 3)
|
for (i = 0, j = 5; i < 16; i++, j += 3)
|
||||||
{
|
{
|
||||||
tmp = a + H(b, c, d) + le32_to_cpu(x[j & 15]) + T[i+32];
|
tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32];
|
||||||
tmp = ROTATE_LEFT (tmp, s3[i & 3]);
|
tmp = ROTATE_LEFT (tmp, s3[i & 3]);
|
||||||
tmp += b;
|
tmp += b;
|
||||||
a = d; d = c; c = b; b = tmp;
|
a = d; d = c; c = b; b = tmp;
|
||||||
|
@ -126,7 +129,7 @@ static void md5_transform (const unsigned char block[64])
|
||||||
/* Round 4 */
|
/* Round 4 */
|
||||||
for (i = 0, j = 0; i < 16; i++, j += 7)
|
for (i = 0, j = 0; i < 16; i++, j += 7)
|
||||||
{
|
{
|
||||||
tmp = a + I(b, c, d) + le32_to_cpu(x[j & 15]) + T[i+48];
|
tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48];
|
||||||
tmp = ROTATE_LEFT (tmp, s4[i & 3]);
|
tmp = ROTATE_LEFT (tmp, s4[i & 3]);
|
||||||
tmp += b;
|
tmp += b;
|
||||||
a = d; d = c; c = b; b = tmp;
|
a = d; d = c; c = b; b = tmp;
|
||||||
|
@ -138,22 +141,26 @@ static void md5_transform (const unsigned char block[64])
|
||||||
state[3] += d;
|
state[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_init() {
|
static void
|
||||||
memcpy ((char *)state, (char *)initstate, sizeof (initstate));
|
md5_init(void)
|
||||||
|
{
|
||||||
|
memcpy ((char *) state, (char *) initstate, sizeof (initstate));
|
||||||
length = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_update(const char *input, int inputlen) {
|
static void
|
||||||
|
md5_update (const char *input, int inputlen)
|
||||||
|
{
|
||||||
int buflen = length & 63;
|
int buflen = length & 63;
|
||||||
length += inputlen;
|
length += inputlen;
|
||||||
if (buflen + inputlen < 64)
|
if (buflen + inputlen < 64)
|
||||||
{
|
{
|
||||||
memcpy(buffer + buflen, input, inputlen);
|
memcpy (buffer + buflen, input, inputlen);
|
||||||
buflen += inputlen;
|
buflen += inputlen;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer + buflen, input, 64 - buflen);
|
memcpy (buffer + buflen, input, 64 - buflen);
|
||||||
md5_transform (buffer);
|
md5_transform (buffer);
|
||||||
input += 64 - buflen;
|
input += 64 - buflen;
|
||||||
inputlen -= 64 - buflen;
|
inputlen -= 64 - buflen;
|
||||||
|
@ -163,11 +170,12 @@ void md5_update(const char *input, int inputlen) {
|
||||||
input += 64;
|
input += 64;
|
||||||
inputlen -= 64;
|
inputlen -= 64;
|
||||||
}
|
}
|
||||||
memcpy(buffer, input, inputlen);
|
memcpy (buffer, input, inputlen);
|
||||||
buflen = inputlen;
|
buflen = inputlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* md5_final()
|
static unsigned char *
|
||||||
|
md5_final()
|
||||||
{
|
{
|
||||||
int i, buflen = length & 63;
|
int i, buflen = length & 63;
|
||||||
|
|
||||||
|
@ -180,68 +188,86 @@ unsigned char* md5_final()
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(UINT4 *) (buffer + 56) = cpu_to_le32(8*length);
|
*(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length);
|
||||||
*(UINT4 *) (buffer + 60) = 0;
|
*(UINT4 *) (buffer + 60) = 0;
|
||||||
md5_transform (buffer);
|
md5_transform (buffer);
|
||||||
|
|
||||||
for (i=0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
state[i] = cpu_to_le32 (state[i]);
|
state[i] = cpu_to_le32 (state[i]);
|
||||||
return (unsigned char*) state;
|
return (unsigned char *) state;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MD5_PASSWORDS
|
#ifdef USE_MD5_PASSWORDS
|
||||||
/* Check a password for correctness. Returns 0 if password was
|
/* If CHECK is true, check a password for correctness. Returns 0
|
||||||
correct, and a value != 0 for error, similarly to strcmp. */
|
if password was correct, and a value != 0 for error, similarly
|
||||||
int check_md5_password (const char* key, const char* crypted) {
|
to strcmp.
|
||||||
int keylen = strlen(key);
|
If CHECK is false, crypt KEY and save the result in CRYPTED.
|
||||||
|
CRYPTED must have a salt. */
|
||||||
|
int
|
||||||
|
md5_password (const char *key, char *crypted, int check)
|
||||||
|
{
|
||||||
|
int keylen = strlen (key);
|
||||||
char *salt = crypted + 3; /* skip $1$ header */
|
char *salt = crypted + 3; /* skip $1$ header */
|
||||||
char *p;
|
char *p;
|
||||||
int saltlen = strstr(salt, "$") - salt;
|
int saltlen;
|
||||||
int i,n;
|
int i, n;
|
||||||
unsigned char alt_result[16];
|
unsigned char alt_result[16];
|
||||||
unsigned char *digest;
|
unsigned char *digest;
|
||||||
|
|
||||||
md5_init();
|
if (check)
|
||||||
md5_update(key, keylen);
|
saltlen = strstr (salt, "$") - salt;
|
||||||
md5_update(salt, saltlen);
|
else
|
||||||
md5_update(key, keylen);
|
{
|
||||||
digest = md5_final();
|
char *end = strstr (salt, "$");
|
||||||
memcpy(alt_result, digest, 16);
|
if (end && end - salt < 8)
|
||||||
|
saltlen = end - salt;
|
||||||
|
else
|
||||||
|
saltlen = 8;
|
||||||
|
|
||||||
memcpy ((char *)state, (char *)initstate, sizeof (initstate));
|
salt[saltlen] = '$';
|
||||||
|
}
|
||||||
|
|
||||||
|
md5_init ();
|
||||||
|
md5_update (key, keylen);
|
||||||
|
md5_update (salt, saltlen);
|
||||||
|
md5_update (key, keylen);
|
||||||
|
digest = md5_final ();
|
||||||
|
memcpy (alt_result, digest, 16);
|
||||||
|
|
||||||
|
memcpy ((char *) state, (char *) initstate, sizeof (initstate));
|
||||||
length = 0;
|
length = 0;
|
||||||
md5_update(key, keylen);
|
md5_update (key, keylen);
|
||||||
md5_update(crypted, 3 + saltlen); /* include the $1$ header */
|
md5_update (crypted, 3 + saltlen); /* include the $1$ header */
|
||||||
for (i = keylen; i > 16; i -= 16)
|
for (i = keylen; i > 16; i -= 16)
|
||||||
md5_update(alt_result, 16);
|
md5_update (alt_result, 16);
|
||||||
md5_update(alt_result, i);
|
md5_update (alt_result, i);
|
||||||
|
|
||||||
for (i = keylen; i > 0; i >>= 1)
|
for (i = keylen; i > 0; i >>= 1)
|
||||||
md5_update(key + ((i & 1) ? keylen : 0), 1);
|
md5_update (key + ((i & 1) ? keylen : 0), 1);
|
||||||
digest = md5_final();
|
digest = md5_final ();
|
||||||
|
|
||||||
for (i = 0; i < 1000; i++)
|
for (i = 0; i < 1000; i++)
|
||||||
{
|
{
|
||||||
memcpy(alt_result, digest, 16);
|
memcpy (alt_result, digest, 16);
|
||||||
|
|
||||||
memcpy ((char *)state, (char *)initstate, sizeof (initstate));
|
memcpy ((char *) state, (char *) initstate, sizeof (initstate));
|
||||||
length = 0;
|
length = 0;
|
||||||
if ((i & 1) != 0)
|
if ((i & 1) != 0)
|
||||||
md5_update(key, keylen);
|
md5_update (key, keylen);
|
||||||
else
|
else
|
||||||
md5_update(alt_result, 16);
|
md5_update (alt_result, 16);
|
||||||
|
|
||||||
if (i % 3 != 0)
|
if (i % 3 != 0)
|
||||||
md5_update(salt, saltlen);
|
md5_update (salt, saltlen);
|
||||||
|
|
||||||
if (i % 7 != 0)
|
if (i % 7 != 0)
|
||||||
md5_update(key, keylen);
|
md5_update (key, keylen);
|
||||||
|
|
||||||
if ((i & 1) != 0)
|
if ((i & 1) != 0)
|
||||||
md5_update(alt_result, 16);
|
md5_update (alt_result, 16);
|
||||||
else
|
else
|
||||||
md5_update(key, keylen);
|
md5_update (key, keylen);
|
||||||
digest = md5_final();
|
digest = md5_final ();
|
||||||
}
|
}
|
||||||
|
|
||||||
p = salt + saltlen + 1;
|
p = salt + saltlen + 1;
|
||||||
|
@ -250,35 +276,57 @@ int check_md5_password (const char* key, const char* crypted) {
|
||||||
unsigned int w =
|
unsigned int w =
|
||||||
digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
|
digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
|
||||||
for (n = 4; n-- > 0;)
|
for (n = 4; n-- > 0;)
|
||||||
|
{
|
||||||
|
if (check)
|
||||||
{
|
{
|
||||||
if (*p++ != b64t[w & 0x3f])
|
if (*p++ != b64t[w & 0x3f])
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p++ = b64t[w & 0x3f];
|
||||||
|
}
|
||||||
|
|
||||||
w >>= 6;
|
w >>= 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
unsigned int w = digest[11];
|
unsigned int w = digest[11];
|
||||||
for (n = 2; n-- > 0;)
|
for (n = 2; n-- > 0;)
|
||||||
|
{
|
||||||
|
if (check)
|
||||||
{
|
{
|
||||||
if (*p++ != b64t[w & 0x3f])
|
if (*p++ != b64t[w & 0x3f])
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p++ = b64t[w & 0x3f];
|
||||||
|
}
|
||||||
|
|
||||||
w >>= 6;
|
w >>= 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! check)
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
return *p;
|
return *p;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
static char* md5 (const char* input)
|
static char *
|
||||||
|
md5 (const char *input)
|
||||||
{
|
{
|
||||||
memcpy ((char *)state, (char *)initstate, sizeof (initstate));
|
memcpy ((char *) state, (char *) initstate, sizeof (initstate));
|
||||||
length = 0;
|
length = 0;
|
||||||
md5_update(input, strlen (input));
|
md5_update (input, strlen (input));
|
||||||
return md5_final();
|
return md5_final ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test (char *buffer, char *expected)
|
static void
|
||||||
|
test (char *buffer, char *expected)
|
||||||
{
|
{
|
||||||
char result[16 * 3 +1];
|
char result[16 * 3 +1];
|
||||||
unsigned char* digest = md5 (buffer);
|
unsigned char* digest = md5 (buffer);
|
||||||
|
@ -293,7 +341,8 @@ static void test (char *buffer, char *expected)
|
||||||
printf ("MD5(%s) OK\n", buffer);
|
printf ("MD5(%s) OK\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main ()
|
int
|
||||||
|
main (void)
|
||||||
{
|
{
|
||||||
test ("", "d41d8cd98f00b204e9800998ecf8427e");
|
test ("", "d41d8cd98f00b204e9800998ecf8427e");
|
||||||
test ("a", "0cc175b9c0f1b6a831c399e269772661");
|
test ("a", "0cc175b9c0f1b6a831c399e269772661");
|
||||||
|
@ -315,11 +364,11 @@ int main ()
|
||||||
test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
|
test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
|
||||||
"80063db1e6b70a2e91eac903f0e46b85");
|
"80063db1e6b70a2e91eac903f0e46b85");
|
||||||
|
|
||||||
if (check_md5_password("Hello world!",
|
if (check_md5_password ("Hello world!",
|
||||||
"$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
|
"$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
|
||||||
printf("Password differs\n");
|
printf ("Password differs\n");
|
||||||
else
|
else
|
||||||
printf("Password OK\n");
|
printf ("Password OK\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
22
stage2/md5.h
22
stage2/md5.h
|
@ -18,17 +18,13 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Initialize the buffers to compute a new md5 checksum. This will
|
/* If CHECK is true, check a password for correctness. Returns 0
|
||||||
destroy any previously calculated md5 sum. */
|
if password was correct, and a value != 0 for error, similarly
|
||||||
extern void md5_init(void);
|
to strcmp.
|
||||||
|
If CHECK is false, crypt KEY and save the result in CRYPTED.
|
||||||
|
CRYPTED must have a salt. */
|
||||||
|
extern int md5_password (const char *key, char *crypted, int check);
|
||||||
|
|
||||||
/* Digestify the given input. This may be called multiple times. */
|
/* For convenience. */
|
||||||
extern void md5_update(const char *input, int inputlen);
|
#define check_md5_password(key,crypted) md5_password((key), (crypted), 1)
|
||||||
|
#define make_md5_password(key,crypted) md5_password((key), (crypted), 0)
|
||||||
/* Calculate the 16 byte md5 check sum. The result will be valid until
|
|
||||||
the next md5_init(). */
|
|
||||||
extern unsigned char* md5_final(void);
|
|
||||||
|
|
||||||
/* Check a md5 password for validity. Returns 0 if password was
|
|
||||||
correct, and a value != 0 for error, similarly to strcmp. */
|
|
||||||
extern int check_md5_password (const char* key, const char* crypted);
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue