- don't free user-supplied string (via -e)
[oweals/busybox.git] / libbb / pw_encrypt.c
index d6b2fe28ddcfcd0990b65caeafa6a8cef3e8b564..469e71f6ccdc9606a8f895d9db2d07127a17419f 100644 (file)
@@ -8,25 +8,77 @@
  */
 
 #include "libbb.h"
-#include <string.h>
-#include <crypt.h>
 
+#if ENABLE_USE_BB_CRYPT
 
-char *pw_encrypt(const char *clear, const char *salt)
+/*
+ * DES and MD5 crypt implementations are taken from uclibc.
+ * They were modified to not use static buffers.
+ */
+/* Common for them */
+static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+#include "pw_encrypt_des.c"
+#include "pw_encrypt_md5.c"
+
+
+static struct const_des_ctx *des_cctx;
+static struct des_ctx *des_ctx;
+
+/* my_crypt returns malloc'ed data */
+static char *my_crypt(const char *key, const char *salt)
+{
+       /* First, check if we are supposed to be using the MD5 replacement
+        * instead of DES...  */
+       if (salt[0] == '$' && salt[1] == '1' && salt[2] == '$') {
+               return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
+       }
+
+       {
+               if (!des_cctx)
+                       des_cctx = const_des_init();
+               des_ctx = des_init(des_ctx, des_cctx);
+               return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
+       }
+}
+
+/* So far nobody wants to have it public */
+static void my_crypt_cleanup(void)
+{
+       free(des_cctx);
+       free(des_ctx);
+       des_cctx = NULL;
+       des_ctx = NULL;
+}
+
+char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
 {
-       static char cipher[128];
-       char *cp;
+       char *encrypted;
 
-#ifdef CONFIG_FEATURE_SHA1_PASSWORDS
+#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */
        if (strncmp(salt, "$2$", 3) == 0) {
                return sha1_crypt(clear);
        }
 #endif
-       cp = (char *) crypt(clear, salt);
-       /* if crypt (a nonstandard crypt) returns a string too large,
-          truncate it so we don't overrun buffers and hope there is
-          enough security in what's left */
-       safe_strncpy(cipher, cp, sizeof(cipher));
-       return cipher;
+
+       encrypted = my_crypt(clear, salt);
+
+       if (cleanup)
+               my_crypt_cleanup();
+
+       return encrypted;
 }
 
+#else /* if !ENABLE_USE_BB_CRYPT */
+
+char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
+{
+#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */
+       if (strncmp(salt, "$2$", 3) == 0) {
+               return xstrdup(sha1_crypt(clear));
+       }
+#endif
+
+       return xstrdup(crypt(clear, salt));
+}
+
+#endif