imap-send: drop global `imap_server_conf` variable
In "imap-send.c", we have a global `sturct imap_server_conf` variable that keeps track of the configuration of the IMAP server. This variable is being populated mostly via the Git configuration. Refactor the code to allocate the structure on the stack instead of having it globally. This change allows us to track its lifetime more closely. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
c77756015e
commit
cea1ff7f1f
57
imap-send.c
57
imap-send.c
|
@ -82,10 +82,6 @@ struct imap_server_conf {
|
||||||
char *auth_method;
|
char *auth_method;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct imap_server_conf server = {
|
|
||||||
.ssl_verify = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct imap_socket {
|
struct imap_socket {
|
||||||
int fd[2];
|
int fd[2];
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
|
@ -110,6 +106,7 @@ struct imap {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imap_store {
|
struct imap_store {
|
||||||
|
const struct imap_server_conf *cfg;
|
||||||
/* currently open mailbox */
|
/* currently open mailbox */
|
||||||
const char *name; /* foreign! maybe preset? */
|
const char *name; /* foreign! maybe preset? */
|
||||||
int uidvalidity;
|
int uidvalidity;
|
||||||
|
@ -194,8 +191,8 @@ static void socket_perror(const char *func, struct imap_socket *sock, int ret)
|
||||||
|
|
||||||
#ifdef NO_OPENSSL
|
#ifdef NO_OPENSSL
|
||||||
static int ssl_socket_connect(struct imap_socket *sock UNUSED,
|
static int ssl_socket_connect(struct imap_socket *sock UNUSED,
|
||||||
int use_tls_only UNUSED,
|
const struct imap_server_conf *cfg,
|
||||||
int verify UNUSED)
|
int use_tls_only UNUSED)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "SSL requested but SSL support not compiled in\n");
|
fprintf(stderr, "SSL requested but SSL support not compiled in\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -250,7 +247,9 @@ static int verify_hostname(X509 *cert, const char *hostname)
|
||||||
cname, 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)
|
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
|
||||||
const SSL_METHOD *meth;
|
const SSL_METHOD *meth;
|
||||||
|
@ -279,7 +278,7 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
||||||
if (use_tls_only)
|
if (use_tls_only)
|
||||||
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
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);
|
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
|
||||||
if (!SSL_CTX_set_default_verify_paths(ctx)) {
|
if (!SSL_CTX_set_default_verify_paths(ctx)) {
|
||||||
|
@ -306,9 +305,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
|
* OpenSSL does not document this function, but the implementation
|
||||||
* returns 1 on success, 0 on failure after calling SSLerr().
|
* 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)
|
if (ret != 1)
|
||||||
warning("SSL_set_tlsext_host_name(%s) failed.", server.host);
|
warning("SSL_set_tlsext_host_name(%s) failed.", cfg->host);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = SSL_connect(sock->ssl);
|
ret = SSL_connect(sock->ssl);
|
||||||
|
@ -317,12 +316,12 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify) {
|
if (cfg->ssl_verify) {
|
||||||
/* make sure the hostname matches that of the certificate */
|
/* make sure the hostname matches that of the certificate */
|
||||||
cert = SSL_get_peer_certificate(sock->ssl);
|
cert = SSL_get_peer_certificate(sock->ssl);
|
||||||
if (!cert)
|
if (!cert)
|
||||||
return error("unable to get peer certificate.");
|
return error("unable to get peer certificate.");
|
||||||
if (verify_hostname(cert, server.host) < 0)
|
if (verify_hostname(cert, cfg->host) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,7 +894,7 @@ static int auth_cram_md5(struct imap_store *ctx, const char *prompt)
|
||||||
int ret;
|
int ret;
|
||||||
char *response;
|
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));
|
ret = socket_write(&ctx->imap->buf.sock, response, strlen(response));
|
||||||
if (ret != strlen(response))
|
if (ret != strlen(response))
|
||||||
|
@ -935,6 +934,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c
|
||||||
|
|
||||||
CALLOC_ARRAY(ctx, 1);
|
CALLOC_ARRAY(ctx, 1);
|
||||||
|
|
||||||
|
ctx->cfg = srvc;
|
||||||
ctx->imap = CALLOC_ARRAY(imap, 1);
|
ctx->imap = CALLOC_ARRAY(imap, 1);
|
||||||
imap->buf.sock.fd[0] = imap->buf.sock.fd[1] = -1;
|
imap->buf.sock.fd[0] = imap->buf.sock.fd[1] = -1;
|
||||||
imap->in_progress_append = &imap->in_progress;
|
imap->in_progress_append = &imap->in_progress;
|
||||||
|
@ -1035,7 +1035,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c
|
||||||
imap->buf.sock.fd[1] = dup(s);
|
imap->buf.sock.fd[1] = dup(s);
|
||||||
|
|
||||||
if (srvc->use_ssl &&
|
if (srvc->use_ssl &&
|
||||||
ssl_socket_connect(&imap->buf.sock, 0, srvc->ssl_verify)) {
|
ssl_socket_connect(&imap->buf.sock, srvc, 0)) {
|
||||||
close(s);
|
close(s);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1068,8 +1068,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c
|
||||||
if (!srvc->use_ssl && CAP(STARTTLS)) {
|
if (!srvc->use_ssl && CAP(STARTTLS)) {
|
||||||
if (imap_exec(ctx, NULL, "STARTTLS") != RESP_OK)
|
if (imap_exec(ctx, NULL, "STARTTLS") != RESP_OK)
|
||||||
goto bail;
|
goto bail;
|
||||||
if (ssl_socket_connect(&imap->buf.sock, 1,
|
if (ssl_socket_connect(&imap->buf.sock, srvc, 1))
|
||||||
srvc->ssl_verify))
|
|
||||||
goto bail;
|
goto bail;
|
||||||
/* capabilities may have changed, so get the new capabilities */
|
/* capabilities may have changed, so get the new capabilities */
|
||||||
if (imap_exec(ctx, NULL, "CAPABILITY") != RESP_OK)
|
if (imap_exec(ctx, NULL, "CAPABILITY") != RESP_OK)
|
||||||
|
@ -1299,23 +1298,24 @@ static int split_msg(struct strbuf *all_msgs, struct strbuf *msg, int *ofs)
|
||||||
static int git_imap_config(const char *var, const char *val,
|
static int git_imap_config(const char *var, const char *val,
|
||||||
const struct config_context *ctx, void *cb)
|
const struct config_context *ctx, void *cb)
|
||||||
{
|
{
|
||||||
|
struct imap_server_conf *cfg = cb;
|
||||||
|
|
||||||
if (!strcmp("imap.sslverify", var))
|
if (!strcmp("imap.sslverify", var))
|
||||||
server.ssl_verify = git_config_bool(var, val);
|
cfg->ssl_verify = git_config_bool(var, val);
|
||||||
else if (!strcmp("imap.preformattedhtml", var))
|
else if (!strcmp("imap.preformattedhtml", var))
|
||||||
server.use_html = git_config_bool(var, val);
|
cfg->use_html = git_config_bool(var, val);
|
||||||
else if (!strcmp("imap.folder", var))
|
else if (!strcmp("imap.folder", var))
|
||||||
return git_config_string(&server.folder, var, val);
|
return git_config_string(&cfg->folder, var, val);
|
||||||
else if (!strcmp("imap.user", var))
|
else if (!strcmp("imap.user", var))
|
||||||
return git_config_string(&server.user, var, val);
|
return git_config_string(&cfg->user, var, val);
|
||||||
else if (!strcmp("imap.pass", var))
|
else if (!strcmp("imap.pass", var))
|
||||||
return git_config_string(&server.pass, var, val);
|
return git_config_string(&cfg->pass, var, val);
|
||||||
else if (!strcmp("imap.tunnel", var))
|
else if (!strcmp("imap.tunnel", var))
|
||||||
return git_config_string(&server.tunnel, var, val);
|
return git_config_string(&cfg->tunnel, var, val);
|
||||||
else if (!strcmp("imap.authmethod", var))
|
else if (!strcmp("imap.authmethod", var))
|
||||||
return git_config_string(&server.auth_method, var, val);
|
return git_config_string(&cfg->auth_method, var, val);
|
||||||
else if (!strcmp("imap.port", var))
|
else if (!strcmp("imap.port", var))
|
||||||
server.port = git_config_int(var, val, ctx->kvi);
|
cfg->port = git_config_int(var, val, ctx->kvi);
|
||||||
else if (!strcmp("imap.host", var)) {
|
else if (!strcmp("imap.host", var)) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
return config_error_nonbool(var);
|
return config_error_nonbool(var);
|
||||||
|
@ -1324,11 +1324,11 @@ static int git_imap_config(const char *var, const char *val,
|
||||||
val += 5;
|
val += 5;
|
||||||
else if (starts_with(val, "imaps:")) {
|
else if (starts_with(val, "imaps:")) {
|
||||||
val += 6;
|
val += 6;
|
||||||
server.use_ssl = 1;
|
cfg->use_ssl = 1;
|
||||||
}
|
}
|
||||||
if (starts_with(val, "//"))
|
if (starts_with(val, "//"))
|
||||||
val += 2;
|
val += 2;
|
||||||
server.host = xstrdup(val);
|
cfg->host = xstrdup(val);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return git_default_config(var, val, ctx, cb);
|
return git_default_config(var, val, ctx, cb);
|
||||||
|
@ -1497,12 +1497,15 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server,
|
||||||
|
|
||||||
int cmd_main(int argc, const char **argv)
|
int cmd_main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
|
struct imap_server_conf server = {
|
||||||
|
.ssl_verify = 1,
|
||||||
|
};
|
||||||
struct strbuf all_msgs = STRBUF_INIT;
|
struct strbuf all_msgs = STRBUF_INIT;
|
||||||
int total;
|
int total;
|
||||||
int nongit_ok;
|
int nongit_ok;
|
||||||
|
|
||||||
setup_git_directory_gently(&nongit_ok);
|
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);
|
argc = parse_options(argc, (const char **)argv, "", imap_send_options, imap_send_usage, 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue