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