From: Junio C Hamano Date: Mon, 27 Nov 2017 01:57:00 +0000 (+0900) Subject: Merge branch 'rs/imap-send-next-arg-fix' into maint X-Git-Tag: v2.15.1~7 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/95bf6151dc6e593ce3dd2b04b2ce1c28a5223199?ds=inline;hp=-c Merge branch 'rs/imap-send-next-arg-fix' into maint Error checking in "git imap-send" for empty response has been improved. * rs/imap-send-next-arg-fix: imap-send: handle missing response codes gracefully imap-send: handle NULL return of next_arg() --- 95bf6151dc6e593ce3dd2b04b2ce1c28a5223199 diff --combined imap-send.c index e0523d3427,efa6af4b51..54e6a80fd6 --- a/imap-send.c +++ b/imap-send.c @@@ -18,11 -18,11 +18,11 @@@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ #include "cache.h" +#include "config.h" #include "credential.h" #include "exec_cmd.h" #include "run-command.h" @@@ -34,11 -34,11 +34,11 @@@ typedef void *SSL #include "http.h" #endif -#if defined(USE_CURL_FOR_IMAP_SEND) && defined(NO_OPENSSL) -/* only available option */ +#if defined(USE_CURL_FOR_IMAP_SEND) +/* Always default to curl if it's available. */ #define USE_CURL_DEFAULT 1 #else -/* strictly opt in */ +/* We don't have curl, so continue to use the historical implementation */ #define USE_CURL_DEFAULT 0 #endif @@@ -683,7 -683,7 +683,7 @@@ static int parse_response_code(struct i struct imap *imap = ctx->imap; char *arg, *p; - if (*s != '[') + if (!s || *s != '[') return RESP_OK; /* no response code */ s++; if (!(p = strchr(s, ']'))) { @@@ -692,6 -692,10 +692,10 @@@ } *p++ = 0; arg = next_arg(&s); + if (!arg) { + fprintf(stderr, "IMAP error: empty response code\n"); + return RESP_BAD; + } if (!strcmp("UIDVALIDITY", arg)) { if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg))) { fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n"); @@@ -724,7 -728,8 +728,8 @@@ static int get_cmd_result(struct imap_s { struct imap *imap = ctx->imap; struct imap_cmd *cmdp, **pcmdp; - char *cmd, *arg, *arg1; + char *cmd; + const char *arg, *arg1; int n, resp, resp2, tag; for (;;) { @@@ -732,6 -737,10 +737,10 @@@ return RESP_BAD; arg = next_arg(&cmd); + if (!arg) { + fprintf(stderr, "IMAP error: empty response\n"); + return RESP_BAD; + } if (*arg == '*') { arg = next_arg(&cmd); if (!arg) { @@@ -776,7 -785,8 +785,7 @@@ offsetof(struct imap_cmd, next)); if (cmdp->cb.data) { n = socket_write(&imap->buf.sock, cmdp->cb.data, cmdp->cb.dlen); - free(cmdp->cb.data); - cmdp->cb.data = NULL; + FREE_AND_NULL(cmdp->cb.data); if (n != (int)cmdp->cb.dlen) return RESP_BAD; } else if (cmdp->cb.cont) { @@@ -806,6 -816,8 +815,8 @@@ if (cmdp->cb.cont || cmdp->cb.data) imap->literal_pending = 0; arg = next_arg(&cmd); + if (!arg) + arg = ""; if (!strcmp("OK", arg)) resp = DRV_OK; else { @@@ -860,7 -872,7 +871,7 @@@ static char hexchar(unsigned int b return b < 10 ? '0' + b : 'a' + (b - 10); } -#define ENCODED_SIZE(n) (4*((n+2)/3)) +#define ENCODED_SIZE(n) (4 * DIV_ROUND_UP((n), 3)) static char *cram(const char *challenge_64, const char *user, const char *pass) { int i, resp_len, encoded_len, decoded_len; @@@ -925,25 -937,6 +936,25 @@@ static int auth_cram_md5(struct imap_st return 0; } +static void server_fill_credential(struct imap_server_conf *srvc, struct credential *cred) +{ + if (srvc->user && srvc->pass) + return; + + cred->protocol = xstrdup(srvc->use_ssl ? "imaps" : "imap"); + cred->host = xstrdup(srvc->host); + + cred->username = xstrdup_or_null(srvc->user); + cred->password = xstrdup_or_null(srvc->pass); + + credential_fill(cred); + + if (!srvc->user) + srvc->user = xstrdup(cred->username); + if (!srvc->pass) + srvc->pass = xstrdup(cred->password); +} + static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *folder) { struct credential cred = CREDENTIAL_INIT; @@@ -982,7 -975,7 +993,7 @@@ int gai; char portstr[6]; - snprintf(portstr, sizeof(portstr), "%d", srvc->port); + xsnprintf(portstr, sizeof(portstr), "%d", srvc->port); memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; @@@ -1096,7 -1089,20 +1107,7 @@@ } #endif imap_info("Logging in...\n"); - if (!srvc->user || !srvc->pass) { - cred.protocol = xstrdup(srvc->use_ssl ? "imaps" : "imap"); - cred.host = xstrdup(srvc->host); - - cred.username = xstrdup_or_null(srvc->user); - cred.password = xstrdup_or_null(srvc->pass); - - credential_fill(&cred); - - if (!srvc->user) - srvc->user = xstrdup(cred.username); - if (!srvc->pass) - srvc->pass = xstrdup(cred.password); - } + server_fill_credential(srvc, &cred); if (srvc->auth_method) { struct imap_cmd_cb cb; @@@ -1397,7 -1403,7 +1408,7 @@@ static int append_msgs_to_imap(struct i } #ifdef USE_CURL_FOR_IMAP_SEND -static CURL *setup_curl(struct imap_server_conf *srvc) +static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred) { CURL *curl; struct strbuf path = STRBUF_INIT; @@@ -1410,7 -1416,6 +1421,7 @@@ if (!curl) die("curl_easy_init failed"); + server_fill_credential(&server, cred); curl_easy_setopt(curl, CURLOPT_USERNAME, server.user); curl_easy_setopt(curl, CURLOPT_PASSWORD, server.pass); @@@ -1460,9 -1465,8 +1471,9 @@@ static int curl_append_msgs_to_imap(str struct buffer msgbuf = { STRBUF_INIT, 0 }; CURL *curl; CURLcode res = CURLE_OK; + struct credential cred = CREDENTIAL_INIT; - curl = setup_curl(server); + curl = setup_curl(server, &cred); curl_easy_setopt(curl, CURLOPT_READDATA, &msgbuf); fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : ""); @@@ -1497,20 -1501,7 +1508,20 @@@ curl_easy_cleanup(curl); curl_global_cleanup(); - return 0; + if (cred.username) { + if (res == CURLE_OK) + credential_approve(&cred); +#if LIBCURL_VERSION_NUM >= 0x070d01 + else if (res == CURLE_LOGIN_DENIED) +#else + else +#endif + credential_reject(&cred); + } + + credential_clear(&cred); + + return res != CURLE_OK; } #endif