diff --git a/doc/src/sgml/ref/pg_enc.sgml b/doc/src/sgml/ref/pg_enc.sgml
index 4a894ad..368cd75 100644
--- a/doc/src/sgml/ref/pg_enc.sgml
+++ b/doc/src/sgml/ref/pg_enc.sgml
@@ -79,6 +79,16 @@ Pgpool-II documentation
+
+
+
+
+ Specifies file containing username and password pairs.
+
+
+
+
+
@@ -160,6 +170,28 @@ Pgpool-II documentation
which will add an entry for username with the password given.
+
+ To avoid password prompt or password in command parameter,
+ pg_enc can read user name:password pairs from file.
+ It will add all user names and encrypted password to
+ authentication file.
+
+ $ cat users.txt
+ username1:secretpassword1
+ username2:secretpassword1
+
+ $ pg_enc -m -f /path/to/pgpool.conf -i users.txt
+ trying to read key from file /home/pgpool/.pgpoolkey
+ trying to read user:password pairs from file users.text
+ LINE#01: USER: username1
+ LINE#02: USER: username2
+
+ $ cat /path/to/pool_passwd
+ username1:AESrx5QdpGyW/+4CB80KWtwhg==
+ username2:AESUAdohy7nCUhWliRI9WiYQA==
+
+
+
diff --git a/src/tools/pgenc/pg_enc.c b/src/tools/pgenc/pg_enc.c
index e62ff95..d973060 100644
--- a/src/tools/pgenc/pg_enc.c
+++ b/src/tools/pgenc/pg_enc.c
@@ -42,12 +42,17 @@
#endif
#include
#include
+#include
+/* Maximum number of characters allowed for input. */
+#define MAX_INPUT_SIZE MAX_USER_NAME_LEN + 1 + MAX_PGPASS_LEN
#define MAX_ENCODED_PASSWD_LEN (MAX_POOL_KEY_LEN * 2)
static void print_usage(const char prog[], int exit_code);
static void set_tio_attr(int enable);
+static void print_encrypted_password(char *pg_pass, char *pool_key);
static void update_pool_passwd(char *conf_file, char *username, char *password, char *key);
+static void update_pool_passwd_from_file(char *conf_file, char *input_file, char *key, bool updatepasswd);
static bool get_pool_key_filename(char *poolKeyFile);
int
@@ -56,6 +61,7 @@ main(int argc, char *argv[])
#define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code)
char conf_file[POOLMAXPATHLEN + 1];
+ char input_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];
@@ -65,6 +71,7 @@ main(int argc, char *argv[])
bool updatepasswd = false;
bool prompt = false;
bool prompt_for_key = false;
+ bool use_input_file = false;
char *pool_key = NULL;
static struct option long_options[] = {
@@ -76,6 +83,7 @@ main(int argc, char *argv[])
{"enc-key", required_argument, NULL, 'K'},
{"key-file", required_argument, NULL, 'k'},
{"config-file", required_argument, NULL, 'f'},
+ {"input-file", required_argument, NULL, 'i'},
{NULL, 0, NULL, 0}
};
@@ -89,7 +97,7 @@ main(int argc, char *argv[])
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)
+ while ((opt = getopt_long(argc, argv, "hPpmf:i:u:k:K:", long_options, &optindex)) != -1)
{
switch (opt)
{
@@ -113,6 +121,15 @@ main(int argc, char *argv[])
strlcpy(conf_file, optarg, sizeof(conf_file));
break;
+ case 'i': /* specify users password input file */
+ if (!optarg)
+ {
+ PRINT_USAGE(EXIT_SUCCESS);
+ }
+ strlcpy(input_file, optarg, sizeof(input_file));
+ use_input_file = true;
+ break;
+
case 'k': /* specify key file for encrypting
* pool_password entries */
if (!optarg)
@@ -150,51 +167,55 @@ main(int argc, char *argv[])
}
}
- /* Prompt for password. */
- if (prompt || optind >= argc)
+ if (!use_input_file)
{
- char buf[MAX_PGPASS_LEN];
- int len;
-
- set_tio_attr(1);
- printf("db password: ");
- if (!fgets(buf, sizeof(buf), stdin))
+ /* Prompt for password. */
+ if (prompt || optind >= argc)
{
- int eno = errno;
+ char buf[MAX_PGPASS_LEN];
+ int len;
- fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)",
- strerror(eno));
+ set_tio_attr(1);
+ printf("db password: ");
+ if (!fgets(buf, sizeof(buf), stdin))
+ {
+ int eno = errno;
- exit(EXIT_FAILURE);
+ 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--;
+ }
+ stpncpy(pg_pass, buf, sizeof(pg_pass));
}
- 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')
+ /* Read password from argv. */
+ else
{
- buf[len - 1] = '\0';
- len--;
- }
- stpncpy(pg_pass, buf, sizeof(pg_pass));
- }
+ int len;
- /* Read password from argv. */
- else
- {
- int len;
+ len = strlen(argv[optind]);
- 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);
+ }
- 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));
}
-
- stpncpy(pg_pass, argv[optind], sizeof(pg_pass));
}
+
/* prompt for key, overrides all key related arguments */
if (prompt_for_key)
{
@@ -256,12 +277,31 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ /* Use input file */
+ if (use_input_file)
+ {
+ update_pool_passwd_from_file(conf_file, input_file, pool_key, updatepasswd);
+ return EXIT_SUCCESS;
+ }
+
if (updatepasswd)
{
update_pool_passwd(conf_file, username, pg_pass, pool_key);
}
else
{
+ print_encrypted_password(pg_pass, pool_key);
+ }
+
+ if (pool_key != enc_key)
+ free(pool_key);
+
+ return EXIT_SUCCESS;
+}
+
+static void
+print_encrypted_password(char *pg_pass, char *pool_key)
+{
unsigned char ciphertext[MAX_ENCODED_PASSWD_LEN];
unsigned char b64_enc[MAX_ENCODED_PASSWD_LEN];
int len;
@@ -285,12 +325,104 @@ main(int argc, char *argv[])
pool_key, plaintext);
plaintext[len] = 0;
#endif
+}
+
+static void
+update_pool_passwd_from_file(char *conf_file, char *input_file, char *key, bool updatepasswd)
+{
+ FILE *fp;
+ struct stat stat_buf;
+
+ char buf[MAX_INPUT_SIZE + 1];
+ char username[MAX_USER_NAME_LEN + 1];
+ char password[MAX_PGPASS_LEN + 1];
+ char *pch;
+ int len;
+ int line_count;
+
+ if (strlen(input_file) == 0)
+ {
+ fprintf(stderr, "input_file is emptry\n\n");
+ exit(EXIT_FAILURE);
}
- if (pool_key != enc_key)
- free(pool_key);
+ if (stat(input_file, &stat_buf) != 0)
+ {
+ fprintf(stderr, "input_file \"%s\" cannot be opened. Check file permissions\n\n", input_file);
+ exit(EXIT_FAILURE);
+ }
- return EXIT_SUCCESS;
+ if (!S_ISREG(stat_buf.st_mode))
+ {
+ fprintf(stderr, "input_file \"%s\" is not a plain file\n\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ fprintf(stdout, "trying to read user:password pairs from file %s\n", input_file);
+ fp = fopen(input_file, "r");
+ if (fp == NULL)
+ {
+ fprintf(stderr, "input_file \"%s\" cannot be opened\n\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ line_count = 0;
+ while (!feof(fp) && !ferror(fp))
+ {
+ line_count++;
+
+ memset(buf, 0, MAX_INPUT_SIZE + 1);
+ memset(username, 0, MAX_USER_NAME_LEN + 1);
+ memset(password, 0, MAX_PGPASS_LEN + 1);
+
+ if (fgets(buf, sizeof(buf), fp) == NULL)
+ break;
+
+ fprintf(stdout, "LINE#%02d: ", line_count);
+ len = strlen(buf);
+ if (len == 0 || *buf == '\n')
+ {
+ fprintf(stdout, "BLANK LINE\n");
+ continue;
+ }
+
+ /* Remove trailing newline */
+ if (buf[len - 1] == '\n')
+ buf[len - 1] = 0;
+
+ /* Split username and passwords */
+ pch = buf;
+ while( pch && pch != buf + len && *pch != ':')
+ pch++;
+ if (*pch == ':')
+ pch++;
+ if (!strlen(pch))
+ {
+ fprintf(stdout, "Invalid username:password pair\n");
+ continue;
+ }
+
+ if( (pch-buf) > sizeof(username))
+ {
+ fprintf(stdout, "Input exceeds maximum username length!\n\n");
+ continue;
+ }
+ strncpy(username, buf, pch-buf-1);
+
+ if (strlen(pch) >= sizeof(password))
+ {
+ fprintf(stdout, "Input exceeds maximum password length given:%d max allowed:%d!\n", (int)strlen(pch), MAX_PGPASS_LEN);
+ continue;
+ }
+ strncpy(password, pch, strlen(pch));
+ fprintf(stdout, "USER: %s\n", username);
+ if (updatepasswd)
+ update_pool_passwd(conf_file, username, password, key);
+ else
+ print_encrypted_password(password, key);
+ }
+
+ fclose(fp);
}
static void
@@ -380,6 +512,8 @@ print_usage(const char prog[], int exit_code)
fprintf(stream, " Encryption key to be used for encrypting database passwords.\n");
fprintf(stream, " -f, --config-file=CONFIG_FILE\n");
fprintf(stream, " Specifies the pgpool.conf file.\n");
+ fprintf(stream, " -i, --input-file=INPUT-FILE\n");
+ fprintf(stream, " Specify file containing username and password pairs.\n");
fprintf(stream, " -p, --prompt Prompt for database password using standard input.\n");
fprintf(stream, " -P, --prompt-for-key Prompt for encryption key using standard input.\n");
fprintf(stream, " -m, --update-pass Create encrypted password entry in the pool_passwd file.\n");