1 /* $OpenBSD: encrypt.c,v 1.37 2015/01/05 14:07:12 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[16]; 67 68 if (operation == DO_BLF) { 69 snprintf(prefbuf, sizeof(prefbuf), "blowfish,%s", extra); 70 pref = prefbuf; 71 } else { 72 login_cap_t *lc; 73 74 if ((lc = login_getclass(extra)) == NULL) 75 errx(1, "unable to get login class `%s'", 76 extra ? (char *)extra : "default"); 77 pref = login_getcapstr(lc, "localcipher", NULL, NULL); 78 } 79 if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0) 80 errx(1, "can't generate hash"); 81 82 fputs(buffer, stdout); 83 } 84 85 int 86 main(int argc, char **argv) 87 { 88 int opt; 89 int operation = -1; 90 int prompt = 0; 91 int rounds; 92 char *extra = NULL; /* Store salt or number of rounds */ 93 const char *errstr; 94 95 while ((opt = getopt(argc, argv, "pb:c:")) != -1) { 96 switch (opt) { 97 case 'p': 98 prompt = 1; 99 break; 100 case 'b': /* Blowfish password hash */ 101 if (operation != -1) 102 usage(); 103 operation = DO_BLF; 104 if (strcmp(optarg, "a") != 0) { 105 (void)strtonum(optarg, 4, 31, &errstr); 106 if (errstr != NULL) 107 errx(1, "rounds is %s: %s", errstr, optarg); 108 } 109 extra = optarg; 110 break; 111 case 'c': /* user login class */ 112 extra = optarg; 113 operation = -1; 114 break; 115 default: 116 usage(); 117 } 118 } 119 120 if (((argc - optind) < 1)) { 121 char line[BUFSIZ], *string; 122 123 if (prompt) { 124 if ((string = getpass("Enter string: ")) == NULL) 125 err(1, "getpass"); 126 print_passwd(string, operation, extra); 127 (void)fputc('\n', stdout); 128 } else { 129 size_t len; 130 /* Encrypt stdin to stdout. */ 131 while (!feof(stdin) && 132 (fgets(line, sizeof(line), stdin) != NULL)) { 133 len = strlen(line); 134 if (len == 0 || line[0] == '\n') 135 continue; 136 if (line[len - 1] == '\n') 137 line[len - 1] = '\0'; 138 139 print_passwd(line, operation, extra); 140 141 (void)fputc('\n', stdout); 142 } 143 } 144 } else { 145 char *string; 146 147 /* can't combine -p with a supplied string */ 148 if (prompt) 149 usage(); 150 151 /* Perhaps it isn't worth worrying about, but... */ 152 if ((string = strdup(argv[optind])) == NULL) 153 err(1, NULL); 154 /* Wipe the argument. */ 155 memset(argv[optind], 0, strlen(argv[optind])); 156 157 print_passwd(string, operation, extra); 158 159 (void)fputc('\n', stdout); 160 161 /* Wipe our copy, before we free it. */ 162 memset(string, 0, strlen(string)); 163 free(string); 164 } 165 exit(0); 166 } 167