1 /* $OpenBSD: encrypt.c,v 1.45 2016/09/04 15:36:13 tb Exp $ */ 2 3 /* 4 * Copyright (c) 1996, Jason Downs. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/types.h> 29 #include <ctype.h> 30 #include <err.h> 31 #include <errno.h> 32 #include <pwd.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <unistd.h> 37 #include <login_cap.h> 38 #include <limits.h> 39 #include <readpassphrase.h> 40 41 /* 42 * Very simple little program, for encrypting passwords from the command 43 * line. Useful for scripts and such. 44 */ 45 46 extern char *__progname; 47 48 static void __dead usage(void); 49 static void print_passwd(char *, int, char *); 50 51 #define DO_BLF 0 52 53 static void __dead 54 usage(void) 55 { 56 57 (void)fprintf(stderr, 58 "usage: %s [-b rounds] [-c class] [-p | string]\n", 59 __progname); 60 exit(1); 61 } 62 63 static void 64 print_passwd(char *string, int operation, char *extra) 65 { 66 char buffer[_PASSWORD_LEN]; 67 const char *pref; 68 char prefbuf[64]; 69 70 if (operation == DO_BLF) { 71 if (snprintf(prefbuf, sizeof(prefbuf), "blowfish,%s", extra) >= 72 sizeof(prefbuf)) 73 errx(1, "pref too long"); 74 pref = prefbuf; 75 } else { 76 login_cap_t *lc; 77 78 if ((lc = login_getclass(extra)) == NULL) 79 errx(1, "unable to get login class `%s'", 80 extra ? (char *)extra : "default"); 81 pref = login_getcapstr(lc, "localcipher", NULL, NULL); 82 } 83 if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0) 84 err(1, "can't generate hash"); 85 86 fputs(buffer, stdout); 87 } 88 89 int 90 main(int argc, char **argv) 91 { 92 int opt; 93 int operation = -1; 94 int prompt = 0; 95 char *extra = NULL; /* Store login class or number of rounds */ 96 const char *errstr; 97 98 if (pledge("stdio rpath wpath tty", NULL) == -1) 99 err(1, "pledge"); 100 101 while ((opt = getopt(argc, argv, "pb:c:")) != -1) { 102 switch (opt) { 103 case 'p': 104 prompt = 1; 105 break; 106 case 'b': /* Blowfish password hash */ 107 if (operation != -1) 108 usage(); 109 operation = DO_BLF; 110 if (strcmp(optarg, "a") != 0) { 111 (void)strtonum(optarg, 4, 31, &errstr); 112 if (errstr != NULL) 113 errx(1, "rounds is %s: %s", errstr, 114 optarg); 115 } 116 extra = optarg; 117 break; 118 case 'c': /* user login class */ 119 extra = optarg; 120 operation = -1; 121 break; 122 default: 123 usage(); 124 } 125 } 126 127 if (((argc - optind) < 1)) { 128 char line[BUFSIZ]; 129 char string[1024]; 130 131 if (prompt) { 132 if (readpassphrase("Enter string: ", string, 133 sizeof(string), RPP_ECHO_OFF) == NULL) 134 err(1, "readpassphrase"); 135 print_passwd(string, operation, extra); 136 (void)fputc('\n', stdout); 137 } else { 138 size_t len; 139 /* Encrypt stdin to stdout. */ 140 while (!feof(stdin) && 141 (fgets(line, sizeof(line), stdin) != NULL)) { 142 len = strlen(line); 143 if (len == 0 || line[0] == '\n') 144 continue; 145 if (line[len - 1] == '\n') 146 line[len - 1] = '\0'; 147 148 print_passwd(line, operation, extra); 149 150 (void)fputc('\n', stdout); 151 } 152 } 153 } else { 154 char *string; 155 156 /* can't combine -p with a supplied string */ 157 if (prompt) 158 usage(); 159 160 /* Perhaps it isn't worth worrying about, but... */ 161 if ((string = strdup(argv[optind])) == NULL) 162 err(1, NULL); 163 /* Wipe the argument. */ 164 explicit_bzero(argv[optind], strlen(argv[optind])); 165 166 print_passwd(string, operation, extra); 167 168 (void)fputc('\n', stdout); 169 170 /* Wipe our copy, before we free it. */ 171 explicit_bzero(string, strlen(string)); 172 free(string); 173 } 174 return 0; 175 } 176