authreg_sqlite.c.patch   [plain text]


--- authreg_sqlite.c	2008-04-27 02:57:30.000000000 -0700
+++ new/authreg_sqlite.c	2009-04-02 14:15:18.000000000 -0700
@@ -32,6 +32,123 @@
 #include "c2s.h"
 #include <sqlite3.h>
 
+#ifdef APPLE_ENABLE_OD_AUTH
+#include <apple_authenticate.h>
+#include <apple_authorize.h>
+
+/* Apple overrides for Open Directory authentication */
+
+/* -----------------------------------------------------------------
+    int _ar_od_user_exists()
+   
+    RETURNS:
+        0 = user not found
+        1 = user exists
+   ----------------------------------------------------------------- */
+static int _ar_od_user_exists(authreg_t ar, char *username, char *realm)
+{
+    log_debug( ZONE, "_ar_od_user_exists()." );
+    if (NULL != username) log_debug( ZONE, "_ar_od_user_exists(): username = %s.", username);
+    if (NULL != realm) log_debug( ZONE, "_ar_od_user_exists(): realm = %s.", realm);
+
+    int iResult = od_auth_check_user_exists((const char *) username);
+    log_debug( ZONE, "_ar_od_user_exists(): od_auth_check_user_exists returned %d", iResult );
+    if (0 > iResult) /* error? */
+        iResult = 0; /* return "not found" */
+
+    return iResult;
+}
+
+/* -----------------------------------------------------------------
+    int _ar_od_check_password()
+
+    RETURNS:
+        0 = password is authenticated
+        1 = authentication failed
+   ----------------------------------------------------------------- */
+static int _ar_od_check_password(authreg_t ar, char *username, char *realm, char password[257])
+{
+    log_debug( ZONE, "_ar_od_check_password()." );
+    if (NULL != username) log_debug( ZONE, "_ar_od_check_password(): username = %s.", username);
+    if (NULL != realm) log_debug( ZONE, "_ar_od_check_password(): realm = %s.", realm);
+    if ((NULL != password) && (0 < strlen(password)))
+        log_debug( ZONE, "_ar_od_check_password(): password = %s.", password);
+
+    /* Verify the password */
+    int iResult = od_auth_check_plain_password(username, password);
+    log_debug( ZONE, "_ar_od_check_password(): od_auth_check_plain_password returned %d", iResult );
+    if (0 != iResult) /* error? */
+        iResult = 1; /* return "auth failed" */
+    else {
+        /* Now that we know the user is legit, verify service access */
+        int iErr = od_auth_check_service_membership(username, APPLE_CHAT_SACL_NAME);
+        log_debug( ZONE, "_ar_od_check_password(): od_auth_check_service_membership returned %d", iErr );
+        iResult = (1 == iErr) ? 0 : 1; /* return success/fail */
+    }
+
+    return iResult;
+}
+
+/* -----------------------------------------------------------------
+    int _ar_od_create_challenge()
+
+    RETURNS:
+       -1 = CRAM-MD5 unsupported for this user
+        0 = operation failed
+        1 = operation succeeded
+   ----------------------------------------------------------------- */
+static int _ar_od_create_challenge(authreg_t ar, char *username, char *challenge, int maxlen)
+{
+    log_debug( ZONE, "_ar_od_create_challenge()." );
+
+    /* check whether the user account supports CRAM-MD5 password authentication */
+    int iResult = od_auth_supports_cram_md5(username);
+    log_debug( ZONE, "_ar_od_create_challenge(): od_auth_supports_cram_md5 returned %d", iResult );
+    if (0 == iResult) /* auth method not available for this user */
+        iResult = -1; /* return "failed" */
+
+    /* create a unique challenge for this request */
+    iResult = od_auth_create_crammd5_challenge(challenge, maxlen);
+    log_debug( ZONE, "_ar_od_create_challenge(): od_auth_create_crammd5_challenge returned %d", iResult );
+    if (0 < iResult) /* ok? */
+        iResult = 1; /* return "success" */
+
+    return iResult;
+}
+
+/* -----------------------------------------------------------------
+    int _ar_od_check_response()
+
+    RETURNS:
+        0 = response is authenticated
+        1 = authentication failed
+   ----------------------------------------------------------------- */
+static int _ar_od_check_response(authreg_t ar, char *username, char *realm, char *challenge, char *response)
+{
+    log_debug( ZONE, "_ar_od_check_response()." );
+    if (NULL != username) log_debug( ZONE, "_ar_od_check_response(): username = %s.", username);
+    if (NULL != realm) log_debug( ZONE, "_ar_od_check_response(): realm = %s.", realm);
+    if ((NULL != challenge) && (0 < strlen(challenge)))
+        log_debug( ZONE, "_ar_od_check_response(): challenge = %s.", challenge);
+    if ((NULL != response) && (0 < strlen(response)))
+        log_debug( ZONE, "_ar_od_check_response(): response = %s.", response);
+
+    /* Verify the response */
+    int iResult = od_auth_check_crammd5_response(username, challenge, response);
+    log_debug( ZONE, "_ar_od_check_response(): od_auth_check_crammd5_response returned %d", iResult );
+    if (0 != iResult) /* error? */
+        iResult = 1; /* return "auth failed" */
+    else {
+        /* Now that we know the user is legit, verify service access */
+        int iErr = od_auth_check_service_membership(username, APPLE_CHAT_SACL_NAME);
+        log_debug( ZONE, "_ar_od_check_response(): od_auth_check_service_membership returned %d", iErr );
+        iResult = (1 == iErr) ? 0 : 1; /* return success/fail */
+    }
+
+    return iResult;
+}
+#else
+
 typedef struct moddata_st {
     sqlite3 *db;
     int txn;
@@ -277,11 +394,25 @@
     
     free(data);
 }
+#endif /* APPLE_ENABLE_OD_AUTH */
 
 DLLEXPORT int
 ar_init(authreg_t ar)
 {
 
+#ifdef APPLE_ENABLE_OD_AUTH
+    log_debug( ZONE, "APPLE: initializing OD auth functions." );
+    ar->user_exists = _ar_od_user_exists;
+    ar->check_password = _ar_od_check_password;
+    ar->create_challenge = _ar_od_create_challenge;
+    ar->check_response = _ar_od_check_response;
+    ar->free = NULL;
+    ar->create_user = NULL;
+    ar->delete_user = NULL;
+    ar->set_password = NULL;
+    return 0;
+#else
+
     int ret;
     sqlite3 *db;
     moddata_t data;
@@ -341,4 +472,5 @@
     log_debug(ZONE, "sqlite (authreg): finish init");
 
     return 0;
+#endif //APPLE_ENABLE_OD_AUTH
 }