0001-Add-option-to-read-username-password-from-file.patch 4.3 KB

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