blob: dfd1f98759d6ca1bcbb85289217ef7b72b5e19cc [file] [log] [blame]
Andrew Geissler8f840682023-07-21 09:09:43 -05001CVE: CVE-2023-35789
2Upstream-Status: Backport [ https://github.com/alanxz/rabbitmq-c/commit/463054383fbeef889b409a7f843df5365288e2a0 ]
3Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
4
5From 463054383fbeef889b409a7f843df5365288e2a0 Mon Sep 17 00:00:00 2001
6From: Christian Kastner <ckk@kvr.at>
7Date: Tue, 13 Jun 2023 14:21:52 +0200
8Subject: [PATCH] Add option to read username/password from file (#781)
9
10* Add option to read username/password from file
11---
12 tools/common.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
13 1 file changed, 66 insertions(+)
14
15diff --git a/tools/common.c b/tools/common.c
16index 73b47e25..7efe557b 100644
17--- a/tools/common.c
18+++ b/tools/common.c
19@@ -18,6 +18,11 @@
20 #include "compat.h"
21 #endif
22
23+/* For when reading auth data from a file */
24+#define MAXAUTHTOKENLEN 128
25+#define USERNAMEPREFIX "username:"
26+#define PASSWORDPREFIX "password:"
27+
28 void die(const char *fmt, ...) {
29 va_list ap;
30 va_start(ap, fmt);
31@@ -125,6 +130,7 @@ static char *amqp_vhost;
32 static char *amqp_username;
33 static char *amqp_password;
34 static int amqp_heartbeat = 0;
35+static char *amqp_authfile;
36 #ifdef WITH_SSL
37 static int amqp_ssl = 0;
38 static char *amqp_cacert = "/etc/ssl/certs/cacert.pem";
39@@ -147,6 +153,8 @@ struct poptOption connect_options[] = {
40 "the password to login with", "password"},
41 {"heartbeat", 0, POPT_ARG_INT, &amqp_heartbeat, 0,
42 "heartbeat interval, set to 0 to disable", "heartbeat"},
43+ {"authfile", 0, POPT_ARG_STRING, &amqp_authfile, 0,
44+ "path to file containing username/password for authentication", "file"},
45 #ifdef WITH_SSL
46 {"ssl", 0, POPT_ARG_NONE, &amqp_ssl, 0, "connect over SSL/TLS", NULL},
47 {"cacert", 0, POPT_ARG_STRING, &amqp_cacert, 0,
48@@ -158,6 +166,50 @@ struct poptOption connect_options[] = {
49 #endif /* WITH_SSL */
50 {NULL, '\0', 0, NULL, 0, NULL, NULL}};
51
52+void read_authfile(const char *path) {
53+ size_t n;
54+ FILE *fp = NULL;
55+ char token[MAXAUTHTOKENLEN];
56+
57+ if ((amqp_username = malloc(MAXAUTHTOKENLEN)) == NULL ||
58+ (amqp_password = malloc(MAXAUTHTOKENLEN)) == NULL) {
59+ die("Out of memory");
60+ } else if ((fp = fopen(path, "r")) == NULL) {
61+ die("Could not read auth data file %s", path);
62+ }
63+
64+ if (fgets(token, MAXAUTHTOKENLEN, fp) == NULL ||
65+ strncmp(token, USERNAMEPREFIX, strlen(USERNAMEPREFIX))) {
66+ die("Malformed auth file (missing username)");
67+ }
68+ strncpy(amqp_username, &token[strlen(USERNAMEPREFIX)], MAXAUTHTOKENLEN);
69+ /* Missing newline means token was cut off */
70+ n = strlen(amqp_username);
71+ if (amqp_username[n - 1] != '\n') {
72+ die("Username too long");
73+ } else {
74+ amqp_username[n - 1] = '\0';
75+ }
76+
77+ if (fgets(token, MAXAUTHTOKENLEN, fp) == NULL ||
78+ strncmp(token, PASSWORDPREFIX, strlen(PASSWORDPREFIX))) {
79+ die("Malformed auth file (missing password)");
80+ }
81+ strncpy(amqp_password, &token[strlen(PASSWORDPREFIX)], MAXAUTHTOKENLEN);
82+ /* Missing newline means token was cut off */
83+ n = strlen(amqp_password);
84+ if (amqp_password[n - 1] != '\n') {
85+ die("Password too long");
86+ } else {
87+ amqp_password[n - 1] = '\0';
88+ }
89+
90+ (void)fgetc(fp);
91+ if (!feof(fp)) {
92+ die("Malformed auth file (trailing data)");
93+ }
94+}
95+
96 static void init_connection_info(struct amqp_connection_info *ci) {
97 ci->user = NULL;
98 ci->password = NULL;
99@@ -237,6 +289,8 @@ static void init_connection_info(struct amqp_connection_info *ci) {
100 if (amqp_username) {
101 if (amqp_url) {
102 die("--username and --url options cannot be used at the same time");
103+ } else if (amqp_authfile) {
104+ die("--username and --authfile options cannot be used at the same time");
105 }
106
107 ci->user = amqp_username;
108@@ -245,11 +299,23 @@ static void init_connection_info(struct amqp_connection_info *ci) {
109 if (amqp_password) {
110 if (amqp_url) {
111 die("--password and --url options cannot be used at the same time");
112+ } else if (amqp_authfile) {
113+ die("--password and --authfile options cannot be used at the same time");
114 }
115
116 ci->password = amqp_password;
117 }
118
119+ if (amqp_authfile) {
120+ if (amqp_url) {
121+ die("--authfile and --url options cannot be used at the same time");
122+ }
123+
124+ read_authfile(amqp_authfile);
125+ ci->user = amqp_username;
126+ ci->password = amqp_password;
127+ }
128+
129 if (amqp_vhost) {
130 if (amqp_url) {
131 die("--vhost and --url options cannot be used at the same time");