v2: - Added support for OAuth2.0 with curl. - Fixed the memory leak in case auth_cram_md5 fails. v3: - Improve wording in first patch - Change misleading message if OAuth2.0 is used without OpenSSL v4: - Add PLAIN authentication mechanism for OpenSSL - Improved wording in the first patch a bit more v5: - Add ability to specify destination folder using the command line - Add ability to set a default between curl and openssl using the config v6: - Fix minor mistakes in --folder documentation v7: - Fix spelling and grammar mistakes in logs shown to the user when running imap-send - Display port alongwith host when git credential is invoked and asks for a password - Display the destination mailbox when sending a message v8: - Drop the patch that enabled user to choose between libcurl and openssl using the config - Add ability to list the available folders by adding a `--list` option v9: - Encourage users to use OAuth2.0 for Gmail (similar change done for send-email docs). v10: - Fix comment styles - Fix failing tests v11: - Use lower case letters for the first word of a sendtence in an error message and avoid using full stops at the end of a sentence. v12: - Gracefully exit PLAIN, CRAM-MD5, OAUTHBEARER and XOAUTH2 authentication methods if OpenSSL support is not compiled in, but is requested by the user. - Use backticks for string literals. - Wrap documentation text to 75 columns. - End the last member of enum CAPABILITY with a trailing comma. v13: - Fix logic error which was using || instead of && when checking if the authentication method is neither XOAUTH2 nor OAUTHBEARER. v14: - Specify why we are not using CURLOPT_PASSWORD for OAuth2.0 methods using a comment. - Add a function try_auth_method() to reduce code duplication when trying to authenticate using a specific method. v15: - Simply rearrange the patches to make the cram md5 patches come before adding OAuth2.0 and PLAIN authentication methods. No change has been done to the code itself. v16: - Rearrage some more patches so that the two new features, i.e., --folder and --list come just after the new authentication methods. Then the two patches with minor improvements of displaying the destination mailbox and displaying port alongwith host have been added. The patch fixing other minor mistakes in the logs has been moved to the end. Just like v15, no change has been done to the code itself. v17: - Rebase on top of master where 30325e2 was causing a conflict. (Sorry for the bad range diff, but I think its easy to understand) v18: - Avoid initialising variables with 0 or NULL. Let them remain uninitialised - Add a white at it note to the commit message of the patch that adds support to specify the folder. - Add another minor fix to the log that displays the unknown auth mechanism used. It was displaying the host rather than the mechanism. - Remove unecessary and pessimistic lines from the patch that enabled showing the host alongwith the port. v19: - Use xstrfmt() for OAuth2 strings and strbuf for PLAIN. Aditya Garg (10): imap-send: fix bug causing cfg->folder being set to NULL imap-send: fix memory leak in case auth_cram_md5 fails imap-send: gracefully fail if CRAM-MD5 authentication is requested without OpenSSL imap-send: add support for OAuth2.0 authentication imap-send: add PLAIN authentication method to OpenSSL imap-send: enable specifying the folder using the command line imap-send: add ability to list the available folders imap-send: display port alongwith host when git credential is invoked imap-send: display the destination mailbox when sending a message imap-send: fix minor mistakes in the logs Documentation/config/imap.adoc | 11 +- Documentation/git-imap-send.adoc | 68 +++++- imap-send.c | 405 ++++++++++++++++++++++++++----- 3 files changed, 407 insertions(+), 77 deletions(-) Range-diff against v18: -: ---------- > 1: 4accbe6ecf imap-send: fix bug causing cfg->folder being set to NULL -: ---------- > 2: 1cfd66ccea imap-send: fix memory leak in case auth_cram_md5 fails -: ---------- > 3: 12ff5135be imap-send: gracefully fail if CRAM-MD5 authentication is requested without OpenSSL 1: 43b18dbfb0 ! 4: 6461607abc imap-send: add support for OAuth2.0 authentication @@ imap-send.c: static char *cram(const char *challenge_64, const char *user, const +static char *oauthbearer_base64(const char *user, const char *access_token) +{ -+ int raw_len, b64_len; ++ int b64_len; + char *raw, *b64; + + /* @@ imap-send.c: static char *cram(const char *challenge_64, const char *user, const + * https://datatracker.ietf.org/doc/html/rfc5801 + * https://datatracker.ietf.org/doc/html/rfc7628 + */ -+ raw_len = strlen(user) + strlen(access_token) + 20; -+ raw = xmallocz(raw_len + 1); -+ snprintf(raw, raw_len + 1, "n,a=%s,\001auth=Bearer %s\001\001", user, access_token); ++ raw = xstrfmt("n,a=%s,\001auth=Bearer %s\001\001", user, access_token); + + /* Base64 encode */ + b64 = xmallocz(ENCODED_SIZE(strlen(raw))); @@ imap-send.c: static char *cram(const char *challenge_64, const char *user, const + +static char *xoauth2_base64(const char *user, const char *access_token) +{ -+ int raw_len, b64_len; ++ int b64_len; + char *raw, *b64; + + /* @@ imap-send.c: static char *cram(const char *challenge_64, const char *user, const + * "user=" {User} "^Aauth=Bearer " {Access Token} "^A^A" + * https://developers.google.com/workspace/gmail/imap/xoauth2-protocol#initial_client_response + */ -+ raw_len = strlen(user) + strlen(access_token) + 20; -+ raw = xmallocz(raw_len + 1); -+ snprintf(raw, raw_len + 1, "user=%s\001auth=Bearer %s\001\001", user, access_token); ++ raw = xstrfmt("user=%s\001auth=Bearer %s\001\001", user, access_token); + + /* Base64 encode */ + b64 = xmallocz(ENCODED_SIZE(strlen(raw))); 2: 1ebf9f935f ! 5: 76745861e8 imap-send: add PLAIN authentication method to OpenSSL @@ imap-send.c: static char hexchar(unsigned int b) #define ENCODED_SIZE(n) (4 * DIV_ROUND_UP((n), 3)) +static char *plain_base64(const char *user, const char *pass) +{ -+ int user_len = strlen(user); -+ int pass_len = strlen(pass); -+ int raw_len = 1 + user_len + 1 + pass_len; ++ struct strbuf raw = STRBUF_INIT; + int b64_len; -+ char *raw, *b64; ++ char *b64; + + /* + * Compose the PLAIN string @@ imap-send.c: static char hexchar(unsigned int b) + * + * https://datatracker.ietf.org/doc/html/rfc4616 + */ -+ raw = xmallocz(raw_len); -+ raw[0] = '\0'; -+ memcpy(raw + 1, user, user_len); -+ raw[1 + user_len] = '\0'; -+ memcpy(raw + 2 + user_len, pass, pass_len); ++ strbuf_addch(&raw, '\0'); ++ strbuf_addstr(&raw, user); ++ strbuf_addch(&raw, '\0'); ++ strbuf_addstr(&raw, pass); + -+ b64 = xmallocz(ENCODED_SIZE(raw_len)); -+ b64_len = EVP_EncodeBlock((unsigned char *)b64, (unsigned char *)raw, raw_len); -+ free(raw); ++ b64 = xmallocz(ENCODED_SIZE(raw.len)); ++ b64_len = EVP_EncodeBlock((unsigned char *)b64, (unsigned char *)raw.buf, raw.len); ++ strbuf_release(&raw); + + if (b64_len < 0) { + free(b64); 3: ce2cfa34cf = 6: cb0857e36e imap-send: enable specifying the folder using the command line 4: 5c36e68493 = 7: 360aa72808 imap-send: add ability to list the available folders 5: cc4f88791f = 8: 422db5f0f0 imap-send: display port alongwith host when git credential is invoked 6: 82432c7b21 = 9: eaef39e6f1 imap-send: display the destination mailbox when sending a message 7: d780afc026 = 10: cc76007b2f imap-send: fix minor mistakes in the logs -- 2.49.0.824.gcc76007b2f