-.\" $OpenBSD: encrypt.1,v 1.4 1996/08/26 08:41:25 downsj Exp $
+.\" $OpenBSD: encrypt.1,v 1.5 1997/03/30 19:22:45 provos Exp $
.\"
.\" Copyright (c) 1996, Jason Downs. All rights reserved.
.\"
.Sh SYNOPSIS
.Nm encrypt
.Op Fl k
+.Op Fl b Ar rounds
.Op Fl m
.Op Fl s Ar salt
.Op Ar string
from within scripts.
.Pp
The following options are supported:
-.Bl -tag -width XxXXXXX
+.Bl -tag -width XxXXXXXXX
.It Fl k
Run in
.Nm makekey
compatible mode; a single combined key and salt are read from standard
input and the DES encrypted result is written to standard output without a
terminating newline.
+.It Fl b Ar rounds
+Encrypt the string using Blowfish hashing with the specified
+.Ar rounds .
.It Fl m
Encrypt the string using MD5.
.It Fl s Ar salt
is specified,
.Nm encrypt
reads one string per line from standard input, encrypting each one with
-the same
-.Ar salt .
+with the chosen algorithm from above. In case that no specific algorithm
+was given as command line option, the default will be looked up from
+.Ar passwd.conf(5) .
+.Pp
+For MD5 and Blowfish a new random salt is automatically generated for each
+password.
+.Pp
Specifing the
.Ar string
on the command line should be discouraged; using the
standard input is more secure.
+.Sh FILES
+.Bl -tag -width /etc/passwd.conf -compact
+.It Pa /etc/passwd.conf
+.El
.Sh SEE ALSO
-.Xr crypt 3
+.Xr crypt 3 ,
+.Xr passwd.conf 5 ,
+.Xr pw_getconf 3
.Sh HISTORY
.Nm encrypt
first appeared in OpenBSD 1.2.
-/* $OpenBSD: encrypt.c,v 1.4 1997/03/27 23:43:36 downsj Exp $ */
+/* $OpenBSD: encrypt.c,v 1.5 1997/03/30 19:22:46 provos Exp $ */
/*
* Copyright (c) 1996, Jason Downs. All rights reserved.
#include <errno.h>
#include <string.h>
#include <unistd.h>
+#include <pwd.h>
/*
* Very simple little program, for encrypting passwords from the command
* line. Useful for scripts and such.
*/
+#define DO_MAKEKEY 0
+#define DO_DES 1
+#define DO_MD5 2
+#define DO_BLF 3
+
extern char *optarg;
extern int optind;
char *progname;
+char buffer[_PASSWORD_LEN];
void usage()
{
- errx(1, "usage: %s [-k] [-m] [-s salt] [string]", progname);
+ errx(1, "usage: %s [-k] [-b rounds] [-m] [-s salt] [string]", progname);
}
char *trim(line)
return(ptr);
}
+void print_passwd(char *string, int operation, void *extra)
+{
+ char msalt[3], *salt;
+ struct passwd pwd;
+ extern char *bcrypt_gensalt __P((int));
+ extern pwd_gensalt __P((char *, int, struct passwd *, char));
+
+ switch(operation) {
+ case DO_MAKEKEY:
+ /*
+ * makekey mode: parse string into seperate DES key and salt.
+ */
+ if (strlen(string) != 10) {
+ /* To be compatible... */
+ fprintf (stderr, "%s: %s\n", progname, strerror(EFTYPE));
+ exit (1);
+ }
+ strcpy(msalt, &string[8]);
+ salt = msalt;
+ break;
+ case DO_MD5:
+ strcpy(buffer, "$1$");
+ to64(&buffer[3], arc4random(), 4);
+ to64(&buffer[7], arc4random(), 4);
+ strcpy(buffer+11, "$");
+ salt = buffer;
+ break;
+ case DO_BLF:
+ strncpy(buffer, bcrypt_gensalt(*(int *)extra), _PASSWORD_LEN - 1);
+ buffer[_PASSWORD_LEN-1] = 0;
+ salt = buffer;
+ break;
+ case DO_DES:
+ salt = extra;
+ break;
+ default:
+ pwd.pw_name = "default";
+ if (!pwd_gensalt(buffer, _PASSWORD_LEN, &pwd, 'l')) {
+ fprintf (stderr, "%s: Can't generate salt\n", progname);
+ exit (1);
+ }
+ salt = buffer;
+ break;
+ }
+
+ fputs(crypt(string, salt), stdout);
+}
+
int main(argc, argv)
int argc;
char *argv[];
{
int opt;
- int do_md5 = 0;
- int do_makekey = 0;
- char *salt = (char *)NULL;
+ int operation = -1;
+ int rounds;
+ void *extra; /* Store salt or number of rounds */
if ((progname = strrchr(argv[0], '/')))
progname++;
progname = argv[0];
if (strcmp(progname, "makekey") == 0)
- do_makekey = 1;
+ operation = DO_MAKEKEY;
- while ((opt = getopt(argc, argv, "kms:")) != -1) {
+ while ((opt = getopt(argc, argv, "kms:b:")) != -1) {
switch (opt) {
- case 'k':
- do_makekey = 1;
+ case 'k': /* Stdin/Stdout Unix crypt */
+ if (operation != -1)
+ usage();
+ operation = DO_MAKEKEY;
break;
- case 'm':
- do_md5 = 1;
+ case 'm': /* MD5 password hash */
+ if (operation != -1)
+ usage();
+ operation = DO_MD5;
break;
- case 's':
- salt = optarg;
- if (salt[0] == '$') /* -s is only for DES. */
+ case 's': /* Unix crypt (DES) */
+ if (operation != -1)
+ usage();
+ operation = DO_DES;
+ if (optarg[0] == '$') /* -s is only for DES. */
usage();
+ extra = optarg;
break;
+ case 'b': /* Blowfish password hash */
+ if (operation != -1)
+ usage();
+ operation = DO_BLF;
+ rounds = atoi(optarg);
+ extra = &rounds;
+ break;
default:
usage();
}
}
- if (do_md5 && !do_makekey && (salt != (char *)NULL))
- usage();
-
- if (!do_md5 && !do_makekey && (salt == (char *)NULL))
- usage();
-
- if (do_makekey && (do_md5 || (salt != (char *)NULL)))
- usage();
-
- if (((argc - optind) < 1) || do_makekey) {
- char line[BUFSIZ], *string, msalt[3];
+ if (((argc - optind) < 1) || operation == DO_MAKEKEY) {
+ char line[BUFSIZ], *string;
/* Encrypt stdin to stdout. */
while (!feof(stdin) && (fgets(line, sizeof(line), stdin) != NULL)) {
string = trim(line);
if (*string == '\0')
continue;
- if (do_makekey) {
- /*
- * makekey mode: parse string into seperate DES key and salt.
- */
- if (strlen(string) != 10) {
- /* To be compatible... */
- fprintf (stderr, "%s: %s\n", progname, strerror(EFTYPE));
- exit (1);
- }
- strcpy(msalt, &string[8]);
- salt = msalt;
- }
+
+ print_passwd(string, operation, extra);
- fputs(crypt(string, (do_md5 ? "$1$" : salt)), stdout);
- if (do_makekey) {
+ if (operation == DO_MAKEKEY) {
fflush(stdout);
break;
}
/* Wipe the argument. */
bzero(argv[optind], strlen(argv[optind]));
- fputs(crypt(string, (do_md5 ? "$1$" : salt)), stdout);
+ print_passwd(string, operation, extra);
+
fputc('\n', stdout);
/* Wipe our copy, before we free it. */