Make the '-in' option in apps/passwd.c less mandatory
[openssl.git] / apps / passwd.c
index 3c6fd5204e22afdf74fba18ce229aba587326343..7ae9e8888012f8a92b9b2e976dfb737530c6c382 100644 (file)
@@ -53,7 +53,6 @@
 
 #if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
 
-# include <assert.h>
 # include <string.h>
 
 # include "apps.h"
@@ -101,6 +100,8 @@ OPTIONS passwd_options[] = {
     {"quiet", OPT_QUIET, '-', "No warnings"},
     {"table", OPT_TABLE, '-', "Format output as table"},
     {"reverse", OPT_REVERSE, '-', "Switch table columns"},
+    {"salt", OPT_SALT, 's', "Use provided salt"},
+    {"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
 # ifndef NO_MD5CRYPT_1
     {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
     {"1", OPT_1, '-', "MD5-based password algorithm"},
@@ -108,8 +109,6 @@ OPTIONS passwd_options[] = {
 # ifndef OPENSSL_NO_DES
     {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
 # endif
-    {"salt", OPT_SALT, 's', "Use provided salt"},
-    {"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
     {NULL}
 };
 
@@ -202,14 +201,20 @@ int passwd_main(int argc, char **argv)
         goto opthelp;
 # endif
 
-    if (infile && in_stdin) {
+    if (infile != NULL && in_stdin) {
         BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog);
         goto end;
     }
 
-    in = bio_open_default(infile, "r");
-    if (in == NULL)
-        goto end;
+    if (infile != NULL || in_stdin) {
+        /*
+         * If in_stdin is true, we know that infile is NULL, and that
+         * bio_open_default() will give us back an alias for stdin.
+         */
+        in = bio_open_default(infile, 'r', FORMAT_TEXT);
+        if (in == NULL)
+            goto end;
+    }
 
     if (usecrypt)
         pw_maxlen = 8;
@@ -221,12 +226,9 @@ int passwd_main(int argc, char **argv)
         /* no passwords on the command line */
 
         passwd_malloc_size = pw_maxlen + 2;
-        /*
-         * longer than necessary so that we can warn about truncation
-         */
-        passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
-        if (passwd_malloc == NULL)
-            goto end;
+        /* longer than necessary so that we can warn about truncation */
+        passwd = passwd_malloc =
+            app_malloc(passwd_malloc_size, "password buffer");
     }
 
     if ((in == NULL) && (passwds == NULL)) {
@@ -287,10 +289,8 @@ int passwd_main(int argc, char **argv)
 
  end:
     ERR_print_errors(bio_err);
-    if (salt_malloc)
-        OPENSSL_free(salt_malloc);
-    if (passwd_malloc)
-        OPENSSL_free(passwd_malloc);
+    OPENSSL_free(salt_malloc);
+    OPENSSL_free(passwd_malloc);
     BIO_free(in);
     return (ret);
 }
@@ -313,60 +313,65 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
     char *salt_out;
     int n;
     unsigned int i;
-    EVP_MD_CTX md, md2;
+    EVP_MD_CTX *md, *md2;
     size_t passwd_len, salt_len;
 
     passwd_len = strlen(passwd);
     out_buf[0] = '$';
     out_buf[1] = 0;
     assert(strlen(magic) <= 4); /* "1" or "apr1" */
-    strncat(out_buf, magic, 4);
-    strncat(out_buf, "$", 1);
-    strncat(out_buf, salt, 8);
+    OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
+    OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
+    OPENSSL_strlcat(out_buf, salt, sizeof out_buf);
     assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
     salt_out = out_buf + 2 + strlen(magic);
     salt_len = strlen(salt_out);
     assert(salt_len <= 8);
 
-    EVP_MD_CTX_init(&md);
-    EVP_DigestInit_ex(&md, EVP_md5(), NULL);
-    EVP_DigestUpdate(&md, passwd, passwd_len);
-    EVP_DigestUpdate(&md, "$", 1);
-    EVP_DigestUpdate(&md, magic, strlen(magic));
-    EVP_DigestUpdate(&md, "$", 1);
-    EVP_DigestUpdate(&md, salt_out, salt_len);
-
-    EVP_MD_CTX_init(&md2);
-    EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
-    EVP_DigestUpdate(&md2, passwd, passwd_len);
-    EVP_DigestUpdate(&md2, salt_out, salt_len);
-    EVP_DigestUpdate(&md2, passwd, passwd_len);
-    EVP_DigestFinal_ex(&md2, buf, NULL);
+    md = EVP_MD_CTX_new();
+    if (md == NULL)
+        return NULL;
+    EVP_DigestInit_ex(md, EVP_md5(), NULL);
+    EVP_DigestUpdate(md, passwd, passwd_len);
+    EVP_DigestUpdate(md, "$", 1);
+    EVP_DigestUpdate(md, magic, strlen(magic));
+    EVP_DigestUpdate(md, "$", 1);
+    EVP_DigestUpdate(md, salt_out, salt_len);
+
+    md2 = EVP_MD_CTX_new();
+    if (md2 == NULL)
+        return NULL;
+    EVP_DigestInit_ex(md2, EVP_md5(), NULL);
+    EVP_DigestUpdate(md2, passwd, passwd_len);
+    EVP_DigestUpdate(md2, salt_out, salt_len);
+    EVP_DigestUpdate(md2, passwd, passwd_len);
+    EVP_DigestFinal_ex(md2, buf, NULL);
 
     for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
-        EVP_DigestUpdate(&md, buf, sizeof buf);
-    EVP_DigestUpdate(&md, buf, i);
+        EVP_DigestUpdate(md, buf, sizeof buf);
+    EVP_DigestUpdate(md, buf, i);
 
     n = passwd_len;
     while (n) {
-        EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
+        EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1);
         n >>= 1;
     }
-    EVP_DigestFinal_ex(&md, buf, NULL);
+    EVP_DigestFinal_ex(md, buf, NULL);
 
     for (i = 0; i < 1000; i++) {
-        EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
-        EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *)passwd : buf,
+        EVP_DigestInit_ex(md2, EVP_md5(), NULL);
+        EVP_DigestUpdate(md2, (i & 1) ? (unsigned const char *)passwd : buf,
                          (i & 1) ? passwd_len : sizeof buf);
         if (i % 3)
-            EVP_DigestUpdate(&md2, salt_out, salt_len);
+            EVP_DigestUpdate(md2, salt_out, salt_len);
         if (i % 7)
-            EVP_DigestUpdate(&md2, passwd, passwd_len);
-        EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *)passwd,
+            EVP_DigestUpdate(md2, passwd, passwd_len);
+        EVP_DigestUpdate(md2, (i & 1) ? buf : (unsigned const char *)passwd,
                          (i & 1) ? sizeof buf : passwd_len);
-        EVP_DigestFinal_ex(&md2, buf, NULL);
+        EVP_DigestFinal_ex(md2, buf, NULL);
     }
-    EVP_MD_CTX_cleanup(&md2);
+    EVP_MD_CTX_free(md2);
+    EVP_MD_CTX_free(md);
 
     {
         /* transform buf into output string */
@@ -405,7 +410,6 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
         *output = 0;
         assert(strlen(out_buf) < sizeof(out_buf));
     }
-    EVP_MD_CTX_cleanup(&md);
 
     return out_buf;
 }
@@ -426,9 +430,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
 # ifndef OPENSSL_NO_DES
         if (usecrypt) {
             if (*salt_malloc_p == NULL) {
-                *salt_p = *salt_malloc_p = OPENSSL_malloc(3);
-                if (*salt_malloc_p == NULL)
-                    goto end;
+                *salt_p = *salt_malloc_p = app_malloc(3, "salt buffer");
             }
             if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
                 goto end;
@@ -447,9 +449,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
             int i;
 
             if (*salt_malloc_p == NULL) {
-                *salt_p = *salt_malloc_p = OPENSSL_malloc(9);
-                if (*salt_malloc_p == NULL)
-                    goto end;
+                *salt_p = *salt_malloc_p = app_malloc(9, "salt buffer");
             }
             if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
                 goto end;
@@ -502,7 +502,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
 
 int passwd_main(int argc, char **argv)
 {
-    fputs("Program not available.\n", stderr)
-        return (1);
+    BIO_printf(bio_err, "Program not available.\n");
+    return (1);
 }
 #endif