Fix for RFC2868 problem in CVS version of radius
Maurice Makaay <[email protected]> Sun, 2 Nov 2003 02:40:40 +0100
| Newsgroups | gmane.comp.gnu.radius.bugs |
|---|---|
| Organization | InterNLnet BV |
| Message-ID | <[email protected]> |
Hi, The RFC2868 implementation is not correct currently. It is now implemented like this: byte1 byte2 byte3 byte4 rest +--------+--------+--------+--------+--------------------------- |tag |passlen |salt |salt |encrypted password .... +--------+--------+--------+--------+--------------------------- But this should be: byte1 byte2 byte3 rest +--------+--------+--------+------------------------------------ |tag |salt |salt |encrypted passlen + password .... +--------+--------+--------+------------------------------------ So the encrypted text contains of the password length concatenated with the password string. I attached a diff for cryptpass.c which fixes this bug. There's also a little fix in the call for encrypt_text(). The salt is of type unsigned short in crypt_tunnel_password() and of type unsigned char in encrypt_text(). This resulted in a compiler warning. With this patch applied I just successfully setup a tunnel connection, so the encryption part is correct. I also updated the decryption part. I think it is correct, but I haven't really tested it (following the invaluable "It compiles, ship it!" philosophy ;-) and because I don't know how to test this easily). Regards, -- Maurice Makaay _______________________________________________ Bug-gnu-radius mailing list [email protected] http://mail.gnu.org/mailman/listinfo/bug-gnu-radius
cryptpass.c.diff
(text/plain, 2.4 KB)
Index: cryptpass.c
===================================================================
RCS file: /cvsroot/radius/radius/lib/cryptpass.c,v
retrieving revision 1.6
diff -u -r1.6 cryptpass.c
--- cryptpass.c 1 Nov 2003 13:44:40 -0000 1.6
+++ cryptpass.c 2 Nov 2003 01:35:11 -0000
@@ -1,4 +1,4 @@
-/* This file is part of GNU Radius.
+/* this file is part of GNU Radius.
Copyright (C) 2000,2001,2002,2003 Sergey Poznyakoff
GNU Radius is free software; you can redistribute it and/or modify
@@ -252,22 +252,33 @@
char *vector, /* Request authenticator */
char *secret) /* Shared secret */
{
+ int len;
+ u_char *encr_string;
u_char *encr_text;
size_t encr_size;
unsigned short salt;
salt = htons( (((long)pair ^ *(long *)vector) & 0xffff) | 0x8000 );
+
+ /* RFC2868 requires that the encrypted string contains the
+ original length of the password as the first byte of the
+ string and the password itself. */
+ len = strlen(password);
+ encr_string = emalloc(2 + len);
+ *encr_string = len;
+ memcpy(encr_string + 1, password, len);
+ encr_string[len + 1] = 0;
encrypt_text(&encr_text, &encr_size,
- password, vector, secret,
- &salt, 2);
+ encr_string, vector, secret,
+ (unsigned char *)&salt, 2);
- pair->avp_strlength = 4 + encr_size;
+ pair->avp_strlength = 3 + encr_size;
pair->avp_strvalue = emalloc(pair->avp_strlength);
pair->avp_strvalue[0] = tag;
- pair->avp_strvalue[1] = strlen(password);
- memcpy(&pair->avp_strvalue[2], &salt, 2);
- memcpy(&pair->avp_strvalue[4], encr_text, encr_size);
+ memcpy(&pair->avp_strvalue[1], &salt, 2);
+ memcpy(&pair->avp_strvalue[3], encr_text, encr_size);
+ efree(encr_string);
efree(encr_text);
}
@@ -279,13 +290,23 @@
char *vector, /* Request authenticator */
char *secret) /* Shared secret */
{
+ int len, i;
+
decrypt_text(password,
- pair->avp_strvalue + 4,
- pair->avp_strlength - 4,
+ pair->avp_strvalue + 3,
+ pair->avp_strlength - 3,
vector,
secret,
- &pair->avp_strvalue[2],
+ &pair->avp_strvalue[1],
2);
- password[pair->avp_strvalue[1]] = 0;
+
+ /* The first byte of the decrypted string contains the length of
+ the password string, so we'll have to do a bit of shifting
+ to get our password. */
+ len = *password;
+ for (i = 0; i < len; i++)
+ password[i] = password[i + 1];
+ password[len] = 0;
+
*tag = pair->avp_strvalue[0];
}