authreg.c.patch   [plain text]


--- /tmp/jabberd-2.2.13/c2s/authreg.c	2011-02-23 08:24:34.000000000 -0800
+++ ./jabberd2/c2s/authreg.c	2011-03-01 10:13:14.000000000 -0800
@@ -27,6 +27,8 @@
   #include <dlfcn.h>
 #endif
 
+#include "auth_event.h"
+
 /* authreg module manager */
 
 typedef struct _authreg_error_st {
@@ -121,7 +123,7 @@ void authreg_free(authreg_t ar) {
 
 /** auth get handler */
 static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {
-    int ns, elem, attr;
+    int ns, elem, attr, err;
     char username[1024], id[128];
     int ar_mechs;
 
@@ -155,7 +157,7 @@ static void _authreg_auth_get(c2s_t c2s,
         ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
         
     /* no point going on if we have no mechanisms */
-    if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST))) {
+    if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_CRAMMD5))) {
         sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));
         return;
     }
@@ -199,6 +201,19 @@ static void _authreg_auth_get(c2s_t c2s,
     if(ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
         nad_append_elem(nad, ns, "digest", 2);
 
+    if (ar_mechs & AR_MECH_TRAD_CRAMMD5 && c2s->ar->create_challenge != NULL) {
+        err = (c2s->ar->create_challenge)(c2s->ar, (char *) username, (char *) sess->auth_challenge, sizeof(sess->auth_challenge));
+        if (0 == err) { /* operation failed */
+            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));
+            return;
+        }
+        else if (1 == err) { /* operation succeeded */
+            nad_append_elem(nad, ns, "crammd5", 2);
+            nad_append_attr(nad, -1, "challenge", sess->auth_challenge);
+        }
+        else ; /* auth method unsupported for user */
+    }
+
     /* give it back to the client */
     sx_nad_write(sess->s, nad);
 
@@ -260,7 +275,7 @@ static void _authreg_auth_set(c2s_t c2s,
         ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
     
     /* no point going on if we have no mechanisms */
-    if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST))) {
+    if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_CRAMMD5))) {
         sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));
         return;
     }
@@ -271,6 +286,24 @@ static void _authreg_auth_set(c2s_t c2s,
         return;
     }
     
+    /* Apple: handle CRAM-MD5 response */
+    if(!authd && ar_mechs & AR_MECH_TRAD_CRAMMD5 && c2s->ar->check_response != NULL)
+    {
+        elem = nad_find_elem(nad, 1, ns, "crammd5", 1);
+        if(elem >= 0)
+        {
+            snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
+            if((c2s->ar->check_response)(c2s->ar, username, sess->host->realm, sess->auth_challenge, str) == 0)
+            {
+                log_debug(ZONE, "crammd5 auth (check) succeded");
+                authd = 1;
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.cram-md5", eAuthSuccess);
+            } else {
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.cram-md5", eAuthFailure);
+            }
+        }
+    }
+
     /* digest auth */
     if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
     {
@@ -286,6 +319,9 @@ static void _authreg_auth_set(c2s_t c2s,
                 {
                     log_debug(ZONE, "digest auth succeeded");
                     authd = 1;
+                    auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.digest", eAuthSuccess);
+                } else {
+                    auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.digest", eAuthFailure);
                 }
             }
         }
@@ -301,6 +337,9 @@ static void _authreg_auth_set(c2s_t c2s,
             {
                 log_debug(ZONE, "plaintext auth (compare) succeeded");
                 authd = 1;
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.plain(compare)", eAuthSuccess);
+            } else {
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.plain(compare)", eAuthFailure);
             }
         }
     }
@@ -316,6 +355,9 @@ static void _authreg_auth_set(c2s_t c2s,
             {
                 log_debug(ZONE, "plaintext auth (check) succeded");
                 authd = 1;
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.plain", eAuthSuccess);
+            } else {
+                auth_event_log_simple(username, sess->s->ip, sess->s->port, "traditional.plain", eAuthFailure);
             }
         }
     }