int main(int argc, char *argv[]) { int ch, i; int password_fd = -1; unsigned int salt_minlen = 0; unsigned int salt_maxlen = 0; unsigned int rounds_support = 0; const char *salt_prefix = NULL; const char *salt_arg = NULL; unsigned int rounds = 0; char *salt = NULL; char rounds_str[30]; char *password = NULL; #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif /* prepend options from environment */ argv = merge_args(getenv("MKPASSWD_OPTIONS"), argv, &argc); while ((ch = GETOPT_LONGISH(argc, argv, "hH:m:5P:R:sS:V", longopts, 0)) > 0) { switch (ch) { case '5': optarg = (char *) "md5"; /* fall through */ case 'm': case 'H': if (!optarg || strcaseeq("help", optarg)) { display_methods(); exit(0); } for (i = 0; methods[i].method != NULL; i++) if (strcaseeq(methods[i].method, optarg)) { salt_prefix = methods[i].prefix; salt_minlen = methods[i].minlen; salt_maxlen = methods[i].maxlen; rounds_support = methods[i].rounds; break; } if (!salt_prefix) { fprintf(stderr, _("Invalid method '%s'.\n"), optarg); exit(1); } break; case 'P': { char *p; password_fd = strtol(optarg, &p, 10); if (p == NULL || *p != '\0' || password_fd < 0) { fprintf(stderr, _("Invalid number '%s'.\n"), optarg); exit(1); } } break; case 'R': { char *p; long r; r = strtol(optarg, &p, 10); if (p == NULL || *p != '\0' || r < 0) { fprintf(stderr, _("Invalid number '%s'.\n"), optarg); exit(1); } rounds = r; } break; case 's': password_fd = 0; break; case 'S': salt_arg = optarg; break; case 'V': display_version(); exit(0); case 'h': display_help(EXIT_SUCCESS); default: fprintf(stderr, _("Try '%s --help' for more information.\n"), argv[0]); exit(1); } } argc -= optind; argv += optind; if (argc == 2 && !salt_arg) { password = argv[0]; salt_arg = argv[1]; } else if (argc == 1) { password = argv[0]; } else if (argc == 0) { } else { display_help(EXIT_FAILURE); } /* default: DES password */ if (!salt_prefix) { salt_minlen = methods[0].minlen; salt_maxlen = methods[0].maxlen; salt_prefix = methods[0].prefix; } if (streq(salt_prefix, "$2a$") || streq(salt_prefix, "$2y$")) { /* OpenBSD Blowfish and derivatives */ if (rounds <= 5) rounds = 5; /* actually for 2a/2y it is the logarithm of the number of rounds */ snprintf(rounds_str, sizeof(rounds_str), "%02u$", rounds); } else if (rounds_support && rounds) snprintf(rounds_str, sizeof(rounds_str), "rounds=%u$", rounds); else rounds_str[0] = '\0'; if (salt_arg) { unsigned int c = strlen(salt_arg); if (c < salt_minlen || c > salt_maxlen) { if (salt_minlen == salt_maxlen) fprintf(stderr, ngettext( "Wrong salt length: %d byte when %d expected.\n", "Wrong salt length: %d bytes when %d expected.\n", c), c, salt_maxlen); else fprintf(stderr, ngettext( "Wrong salt length: %d byte when %d <= n <= %d" " expected.\n", "Wrong salt length: %d bytes when %d <= n <= %d" " expected.\n", c), c, salt_minlen, salt_maxlen); exit(1); } while (c-- > 0) { if (strchr(valid_salts, salt_arg[c]) == NULL) { fprintf(stderr, _("Illegal salt character '%c'.\n"), salt_arg[c]); exit(1); } } salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str) + strlen(salt_arg) + 1)); *salt = '\0'; strcat(salt, salt_prefix); strcat(salt, rounds_str); strcat(salt, salt_arg); } else { #ifdef HAVE_SOLARIS_CRYPT_GENSALT salt = crypt_gensalt(salt_prefix, NULL); if (!salt) perror("crypt_gensalt"); #elif defined HAVE_LINUX_CRYPT_GENSALT void *entropy = get_random_bytes(64); salt = crypt_gensalt(salt_prefix, rounds, entropy, 64); if (!salt) { fprintf(stderr, "crypt_gensalt failed.\n"); exit(2); } free(entropy); #else unsigned int salt_len = salt_maxlen; if (salt_minlen != salt_maxlen) { /* salt length can vary */ srand(time(NULL) + getpid()); salt_len = rand() % (salt_maxlen - salt_minlen + 1) + salt_minlen; } salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str) + salt_len + 1)); *salt = '\0'; strcat(salt, salt_prefix); strcat(salt, rounds_str); generate_salt(salt + strlen(salt), salt_len); #endif } if (password) { } else if (password_fd != -1) { FILE *fp; char *p; if (isatty(password_fd)) fprintf(stderr, _("Password: "******"r"); if (!fp) { perror("fdopen"); exit(2); } if (!fgets(password, 128, fp)) { perror("fgets"); exit(2); } p = strpbrk(password, "\n\r"); if (p) *p = '\0'; } else { password = getpass(_("Password: "******"getpass"); exit(2); } } { const char *result; result = crypt(password, salt); /* xcrypt returns "*0" on errors */ if (!result || result[0] == '*') { fprintf(stderr, "crypt failed.\n"); exit(2); } /* yes, using strlen(salt_prefix) on salt. It's not * documented whether crypt_gensalt may change the prefix */ if (!strneq(result, salt, strlen(salt_prefix))) { fprintf(stderr, _("Method not supported by crypt(3).\n")); exit(2); } printf("%s\n", result); } exit(0); }
int main(int argc, char *argv[]) { int ch, nopar = 0; const char *server = NULL, *port = NULL; char *p, *q, *qstring, fstring[64] = "\0"; #ifdef _WIN32 WSADATA wsa; if (WSAStartup(0x0101, &wsa)) { fputs("Winsock initalization error.", stderr); return -1; } #endif #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif while ((ch = GETOPT_LONGISH(argc, argv, "acdFg:h:Hi:KlLmMp:q:rRs:St:T:v:V:x", longopts, 0)) > 0) { /* RIPE flags */ if (strchr(ripeflags, ch)) { for (p = fstring; *p; p++); sprintf(p--, "-%c ", ch); continue; } if (strchr(ripeflagsp, ch)) { for (p = fstring; *p; p++); snprintf(p--, sizeof(fstring), "-%c %s ", ch, optarg); if (ch == 't' || ch == 'v' || ch == 'q') nopar = 1; continue; } /* program flags */ switch (ch) { case 'h': server = q = malloc(strlen(optarg) + 1); for (p = optarg; *p && *p != ':'; *q++ = tolower(*p++)); if (*p == ':') port = p + 1; *q = '\0'; break; case 'V': client_tag = optarg; case 'H': hide_discl = 0; /* enable disclaimers hiding */ break; case 'p': port = optarg; break; case 2: verb = 1; break; case 1: #ifdef VERSION fprintf(stderr, _("Version %s.\n\nReport bugs to %s.\n"), VERSION, "<*****@*****.**>"); #else fprintf(stderr, "%s %s\n", inetutils_package, inetutils_version); #endif exit(0); default: usage(); } } argc -= optind; argv += optind; if (argc == 0 && !nopar) /* there is no parameter */ usage(); /* On some systems realloc only works on non-NULL buffers */ qstring = malloc(64); *qstring = '\0'; /* parse other parameters, if any */ if (!nopar) { int qslen = 0; while (1) { qslen += strlen(*argv) + 1 + 1; qstring = realloc(qstring, qslen); strcat(qstring, *argv++); if (argc == 1) break; strcat(qstring, " "); argc--; } } /* -v or -t has been used */ if (!server && !*qstring) server = "whois.ripe.net"; #ifdef CONFIG_FILE if (!server) { server = match_config_file(qstring); if (verb && server) printf(_("Using server %s.\n"), server); } #endif signal(SIGTERM, sighandler); signal(SIGINT, sighandler); #ifndef _WIN32 signal(SIGALRM, alarm_handler); #endif alarm(60); if (!server) { char *tmp; tmp = normalize_domain(qstring); server = whichwhois(tmp); free(tmp); switch (server[0]) { case 0: if (!(server = getenv("WHOIS_SERVER"))) server = DEFAULTSERVER; if (verb) printf(_("Using default server %s.\n"), server); break; case 1: puts(_("This TLD has no whois server, but you can access the " "whois database at")); case 2: puts(server + 1); exit(0); case 3: puts(_("This TLD has no whois server.")); exit(0); case 4: if (verb) puts(_("Connecting to whois.crsnic.net.")); sockfd = openconn("whois.crsnic.net", NULL); server = query_crsnic(sockfd, qstring); closesocket(sockfd); if (!server) exit(0); printf(_("\nFound a referral to %s.\n\n"), server); alarm(60); break; case 9: if (verb) puts(_("Connecting to whois.nic.cc.")); sockfd = openconn("whois.nic.cc", NULL); server = query_crsnic(sockfd, qstring); closesocket(sockfd); if (!server) exit(0); printf(_("\nFound a referral to %s.\n\n"), server); alarm(60); break; case 7: if (verb) puts(_("Connecting to whois.publicinterestregistry.net.")); sockfd = openconn("whois.publicinterestregistry.net", NULL); server = query_pir(sockfd, qstring); closesocket(sockfd); if (!server) exit(0); printf(_("\nFound referral to %s.\n\n"), server); alarm(60); break; case 5: puts(_("No whois server is known for this kind of object.")); exit(0); case 6: puts(_("Unknown AS number or IP network. Please upgrade this program.")); exit(0); default: if (verb) printf(_("Using server %s.\n"), server); } } if (getenv("WHOIS_HIDE")) hide_discl = 0; p = queryformat(server, fstring, qstring); if (verb) printf(_("Query string: \"%s\"\n\n"), p); strcat(p, "\r\n"); sockfd = openconn(server, port); /* * Now we are connected and the query is supposed to complete quickly. * This will help people who run whois ... | less */ alarm(0); do_query(sockfd, p); exit(0); }