krb5 commit: Simplify LDAP password decoding

Greg Hudson ghudson at MIT.EDU
Fri Feb 1 02:16:59 EST 2013


https://github.com/krb5/krb5/commit/1f6d917fb52be81c9d009d7c10177d1193bf5ae1
commit 1f6d917fb52be81c9d009d7c10177d1193bf5ae1
Author: Greg Hudson <ghudson at mit.edu>
Date:   Fri Feb 1 02:14:45 2013 -0500

    Simplify LDAP password decoding
    
    Make dec_password a static function in ldap_service_stash.c and remove
    some impedance mismatch with krb5_ldap_readpassword() by making it
    operate on C strings and return a krb5_error_code.

 .../kdb/ldap/libkdb_ldap/ldap_service_stash.c      |  146 ++++++--------------
 .../kdb/ldap/libkdb_ldap/ldap_service_stash.h      |   12 --
 2 files changed, 45 insertions(+), 113 deletions(-)

diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
index b6f5413..9985a1b 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
@@ -33,6 +33,50 @@
 #include "kdb_ldap.h"
 #include "ldap_service_stash.h"
 
+/* Decode a password of the form {HEX}<hexstring>. */
+static krb5_error_code
+dec_password(krb5_context context, const char *str,
+             unsigned char **password_out)
+{
+    size_t len;
+    const unsigned char *p;
+    unsigned char *password, *q;
+    unsigned int k;
+
+    *password_out = NULL;
+
+    if (strncmp(str, "{HEX}", 5) != 0) {
+        krb5_set_error_message(context, EINVAL,
+                               _("Not a hexadecimal password"));
+        return EINVAL;
+    }
+    str += 5;
+
+    len = strlen(str);
+    if (len % 2 != 0) {
+        krb5_set_error_message(context, EINVAL, _("Password corrupt"));
+        return EINVAL;
+    }
+
+    q = password = malloc(len / 2 + 1);
+    if (password == NULL)
+        return ENOMEM;
+
+    for (p = (unsigned char *)str; *p != '\0'; p += 2) {
+        if (!isxdigit(*p) || !isxdigit(p[1])) {
+            free(password);
+            krb5_set_error_message(context, EINVAL, _("Password corrupt"));
+            return EINVAL;
+        }
+        sscanf((char *)p, "%2x", &k);
+        *q++ = k;
+    }
+    *q = '\0';
+
+    *password_out = password;
+    return 0;
+}
+
 krb5_error_code
 krb5_ldap_readpassword(krb5_context context, krb5_ldap_context *ldap_context,
                        unsigned char **password)
@@ -42,7 +86,6 @@ krb5_ldap_readpassword(krb5_context context, krb5_ldap_context *ldap_context,
     char                        line[RECORDLEN]="0", *start=NULL, *file=NULL;
     char                        errbuf[1024];
     FILE                        *fptr=NULL;
-    struct data                 PT, CT;
 
     *password = NULL;
 
@@ -120,34 +163,7 @@ krb5_ldap_readpassword(krb5_context context, krb5_ldap_context *ldap_context,
     ++ start;
 
     /* Extract the plain password information. */
-    CT.value = (unsigned char *)start;
-    CT.len = strlen((char *)CT.value);
-    st = dec_password(CT, &PT);
-    if (st != 0) {
-        switch (st) {
-        case ERR_NO_MEM:
-            st = ENOMEM;
-            break;
-        case ERR_PWD_ZERO:
-            st = EINVAL;
-            krb5_set_error_message(context, st, _("Password has zero length"));
-            break;
-        case ERR_PWD_BAD:
-            st = EINVAL;
-            krb5_set_error_message(context, st, _("Password corrupted"));
-            break;
-        case ERR_PWD_NOT_HEX:
-            st = EINVAL;
-            krb5_set_error_message(context, st,
-                                   _("Not a hexadecimal password"));
-            break;
-        default:
-            st = KRB5_KDB_SERVER_INTERNAL_ERR;
-            break;
-        }
-        goto rp_exit;
-    }
-    *password = PT.value;
+    st = dec_password(context, start, password);
 
 rp_exit:
     if (st) {
@@ -188,75 +204,3 @@ cleanup:
 
     return err;
 }
-
-/* The entry in the password file will have the following format
- * <FQDN of service> = <secret>
- *   <secret> := {HEX}<password in hexadecimal>
- *
- * <password> is the actual eDirectory password of the service
- * Return values:
- * ERR_NO_MEM      - No Memory
- * ERR_PWD_ZERO    - Password has zero length
- * ERR_PWD_BAD     - Passowrd corrupted
- * ERR_PWD_NOT_HEX - Not a hexadecimal password
- */
-
-int
-dec_password(struct data pwd, struct data *ret)
-{
-    int err=0;
-    int i=0, j=0;
-
-    ret->len = 0;
-    ret->value = NULL;
-
-    if (pwd.len == 0) {
-        err = ERR_PWD_ZERO;
-        ret->len = 0;
-        goto cleanup;
-    }
-
-    /* Check if it is a hexadecimal encoded password */
-    if (pwd.len >= strlen("{HEX}") &&
-        strncmp((char *)pwd.value, "{HEX}", strlen("{HEX}")) == 0) {
-
-        if ((pwd.len - strlen("{HEX}")) % 2 != 0) {
-            /* A hexadecimal encoded password should have even length */
-            err = ERR_PWD_BAD;
-            ret->len = 0;
-            goto cleanup;
-        }
-        ret->value = (unsigned char *)malloc((pwd.len - strlen("{HEX}")) / 2 + 1);
-        if (ret->value == NULL) {
-            err = ERR_NO_MEM;
-            ret->len = 0;
-            goto cleanup;
-        }
-        ret->len = (pwd.len - strlen("{HEX}")) / 2;
-        ret->value[ret->len] = '\0';
-        for (i = strlen("{HEX}"), j = 0; i < pwd.len; i += 2, j++) {
-            unsigned int k;
-            /* Check if it is a hexadecimal number */
-            if (isxdigit(pwd.value[i]) == 0 || isxdigit(pwd.value[i + 1]) == 0) {
-                err = ERR_PWD_NOT_HEX;
-                ret->len = 0;
-                goto cleanup;
-            }
-            sscanf((char *)pwd.value + i, "%2x", &k);
-            ret->value[j] = k;
-        }
-        goto cleanup;
-    } else {
-        err = ERR_PWD_NOT_HEX;
-        ret->len = 0;
-        goto cleanup;
-    }
-
-cleanup:
-
-    if (ret->len == 0) {
-        free(ret->value);
-        ret->value = NULL;
-    }
-    return(err);
-}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
index 167624c..31511fc 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
@@ -32,18 +32,6 @@
 #define LDAP_SERVICE_STASH_H 1
 
 #define RECORDLEN 1024
-struct data{
-    int           len;
-    unsigned char *value;
-};
-
-#define ERR_NO_MEM      1
-#define ERR_PWD_ZERO    2
-#define ERR_PWD_BAD     3
-#define ERR_PWD_NOT_HEX 4
-
-int
-dec_password(struct data, struct data *);
 
 krb5_error_code
 krb5_ldap_readpassword(krb5_context, krb5_ldap_context *, unsigned char **);


More information about the cvs-krb5 mailing list