authreg.c.patch   [plain text]


--- /tmp/jabberd-2.1.24.1/c2s/authreg.c	2008-04-27 02:57:20.000000000 -0700
+++ ./jabberd2/c2s/authreg.c	2008-11-24 14:21:54.000000000 -0800
@@ -119,7 +119,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;
 
@@ -152,8 +152,8 @@ static void _authreg_auth_get(c2s_t c2s,
     if (sess->s->ssf>0) 
         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))) {
+    /* no point going on if we have no mechanisms (Apple: added CRAM-MD5 check) */
+    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;
     }
@@ -197,6 +197,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);
 
@@ -258,7 +271,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;
     }
@@ -269,6 +282,22 @@ 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;
+            }
+        }
+    }
+
+    
     /* digest auth */
     if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
     {