[balsa/gtk3] Implement the 'AUTH PLAIN' SASL mechanism for POP3



commit d032986537f1131366e667dd3c71f4fbfd3e745b
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon Oct 3 19:52:09 2016 -0400

    Implement the 'AUTH PLAIN' SASL mechanism for POP3

 ChangeLog            |    8 ++++++++
 libbalsa/imap/pop3.c |   44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c15f3a5..a66d582 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2016-10-03  Albrecht Dreß
 
+       Implement the 'AUTH PLAIN' SASL mechanism for POP3
+       according to RFC 5043 and RFC 4616
+
+       * libbalsa/imap/pop3.c (pop_get_capa), (pop_auth_sasl_plain):
+         implement the 'AUTH PLAIN' SASL mechanism for POP3.
+
+2016-10-03  Albrecht Dreß
+
        Deprecation cleanups
 
        * AUTHORS:
diff --git a/libbalsa/imap/pop3.c b/libbalsa/imap/pop3.c
index fb74863..c9ae80e 100644
--- a/libbalsa/imap/pop3.c
+++ b/libbalsa/imap/pop3.c
@@ -240,7 +240,10 @@ pop_get_capa(PopHandle *pop, GError **err)
       if(strstr(buf, " CRAM-MD5"))
         pop->capabilities[POP_CAP_AUTH_CRAM] = 1;
     } else if(strncmp(buf, "SASL", 4) == 0) {
-      /* FIXME: implement SASL support */
+       if (strstr(buf, " PLAIN") != NULL) {
+               pop->capabilities[POP_CAP_SASL_PLAIN] = 1;
+       }
+      /* FIXME: implement more SASL mechanisms */
     } else {
       unsigned i;
       for(i=0; i<ELEMENTS(capa_names); i++) {
@@ -389,12 +392,51 @@ pop_auth_user(PopHandle *pop, const char *greeting, GError **err)
   return pop_exec(pop, line, err) ? IMAP_SUCCESS : IMAP_AUTH_FAILURE;
 }
 
+static ImapResult
+pop_auth_sasl_plain(PopHandle *pop, const char *greeting, GError **err)
+{
+       char *user = NULL, *pass = NULL;
+       int ok = 0;
+       gchar *base64_buf;
+       gchar *plain_buf;
+       size_t user_len;
+       size_t passwd_len;
+       char line[POP_LINE_LEN];
+
+       if (pop_can_do(pop, POP_CAP_SASL_PLAIN) == 0) {
+               return IMAP_AUTH_UNAVAIL;
+       }
+
+       if (pop->user_cb != NULL) {
+               pop->user_cb(IME_GET_USER_PASS, pop->user_arg, "SASL PLAIN", &user, &pass, &ok);
+       }
+       if ((ok == 0) || (user == NULL) || (pass == NULL)) {
+               g_set_error(err, IMAP_ERROR, IMAP_POP_AUTH_ERROR, "SASL PLAIN Authentication cancelled");
+               return IMAP_AUTH_FAILURE;
+       }
+
+       user_len = strlen(user);
+       passwd_len = strlen(pass);
+       plain_buf = g_malloc0((2U * user_len) + passwd_len + 3U);
+       strcpy(plain_buf, user);
+       strcpy(&plain_buf[user_len + 1U], user);
+       g_free(user);
+       strcpy(&plain_buf[(2U * user_len) + 2U], pass);
+       g_free(pass);
+       base64_buf = g_base64_encode((const guchar *) plain_buf, (2U * user_len) + passwd_len + 2U);
+       g_free(plain_buf);
+       g_snprintf(line, sizeof(line), "AUTH PLAIN %s\r\n", base64_buf);
+       g_free(base64_buf);
+       return pop_exec(pop, line, err) ? IMAP_SUCCESS : IMAP_AUTH_FAILURE;
+}
+
 typedef ImapResult (*PopAuthenticator)(PopHandle*, const char*, GError **err);
 /* ordered from strongest to weakest */
 static const PopAuthenticator pop_authenticators_arr[] = {
   pop_auth_cram,
   pop_auth_apop,
   pop_auth_user,
+  pop_auth_sasl_plain,
   NULL
 };
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]