1 /* $OpenBSD: encrypt.c,v 1.44 2016/09/02 18:06:43 tedu 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 void usage(void); 49 50 #define DO_BLF 0 51 52 void 53 usage(void) 54 { 55 56 (void)fprintf(stderr, 57 "usage: %s [-b rounds] [-c class] [-p | string]\n", 58 __progname); 59 exit(1); 60 } 61 62 static void 63 print_passwd(char *string, int operation, char *extra) 64 { 65 char buffer[_PASSWORD_LEN]; 66 const char *pref; 67 char prefbuf[64]; 68 69 if (operation == DO_BLF) { 70 if (snprintf(prefbuf, sizeof(prefbuf), "blowfish,%s", extra) >= 71 sizeof(prefbuf)) 72 errx(1, "pref too long"); 73 pref = prefbuf; 74 } else { 75 login_cap_t *lc; 76 77 if ((lc = login_getclass(extra)) == NULL) 78 errx(1, "unable to get login class `%s'", 79 extra ? (char *)extra : "default"); 80 pref = login_getcapstr(lc, "localcipher", NULL, NULL); 81 } 82 if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0) 83 err(1, "can't generate hash"); 84 85 fputs(buffer, stdout); 86 } 87 88 int 89 main(int argc, char **argv) 90 { 91 int opt; 92 int operation = -1; 93 int prompt = 0; 94 char *extra = NULL; /* Store login class or number of rounds */ 95 const char *errstr; 96 97 if (pledge("stdio rpath wpath tty", NULL) == -1) 98 err(1, "pledge"); 99 100 while ((opt = getopt(argc, argv, "pb:c:")) != -1) { 101 switch (opt) { 102 case 'p': 103 prompt = 1; 104 break; 105 case 'b': /* Blowfish password hash */ 106 if (operation != -1) 107 usage(); 108 operation = DO_BLF; 109 if (strcmp(optarg, "a") != 0) { 110 (void)strtonum(optarg, 4, 31, &errstr); 111 if (errstr != NULL) 112 errx(1, "rounds is %s: %s", errstr, 113 optarg); 114 } 115 extra = optarg; 116 break; 117 case 'c': /* user login class */ 118 extra = optarg; 119 operation = -1; 120 break; 121 default: 122 usage(); 123 } 124 } 125 126 if (((argc - optind) < 1)) { 127 char line[BUFSIZ]; 128 char string[1024]; 129 130 if (prompt) { 131 if (readpassphrase("Enter string: ", string, 132 sizeof(string), RPP_ECHO_OFF) == NULL) 133 err(1, "readpassphrase"); 134 print_passwd(string, operation, extra); 135 (void)fputc('\n', stdout); 136 } else { 137 size_t len; 138 /* Encrypt stdin to stdout. */ 139 while (!feof(stdin) && 140 (fgets(line, sizeof(line), stdin) != NULL)) { 141 len = strlen(line); 142 if (len == 0 || line[0] == '\n') 143 continue; 144 if (line[len - 1] == '\n') 145 line[len - 1] = '\0'; 146 147 print_passwd(line, operation, extra); 148 149 (void)fputc('\n', stdout); 150 } 151 } 152 } else { 153 char *string; 154 155 /* can't combine -p with a supplied string */ 156 if (prompt) 157 usage(); 158 159 /* Perhaps it isn't worth worrying about, but... */ 160 if ((string = strdup(argv[optind])) == NULL) 161 err(1, NULL); 162 /* Wipe the argument. */ 163 explicit_bzero(argv[optind], strlen(argv[optind])); 164 165 print_passwd(string, operation, extra); 166 167 (void)fputc('\n', stdout); 168 169 /* Wipe our copy, before we free it. */ 170 explicit_bzero(string, strlen(string)); 171 free(string); 172 } 173 exit(0); 174 } 175