}
static void
-auth_user_info_parse_arg(struct auth_user_info *info, const char *arg)
+auth_user_info_parse_arg(struct auth_user_info *info, const char *arg,
+ ARRAY_TYPE(const_string) *forward_fields)
{
const char *key, *value;
if (net_str2port(value, &info->real_remote_port) < 0)
i_fatal("real_rport: Invalid port number");
} else if (str_begins(arg, "forward_", &key)) {
- value = strchr(key, '=');
-
- if (value == NULL)
- value = "";
- else
- key = t_strdup_until(key, value++);
- key = str_tabescape(key);
- value = str_tabescape(value);
- if (info->forward_fields == NULL) {
- info->forward_fields =
- t_strdup_printf("%s=%s", key, value);
- } else {
- info->forward_fields =
- t_strdup_printf("%s\t%s=%s", info->forward_fields, key, value);
- }
+ array_push_back(forward_fields, &key);
} else {
if (!array_is_created(&info->extra_fields))
t_array_init(&info->extra_fields, 4);
static void
auth_user_info_parse(struct auth_user_info *info, const char *const *args)
{
+ ARRAY_TYPE(const_string) forward_fields;
+ t_array_init(&forward_fields, 8);
for (unsigned int i = 0; args[i] != NULL; i++)
- auth_user_info_parse_arg(info, args[i]);
+ auth_user_info_parse_arg(info, args[i], &forward_fields);
+ if (array_count(&forward_fields) > 0) {
+ array_append_zero(&forward_fields);
+ info->forward_fields = array_front(&forward_fields);
+ }
}
static void
doveadm_mail_cmd_input_read(ctx);
}
-const char *
+const char *const *
doveadm_mail_get_forward_fields(struct doveadm_mail_cmd_context *ctx)
{
- const char *field;
- string_t *str;
-
if (!array_is_created(&ctx->proxy_forward_fields))
return NULL;
- str = t_str_new(128);
- array_foreach_elem(&ctx->proxy_forward_fields, field) {
- if (str_len(str) > 0)
- str_append_c(str, '\t');
- str_append_tabescaped(str, field);
- }
- return str_c(str);
+ array_append_zero(&ctx->proxy_forward_fields);
+ array_pop_back(&ctx->proxy_forward_fields);
+ return array_front(&ctx->proxy_forward_fields);
}
struct mailbox *
/* Request input stream to be read (from stdin). This must be called from
the command's init() function. */
void doveadm_mail_get_input(struct doveadm_mail_cmd_context *ctx);
-const char *
+const char *const *
doveadm_mail_get_forward_fields(struct doveadm_mail_cmd_context *ctx);
struct mailbox *
str_append_tabescaped(str, info->client_id);
event_add_str(request->event, "client_id", info->client_id);
}
- if (info->forward_fields != NULL &&
- *info->forward_fields != '\0') {
+ if (info->forward_fields != NULL && info->forward_fields[0] != NULL) {
+ string_t *forward = t_str_new(64);
+ str_append_tabescaped(forward, info->forward_fields[0]);
+ for (unsigned int i = 1; info->forward_fields[i] != NULL; i++) {
+ str_append_c(forward, '\t');
+ str_append_tabescaped(forward, info->forward_fields[i]);
+ }
str_append(str, "\tforward_fields=");
- str_append_tabescaped(str, info->forward_fields);
+ str_append_tabescaped(str, str_c(forward));
}
if (array_is_created(&info->extra_fields)) {
const char *const *fieldp;
const char *cert_username;
const char *local_name;
const char *client_id;
- const char *forward_fields;
+ const char *const *forward_fields;
ARRAY_TYPE(const_string) extra_fields;
unsigned int ssl_cipher_bits;
str_printfa(str, "\treal_rport=%d", info->real_remote_port);
if (info->debug)
str_append(str, "\tdebug");
- if (info->forward_fields != NULL &&
- *info->forward_fields != '\0') {
+ if (info->forward_fields != NULL && info->forward_fields[0] != NULL) {
+ string_t *forward = t_str_new(64);
+ str_append_tabescaped(forward, info->forward_fields[0]);
+ for (unsigned int i = 1; info->forward_fields[i] != NULL; i++) {
+ str_append_c(forward, '\t');
+ str_append_tabescaped(forward, info->forward_fields[i]);
+ }
str_append(str, "\tforward_fields=");
- str_append_tabescaped(str, info->forward_fields);
+ str_append_tabescaped(str, str_c(forward));
}
if (array_is_created(&info->extra_fields)) {
array_foreach(&info->extra_fields, fieldp) {
const char *local_name;
struct ip_addr local_ip, remote_ip, real_local_ip, real_remote_ip;
in_port_t local_port, remote_port, real_local_port, real_remote_port;
- const char *forward_fields;
+ const char *const *forward_fields;
ARRAY_TYPE(const_string) extra_fields;
bool debug;
};
const char *const *userdb_fields;
- const char *forward_fields;
+ const char *const *forward_fields;
/* Override specified global flags */
enum mail_storage_service_flags flags_override_add;
#include "lmtp-common.h"
#include "str.h"
+#include "strescape.h"
#include "istream.h"
#include "istream-concat.h"
#include "ostream.h"
return -1;
}
- lrcpt->forward_fields = p_strdup(rcpt->pool, str_c(xforward));
+ char **fields = p_strsplit_tabescaped(rcpt->pool, str_c(xforward));
+ lrcpt->forward_fields = (const char *const *)fields;
return 0;
}
void *backend_context;
const char *session_id;
- const char *forward_fields;
+ const char *const *forward_fields;
/* Module-specific contexts. */
ARRAY(union lmtp_recipient_module_context *) module_contexts;
t_array_init(&info.extra_fields, N_ELEMENTS(extra_fields));
array_append(&info.extra_fields, extra_fields,
N_ELEMENTS(extra_fields));
- if (client->forward_fields != NULL)
- info.forward_fields = str_c(client->forward_fields);
+ if (array_is_created(&client->forward_fields)) {
+ array_append_zero(&client->forward_fields);
+ array_pop_back(&client->forward_fields);
+ info.forward_fields = array_front(&client->forward_fields);
+ }
client->reauth_request =
auth_client_request_new(auth_client, &info,
proxy_redirect_reauth_callback, client);
client_disconnect(client, reason, !client->login_success);
pool_unref(&client->preproxy_pool);
- client->forward_fields = NULL;
+ i_zero(&client->forward_fields);
client->client_id = NULL;
if (client->master_tag != 0) {
void client_add_forward_field(struct client *client, const char *key,
const char *value)
{
- if (client->forward_fields == NULL)
- client->forward_fields = str_new(client->preproxy_pool, 32);
- else
- str_append_c(client->forward_fields, '\t');
+ if (!array_is_created(&client->forward_fields))
+ p_array_init(&client->forward_fields, client->preproxy_pool, 8);
/* prefixing is done by auth process */
- str_append_tabescaped(client->forward_fields, key);
- str_append_c(client->forward_fields, '=');
- str_append_tabescaped(client->forward_fields, value);
+ const char *entry =
+ p_strdup_printf(client->preproxy_pool, "%s=%s", key, value);
+ array_push_back(&client->forward_fields, &entry);
}
bool client_forward_decode_base64(struct client *client, const char *value)
{
size_t value_len = strlen(value);
- string_t *str = str_new(client->preproxy_pool,
- MAX_BASE64_DECODED_SIZE(value_len));
+ string_t *str = t_str_new(MAX_BASE64_DECODED_SIZE(value_len));
if (base64_decode(value, value_len, str) < 0)
return FALSE;
- client->forward_fields = str;
+ char **_fields = p_strsplit_tabescaped(client->preproxy_pool,
+ str_c(str));
+ const char *const *fields = (const char *const *)_fields;
+ unsigned int fields_count = str_array_length(fields);
+ p_array_init(&client->forward_fields,
+ client->preproxy_pool, fields_count);
+ array_append(&client->forward_fields, fields, fields_count);
return TRUE;
}
const char *client_cert_common_name;
string_t *client_id;
- string_t *forward_fields;
+ ARRAY_TYPE(const_string) forward_fields;
int fd;
struct istream *input;
/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "login-common.h"
+#include "array.h"
#include "str.h"
#include "base64.h"
#include "buffer.h"
info_r->real_remote_port = client->real_remote_port;
if (client->client_id != NULL)
info_r->client_id = str_c(client->client_id);
- if (client->forward_fields != NULL)
- info_r->forward_fields = str_c(client->forward_fields);
+ if (array_is_created(&client->forward_fields)) {
+ array_append_zero(&client->forward_fields);
+ array_pop_back(&client->forward_fields);
+ info_r->forward_fields = array_front(&client->forward_fields);
+ }
return 0;
}