Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}