int main(int argc, char *argv[]) { #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) char conf_file[POOLMAXPATHLEN + 1]; char enc_key[MAX_POOL_KEY_LEN + 1]; char pg_pass[MAX_PGPASS_LEN + 1]; char username[MAX_USER_NAME_LEN + 1]; char key_file_path[POOLMAXPATHLEN + sizeof(POOLKEYFILE) + 1]; int opt; int optindex; bool updatepasswd = false; bool prompt = false; bool prompt_for_key = false; char *pool_key = NULL; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"prompt", no_argument, NULL, 'p'}, {"prompt-for-key", no_argument, NULL, 'P'}, {"update-pass", no_argument, NULL, 'm'}, {"username", required_argument, NULL, 'u'}, {"enc-key", required_argument, NULL, 'K'}, {"key-file", required_argument, NULL, 'k'}, {"config-file", required_argument, NULL, 'f'}, {NULL, 0, NULL, 0} }; snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); /* * initialize username buffer with zeros so that we can use strlen on it * later to check if a username was given on the command line */ memset(username, 0, sizeof(username)); memset(enc_key, 0, sizeof(enc_key)); memset(key_file_path, 0, sizeof(key_file_path)); while ((opt = getopt_long(argc, argv, "hPpmf:u:k:K:", long_options, &optindex)) != -1) { switch (opt) { case 'p': /* prompt for postgres password */ prompt = true; break; case 'P': /* prompt for encryption key */ prompt_for_key = true; break; case 'm': /* update password file */ updatepasswd = true; break; case 'f': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } strlcpy(conf_file, optarg, sizeof(conf_file)); break; case 'k': /* specify key file for encrypting * pool_password entries */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } strlcpy(key_file_path, optarg, sizeof(key_file_path)); break; case 'K': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } strlcpy(enc_key, optarg, sizeof(enc_key)); break; case 'u': if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } /* check the input limit early */ if (strlen(optarg) > sizeof(username)) { fprintf(stderr, "Error: input exceeds maximum username length!\n\n"); exit(EXIT_FAILURE); } strlcpy(username, optarg, sizeof(username)); break; default: PRINT_USAGE(EXIT_SUCCESS); break; } } /* Prompt for password. */ if (prompt || optind >= argc) { char buf[MAX_PGPASS_LEN]; int len; set_tio_attr(1); printf("db password: "******"Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); exit(EXIT_FAILURE); } printf("\n"); set_tio_attr(0); /* Remove LF at the end of line, if there is any. */ len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') { buf[len - 1] = '\0'; len--; } stpncpy(pg_pass, buf, sizeof(pg_pass)); } /* Read password from argv. */ else { int len; len = strlen(argv[optind]); if (len > MAX_PGPASS_LEN) { fprintf(stderr, "Error: Input exceeds maximum password length given:%d max allowed:%d!\n\n", len, MAX_PGPASS_LEN); PRINT_USAGE(EXIT_FAILURE); } stpncpy(pg_pass, argv[optind], sizeof(pg_pass)); } /* prompt for key, overrides all key related arguments */ if (prompt_for_key) { char buf[MAX_POOL_KEY_LEN]; int len; /* we need to read the encryption key from stdin */ set_tio_attr(1); printf("encryption key: "); if (!fgets(buf, sizeof(buf), stdin)) { int eno = errno; fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); exit(EXIT_FAILURE); } printf("\n"); set_tio_attr(0); /* Remove LF at the end of line, if there is any. */ len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') { buf[len - 1] = '\0'; len--; } if (len == 0) { fprintf(stderr, "encryption key not provided\n"); exit(EXIT_FAILURE); } stpncpy(enc_key, buf, sizeof(enc_key)); } else { /* check if we already have not got the key from command line argument */ if (strlen(enc_key) == 0) { /* read from file */ if (strlen(key_file_path) == 0) { get_pool_key_filename(key_file_path); } fprintf(stdout, "trying to read key from file %s\n", key_file_path); pool_key = read_pool_key(key_file_path); } else { pool_key = enc_key; } } if (pool_key == NULL) { fprintf(stderr, "encryption key not provided\n"); exit(EXIT_FAILURE); } if (updatepasswd) { update_pool_passwd(conf_file, username, pg_pass, pool_key); } else { unsigned char ciphertext[MAX_ENCODED_PASSWD_LEN]; unsigned char b64_enc[MAX_ENCODED_PASSWD_LEN]; int len; int cypher_len; cypher_len = aes_encrypt_with_password((unsigned char *) pg_pass, strlen(pg_pass), pool_key, ciphertext); /* generate the hash for the given username */ len = pg_b64_encode((const char *) ciphertext, cypher_len, (char *) b64_enc); b64_enc[len] = 0; fprintf(stdout, "\n%s\n", b64_enc); fprintf(stdout, "pool_passwd string: AES%s\n", b64_enc); #ifdef DEBUG_ENCODING unsigned char b64_dec[MAX_ENCODED_PASSWD_LEN]; unsigned char plaintext[MAX_PGPASS_LEN]; len = pg_b64_decode(b64_enc, len, b64_dec); len = aes_decrypt_with_password(b64_dec, len, pool_key, plaintext); plaintext[len] = 0; #endif } if (pool_key != enc_key) free(pool_key); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) char conf_file[POOLMAXPATHLEN+1]; char username[MAX_INPUT_SIZE+1]; int opt; int optindex; bool md5auth = false; bool prompt = false; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"prompt", no_argument, NULL, 'p'}, {"md5auth", no_argument, NULL, 'm'}, {"username", required_argument, NULL, 'u'}, {"config-file", required_argument, NULL, 'f'}, {NULL, 0, NULL, 0} }; snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); /* initialize username buffer with zeros so that we can use strlen on it later to check if a username was given on the command line */ memset(username, 0, MAX_INPUT_SIZE+1); while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1) { switch (opt) { case 'p': /* prompt for password */ prompt = true; break; case 'm': /* produce md5 authentication password */ md5auth = true; break; case 'f': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } strlcpy(conf_file, optarg, sizeof(conf_file)); break; case 'u': if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } /* check the input limit early */ if (strlen(optarg) > MAX_INPUT_SIZE) { fprintf(stderr, "Error: input exceeds maximum username length!\n\n"); exit(EXIT_FAILURE); } strlcpy(username, optarg, sizeof(username)); break; default: PRINT_USAGE(EXIT_SUCCESS); break; } } /* Prompt for password. */ if (prompt) { char md5[MD5_PASSWD_LEN+1]; char buf[MAX_INPUT_SIZE+1]; int len; set_tio_attr(1); printf("password: "******"Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); exit(EXIT_FAILURE); } printf("\n"); set_tio_attr(0); /* Remove LF at the end of line, if there is any. */ len = strlen(buf); if (len > 0 && buf[len-1] == '\n') { buf[len-1] = '\0'; len--; } if (md5auth) { update_pool_passwd(conf_file, username, buf); } else { pool_md5_hash(buf, len, md5); printf("%s\n", md5); } } /* Read password from argv. */ else { char md5[POOL_PASSWD_LEN+1]; int len; if (optind >= argc) { PRINT_USAGE(EXIT_FAILURE); } len = strlen(argv[optind]); if (len > MAX_INPUT_SIZE) { fprintf(stderr, "Error: Input exceeds maximum password length!\n\n"); PRINT_USAGE(EXIT_FAILURE); } if (md5auth) { update_pool_passwd(conf_file, username, argv[optind]); } else { pool_md5_hash(argv[optind], len, md5); printf("%s\n", md5); } } return EXIT_SUCCESS; }