void imap_append_astring(string_t *dest, const char *src) { unsigned int i; i_assert(src != NULL); for (i = 0; src[i] != '\0'; i++) { if (!IS_ASTRING_CHAR(src[i])) { imap_append_string(dest, src); return; } } /* don't mix up NIL and "NIL"! */ if (i == 0 || strcasecmp(src, "NIL") == 0) imap_append_string(dest, src); else str_append(dest, src); }
static void list_namespaces(struct mail_namespace *ns, enum mail_namespace_type type, string_t *str) { string_t *mutf7_prefix = t_str_new(64); char ns_sep; bool found = FALSE; while (ns != NULL) { if (ns->type == type && (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) { if (!found) { str_append_c(str, '('); found = TRUE; } ns_sep = mail_namespace_get_sep(ns); str_append_c(str, '('); str_truncate(mutf7_prefix, 0); if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) { i_panic("LIST: Namespace prefix not UTF-8: %s", ns->prefix); } imap_append_string(str, str_c(mutf7_prefix)); str_append(str, " \""); if (ns_sep == '\\') str_append_c(str, '\\'); str_append_c(str, ns_sep); str_append(str, "\")"); } ns = ns->next; } if (found) str_append_c(str, ')'); else str_append(str, "NIL"); }
static void proxy_write_id(struct imap_client *client, string_t *str) { i_assert(client->common.proxy_ttl > 1); str_append(str, "I ID ("); if (client->common.client_id != NULL && str_len(client->common.client_id) > 0) { str_append_str(str, client->common.client_id); str_append_c(str, ' '); } str_printfa(str, "\"x-session-id\" \"%s\" " "\"x-originating-ip\" \"%s\" " "\"x-originating-port\" \"%u\" " "\"x-connected-ip\" \"%s\" " "\"x-connected-port\" \"%u\" " "\"x-proxy-ttl\" \"%u\"", client_get_session_id(&client->common), net_ip2addr(&client->common.ip), client->common.remote_port, net_ip2addr(&client->common.local_ip), client->common.local_port, client->common.proxy_ttl - 1); /* append any forward_ variables to request */ for(const char *const *ptr = client->common.auth_passdb_args; *ptr != NULL; ptr++) { if (strncasecmp(*ptr, "forward_", 8) == 0) { const char *key = t_strconcat("x-forward-", t_strcut((*ptr)+8, '='), NULL); const char *val = i_strchr_to_next(*ptr, '='); str_append_c(str, ' '); imap_append_string(str, key); str_append_c(str, ' '); imap_append_nstring(str, val); } } str_append(str, ")\r\n"); }
static int proxy_write_login(struct imap_client *client, string_t *str) { struct dsasl_client_settings sasl_set; const unsigned char *output; unsigned int len; const char *mech_name, *error; /* Send CAPABILITY command if we don't know the capabilities yet. Also as kind of a Dovecot-backend workaround if the client insisted on sending CAPABILITY command (even though our banner already sent it), send the (unnecessary) CAPABILITY command to backend as well to avoid sending the CAPABILITY reply twice (untagged and OK resp code). */ if (!client->proxy_capability_request_sent && (client->proxy_backend_capability == NULL || client->client_ignores_capability_resp_code)) { client->proxy_capability_request_sent = TRUE; str_append(str, "C CAPABILITY\r\n"); if (client->common.proxy_nopipelining) { /* authenticate only after receiving C OK reply. */ return 0; } } if (client->common.proxy_mech == NULL) { /* logging in normally - use LOGIN command */ if (client->proxy_logindisabled && login_proxy_get_ssl_flags(client->common.login_proxy) == 0) { client_log_err(&client->common, "proxy: Remote advertised LOGINDISABLED and SSL/TLS not enabled"); return -1; } str_append(str, "L LOGIN "); imap_append_string(str, client->common.proxy_user); str_append_c(str, ' '); imap_append_string(str, client->common.proxy_password); str_append(str, "\r\n"); proxy_free_password(&client->common); return 0; } i_assert(client->common.proxy_sasl_client == NULL); memset(&sasl_set, 0, sizeof(sasl_set)); sasl_set.authid = client->common.proxy_master_user != NULL ? client->common.proxy_master_user : client->common.proxy_user; sasl_set.authzid = client->common.proxy_user; sasl_set.password = client->common.proxy_password; client->common.proxy_sasl_client = dsasl_client_new(client->common.proxy_mech, &sasl_set); mech_name = dsasl_client_mech_get_name(client->common.proxy_mech); str_append(str, "L AUTHENTICATE "); str_append(str, mech_name); if (client->proxy_sasl_ir) { if (dsasl_client_output(client->common.proxy_sasl_client, &output, &len, &error) < 0) { client_log_err(&client->common, t_strdup_printf( "proxy: SASL mechanism %s init failed: %s", mech_name, error)); return -1; } str_append_c(str, ' '); if (len == 0) str_append_c(str, '='); else base64_encode(output, len, str); } str_append(str, "\r\n"); proxy_free_password(&client->common); return 0; }