Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to read username/password from file #781

Merged
merged 4 commits into from
Jun 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 66 additions & 0 deletions tools/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#include "compat.h"
#endif

/* For when reading auth data from a file */
#define MAXAUTHTOKENLEN 128
#define USERNAMEPREFIX "username:"
#define PASSWORDPREFIX "password:"

void die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
Expand Down Expand Up @@ -125,6 +130,7 @@ static char *amqp_vhost;
static char *amqp_username;
static char *amqp_password;
static int amqp_heartbeat = 0;
static char *amqp_authfile;
#ifdef WITH_SSL
static int amqp_ssl = 0;
static char *amqp_cacert = "/etc/ssl/certs/cacert.pem";
Expand All @@ -147,6 +153,8 @@ struct poptOption connect_options[] = {
"the password to login with", "password"},
{"heartbeat", 0, POPT_ARG_INT, &amqp_heartbeat, 0,
"heartbeat interval, set to 0 to disable", "heartbeat"},
{"authfile", 0, POPT_ARG_STRING, &amqp_authfile, 0,
"path to file containing username/password for authentication", "file"},
#ifdef WITH_SSL
{"ssl", 0, POPT_ARG_NONE, &amqp_ssl, 0, "connect over SSL/TLS", NULL},
{"cacert", 0, POPT_ARG_STRING, &amqp_cacert, 0,
Expand All @@ -158,6 +166,50 @@ struct poptOption connect_options[] = {
#endif /* WITH_SSL */
{NULL, '\0', 0, NULL, 0, NULL, NULL}};

void read_authfile(const char *path) {
size_t n;
FILE *fp = NULL;
char token[MAXAUTHTOKENLEN];

if ((amqp_username = malloc(MAXAUTHTOKENLEN)) == NULL ||
(amqp_password = malloc(MAXAUTHTOKENLEN)) == NULL) {
die("Out of memory");
} else if ((fp = fopen(path, "r")) == NULL) {
die("Could not read auth data file %s", path);
}

if (fgets(token, MAXAUTHTOKENLEN, fp) == NULL ||
strncmp(token, USERNAMEPREFIX, strlen(USERNAMEPREFIX))) {
die("Malformed auth file (missing username)");
}
strncpy(amqp_username, &token[strlen(USERNAMEPREFIX)], MAXAUTHTOKENLEN);
/* Missing newline means token was cut off */
n = strlen(amqp_username);
if (amqp_username[n - 1] != '\n') {
die("Username too long");
} else {
amqp_username[n - 1] = '\0';
}

if (fgets(token, MAXAUTHTOKENLEN, fp) == NULL ||
strncmp(token, PASSWORDPREFIX, strlen(PASSWORDPREFIX))) {
die("Malformed auth file (missing password)");
}
strncpy(amqp_password, &token[strlen(PASSWORDPREFIX)], MAXAUTHTOKENLEN);
/* Missing newline means token was cut off */
n = strlen(amqp_password);
if (amqp_password[n - 1] != '\n') {
die("Password too long");
} else {
amqp_password[n - 1] = '\0';
}

(void)fgetc(fp);
if (!feof(fp)) {
die("Malformed auth file (trailing data)");
}
}

static void init_connection_info(struct amqp_connection_info *ci) {
ci->user = NULL;
ci->password = NULL;
Expand Down Expand Up @@ -237,6 +289,8 @@ static void init_connection_info(struct amqp_connection_info *ci) {
if (amqp_username) {
if (amqp_url) {
die("--username and --url options cannot be used at the same time");
} else if (amqp_authfile) {
die("--username and --authfile options cannot be used at the same time");
}

ci->user = amqp_username;
Expand All @@ -245,11 +299,23 @@ static void init_connection_info(struct amqp_connection_info *ci) {
if (amqp_password) {
if (amqp_url) {
die("--password and --url options cannot be used at the same time");
} else if (amqp_authfile) {
die("--password and --authfile options cannot be used at the same time");
}

ci->password = amqp_password;
}

if (amqp_authfile) {
if (amqp_url) {
die("--authfile and --url options cannot be used at the same time");
}

read_authfile(amqp_authfile);
ci->user = amqp_username;
ci->password = amqp_password;
}

if (amqp_vhost) {
if (amqp_url) {
die("--vhost and --url options cannot be used at the same time");
Expand Down