diff options
Diffstat (limited to 'imap-send.c')
| -rw-r--r-- | imap-send.c | 142 |
1 files changed, 82 insertions, 60 deletions
diff --git a/imap-send.c b/imap-send.c index c0130d0e02..da3e7ec17e 100644 --- a/imap-send.c +++ b/imap-send.c @@ -69,21 +69,16 @@ static void imap_warn(const char *, ...); static char *next_arg(char **); struct imap_server_conf { - const char *name; - const char *tunnel; - const char *host; + char *tunnel; + char *host; int port; - const char *folder; - const char *user; - const char *pass; + char *folder; + char *user; + char *pass; int use_ssl; int ssl_verify; int use_html; - const char *auth_method; -}; - -static struct imap_server_conf server = { - .ssl_verify = 1, + char *auth_method; }; struct imap_socket { @@ -110,6 +105,7 @@ struct imap { }; struct imap_store { + const struct imap_server_conf *cfg; /* currently open mailbox */ const char *name; /* foreign! maybe preset? */ int uidvalidity; @@ -194,8 +190,8 @@ static void socket_perror(const char *func, struct imap_socket *sock, int ret) #ifdef NO_OPENSSL static int ssl_socket_connect(struct imap_socket *sock UNUSED, - int use_tls_only UNUSED, - int verify UNUSED) + const struct imap_server_conf *cfg, + int use_tls_only UNUSED) { fprintf(stderr, "SSL requested but SSL support not compiled in\n"); return -1; @@ -250,7 +246,9 @@ static int verify_hostname(X509 *cert, const char *hostname) cname, hostname); } -static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int verify) +static int ssl_socket_connect(struct imap_socket *sock, + const struct imap_server_conf *cfg, + int use_tls_only) { #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) const SSL_METHOD *meth; @@ -279,7 +277,7 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve if (use_tls_only) SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - if (verify) + if (cfg->ssl_verify) SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); if (!SSL_CTX_set_default_verify_paths(ctx)) { @@ -306,9 +304,9 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve * OpenSSL does not document this function, but the implementation * returns 1 on success, 0 on failure after calling SSLerr(). */ - ret = SSL_set_tlsext_host_name(sock->ssl, server.host); + ret = SSL_set_tlsext_host_name(sock->ssl, cfg->host); if (ret != 1) - warning("SSL_set_tlsext_host_name(%s) failed.", server.host); + warning("SSL_set_tlsext_host_name(%s) failed.", cfg->host); #endif ret = SSL_connect(sock->ssl); @@ -317,12 +315,12 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve return -1; } - if (verify) { + if (cfg->ssl_verify) { /* make sure the hostname matches that of the certificate */ cert = SSL_get_peer_certificate(sock->ssl); if (!cert) return error("unable to get peer certificate."); - if (verify_hostname(cert, server.host) < 0) + if (verify_hostname(cert, cfg->host) < 0) return -1; } @@ -895,7 +893,7 @@ static int auth_cram_md5(struct imap_store *ctx, const char *prompt) int ret; char *response; - response = cram(prompt, server.user, server.pass); + response = cram(prompt, ctx->cfg->user, ctx->cfg->pass); ret = socket_write(&ctx->imap->buf.sock, response, strlen(response)); if (ret != strlen(response)) @@ -935,6 +933,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c CALLOC_ARRAY(ctx, 1); + ctx->cfg = srvc; ctx->imap = CALLOC_ARRAY(imap, 1); imap->buf.sock.fd[0] = imap->buf.sock.fd[1] = -1; imap->in_progress_append = &imap->in_progress; @@ -1035,7 +1034,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c imap->buf.sock.fd[1] = dup(s); if (srvc->use_ssl && - ssl_socket_connect(&imap->buf.sock, 0, srvc->ssl_verify)) { + ssl_socket_connect(&imap->buf.sock, srvc, 0)) { close(s); goto bail; } @@ -1068,8 +1067,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c if (!srvc->use_ssl && CAP(STARTTLS)) { if (imap_exec(ctx, NULL, "STARTTLS") != RESP_OK) goto bail; - if (ssl_socket_connect(&imap->buf.sock, 1, - srvc->ssl_verify)) + if (ssl_socket_connect(&imap->buf.sock, srvc, 1)) goto bail; /* capabilities may have changed, so get the new capabilities */ if (imap_exec(ctx, NULL, "CAPABILITY") != RESP_OK) @@ -1215,9 +1213,9 @@ static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg) static void wrap_in_html(struct strbuf *msg) { struct strbuf buf = STRBUF_INIT; - static char *content_type = "Content-Type: text/html;\n"; - static char *pre_open = "<pre>\n"; - static char *pre_close = "</pre>\n"; + static const char *content_type = "Content-Type: text/html;\n"; + static const char *pre_open = "<pre>\n"; + static const char *pre_close = "</pre>\n"; const char *body = strstr(msg->buf, "\n\n"); if (!body) @@ -1299,24 +1297,30 @@ static int split_msg(struct strbuf *all_msgs, struct strbuf *msg, int *ofs) static int git_imap_config(const char *var, const char *val, const struct config_context *ctx, void *cb) { - - if (!strcmp("imap.sslverify", var)) - server.ssl_verify = git_config_bool(var, val); - else if (!strcmp("imap.preformattedhtml", var)) - server.use_html = git_config_bool(var, val); - else if (!strcmp("imap.folder", var)) - return git_config_string(&server.folder, var, val); - else if (!strcmp("imap.user", var)) - return git_config_string(&server.user, var, val); - else if (!strcmp("imap.pass", var)) - return git_config_string(&server.pass, var, val); - else if (!strcmp("imap.tunnel", var)) - return git_config_string(&server.tunnel, var, val); - else if (!strcmp("imap.authmethod", var)) - return git_config_string(&server.auth_method, var, val); - else if (!strcmp("imap.port", var)) - server.port = git_config_int(var, val, ctx->kvi); - else if (!strcmp("imap.host", var)) { + struct imap_server_conf *cfg = cb; + + if (!strcmp("imap.sslverify", var)) { + cfg->ssl_verify = git_config_bool(var, val); + } else if (!strcmp("imap.preformattedhtml", var)) { + cfg->use_html = git_config_bool(var, val); + } else if (!strcmp("imap.folder", var)) { + FREE_AND_NULL(cfg->folder); + return git_config_string(&cfg->folder, var, val); + } else if (!strcmp("imap.user", var)) { + FREE_AND_NULL(cfg->folder); + return git_config_string(&cfg->user, var, val); + } else if (!strcmp("imap.pass", var)) { + FREE_AND_NULL(cfg->folder); + return git_config_string(&cfg->pass, var, val); + } else if (!strcmp("imap.tunnel", var)) { + FREE_AND_NULL(cfg->folder); + return git_config_string(&cfg->tunnel, var, val); + } else if (!strcmp("imap.authmethod", var)) { + FREE_AND_NULL(cfg->folder); + return git_config_string(&cfg->auth_method, var, val); + } else if (!strcmp("imap.port", var)) { + cfg->port = git_config_int(var, val, ctx->kvi); + } else if (!strcmp("imap.host", var)) { if (!val) { return config_error_nonbool(var); } else { @@ -1324,14 +1328,15 @@ static int git_imap_config(const char *var, const char *val, val += 5; else if (starts_with(val, "imaps:")) { val += 6; - server.use_ssl = 1; + cfg->use_ssl = 1; } if (starts_with(val, "//")) val += 2; - server.host = xstrdup(val); + cfg->host = xstrdup(val); } - } else + } else { return git_default_config(var, val, ctx, cb); + } return 0; } @@ -1497,12 +1502,16 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server, int cmd_main(int argc, const char **argv) { + struct imap_server_conf server = { + .ssl_verify = 1, + }; struct strbuf all_msgs = STRBUF_INIT; int total; int nongit_ok; + int ret; setup_git_directory_gently(&nongit_ok); - git_config(git_imap_config, NULL); + git_config(git_imap_config, &server); argc = parse_options(argc, (const char **)argv, "", imap_send_options, imap_send_usage, 0); @@ -1526,42 +1535,55 @@ int cmd_main(int argc, const char **argv) if (!server.folder) { fprintf(stderr, "no imap store specified\n"); - return 1; + ret = 1; + goto out; } if (!server.host) { if (!server.tunnel) { fprintf(stderr, "no imap host specified\n"); - return 1; + ret = 1; + goto out; } - server.host = "tunnel"; + server.host = xstrdup("tunnel"); } /* read the messages */ if (strbuf_read(&all_msgs, 0, 0) < 0) { error_errno(_("could not read from stdin")); - return 1; + ret = 1; + goto out; } if (all_msgs.len == 0) { fprintf(stderr, "nothing to send\n"); - return 1; + ret = 1; + goto out; } total = count_messages(&all_msgs); if (!total) { fprintf(stderr, "no messages to send\n"); - return 1; + ret = 1; + goto out; } /* write it to the imap server */ if (server.tunnel) - return append_msgs_to_imap(&server, &all_msgs, total); - + ret = append_msgs_to_imap(&server, &all_msgs, total); #ifdef USE_CURL_FOR_IMAP_SEND - if (use_curl) - return curl_append_msgs_to_imap(&server, &all_msgs, total); + else if (use_curl) + ret = curl_append_msgs_to_imap(&server, &all_msgs, total); #endif - - return append_msgs_to_imap(&server, &all_msgs, total); + else + ret = append_msgs_to_imap(&server, &all_msgs, total); + +out: + free(server.tunnel); + free(server.host); + free(server.folder); + free(server.user); + free(server.pass); + free(server.auth_method); + return ret; } |
