Imported upstream version 0.61.0
[hcoop/debian/courier-authlib.git] / authsasl.c
index 6fa53f8..42a932e 100644 (file)
@@ -1,12 +1,13 @@
-/* $Id: authsasl.c,v 1.3 2004/10/21 00:10:49 mrsam Exp $ */
+/* $Id: authsasl.c,v 1.5 2008/07/10 02:43:55 mrsam Exp $ */
 
 /*
-** Copyright 1998 - 2000 Double Precision, Inc.  See COPYING for
+** Copyright 1998 - 2008 Double Precision, Inc.  See COPYING for
 ** distribution information.
 */
 
 #include       "courier_auth_config.h"
 #include       "courierauthsasl.h"
+#include       "authsaslclient.h"
 #include       <stdlib.h>
 #include       <ctype.h>
 #include       <string.h>
 
 /* Use the SASL_LIST macro to build authsasl_list */
 
-#define        SASL(a,b,c) int b(const char *, const char *, \
-                       char *(*)(const char *, void *), \
-                       void *, \
-                       char **, \
-                       char **);
+#define NO_SERVER_FUNC()
+
+#define        SERVER_FUNC(b) int b(const char *, const char *,                \
+                                char *(*)(const char *, void *),       \
+                                void *,                                \
+                                char **,                               \
+                                char **);
+
+#define SASL(a,b,c) b
 SASL_LIST
 
 #undef SASL
 
+#undef  SERVER_FUNC
+#define SERVER_FUNC(n) n
+
+#undef  NO_SERVER_FUNC
+#define NO_SERVER_FUNC() 0
+
 #define        SASL(a,b,c) {a, b},
 
 struct authsasl_info authsasl_list[] = {
@@ -49,7 +60,8 @@ char  *p, *q;
 
        for (i=0; authsasl_list[i].sasl_method; i++)
        {
-               if (strcmp(p, authsasl_list[i].sasl_method) == 0)
+               if (strcmp(p, authsasl_list[i].sasl_method) == 0 &&
+                   authsasl_list[i].sasl_func)
                {
                        free(p);
                        return ( (*authsasl_list[i].sasl_func)
@@ -63,3 +75,65 @@ char *p, *q;
        errno=ENOENT;
        return (AUTHSASL_ERROR);
 }
+
+int auth_sasl_ex(const char *method,
+                const char *initresponse,
+                const char *externalauth,
+                char *(*callback_func)(const char *, void *),
+                void *callback_arg,
+                char **authtype_ptr,           /* Returned - AUTHTYPE */
+                char **authdata_ptr)
+{
+       char    *uid;
+       int n;
+
+       if (strcmp(method, "EXTERNAL"))
+               return auth_sasl(method, initresponse, callback_func,
+                                callback_arg,
+                                authtype_ptr,
+                                authdata_ptr);
+
+       if (initresponse && *initresponse)
+               return AUTHSASL_ERROR;
+
+       if (!externalauth || !*externalauth)
+               return AUTHSASL_ERROR;
+
+       if (!initresponse)
+       {
+               uid=callback_func("", callback_arg);
+
+               if (*uid == '*')
+               {
+                       free(uid);
+                       return (AUTHSASL_ABORTED);
+               }
+
+               n=authsasl_frombase64(uid);
+
+               if (n < 0)
+               {
+                       free(uid);
+                       return AUTHSASL_ABORTED;
+               }
+               uid[n]=0;
+
+               if (uid[0])
+               {
+                       free(uid);
+                       return AUTHSASL_ABORTED;
+               }
+               free(uid);
+       }
+
+       if ((*authtype_ptr=strdup("EXTERNAL")) == NULL)
+               return AUTHSASL_ABORTED;
+
+       if ((*authdata_ptr=strdup(externalauth)) == NULL)
+       {
+               free(authtype_ptr);
+               return AUTHSASL_ABORTED;
+       }
+
+       return 0;
+}