1
2 /*
3 ** Copyright 1998 - 2013 Double Precision, Inc. See COPYING for
4 ** distribution information.
5 */
6
7 #include "courier_auth_config.h"
8 #include "courierauth.h"
9 #include "courierauthsasl.h"
10 #include "authsaslclient.h"
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <string.h>
14 #include <errno.h>
15
16 /* Use the SASL_LIST macro to build authsasl_list */
17
18 #define NO_SERVER_FUNC()
19
20 #define SERVER_FUNC(b) int b(const char *, const char *, \
21 char *(*)(const char *, void *), \
22 void *, \
23 char **, \
24 char **);
25
26 #define SASL(a,b,c) b
27 SASL_LIST
28
29 #undef SASL
30
31 #undef SERVER_FUNC
32 #define SERVER_FUNC(n) n
33
34 #undef NO_SERVER_FUNC
35 #define NO_SERVER_FUNC() 0
36
37 #define SASL(a,b,c) {a, b},
38
39 struct authsasl_info authsasl_list[] = {
40
41 SASL_LIST
42
43 { 0, 0}};
44
auth_sasl(const char * method,const char * initreply,char * (* callback_func)(const char *,void *),void * callback_arg,char ** authtype_ptr,char ** authdata_ptr)45 int auth_sasl(const char *method,
46 const char *initreply,
47 char *(*callback_func)(const char *, void *),
48 void *callback_arg,
49 char **authtype_ptr, /* Returned - AUTHTYPE */
50 char **authdata_ptr)
51 {
52 int i;
53 char *p, *q;
54
55 if ((p=malloc(strlen(method)+1)) == 0)
56 return (0);
57 strcpy(p, method);
58 for (q=p; *q; q++)
59 *q=toupper((int)(unsigned char)*q);
60
61 for (i=0; authsasl_list[i].sasl_method; i++)
62 {
63 if (strcmp(p, authsasl_list[i].sasl_method) == 0 &&
64 authsasl_list[i].sasl_func)
65 {
66 free(p);
67 return ( (*authsasl_list[i].sasl_func)
68 (method,
69 initreply, callback_func,
70 callback_arg,
71 authtype_ptr, authdata_ptr));
72 }
73 }
74 free(p);
75 errno=ENOENT;
76 return (AUTHSASL_ERROR);
77 }
78
auth_sasl_ex(const char * method,const char * initresponse,const char * externalauth,char * (* callback_func)(const char *,void *),void * callback_arg,char ** authtype_ptr,char ** authdata_ptr)79 int auth_sasl_ex(const char *method,
80 const char *initresponse,
81 const char *externalauth,
82 char *(*callback_func)(const char *, void *),
83 void *callback_arg,
84 char **authtype_ptr, /* Returned - AUTHTYPE */
85 char **authdata_ptr)
86 {
87 char *uid;
88 int n;
89
90 if (strcmp(method, "EXTERNAL"))
91 return auth_sasl(method, initresponse, callback_func,
92 callback_arg,
93 authtype_ptr,
94 authdata_ptr);
95
96 if (!externalauth || !*externalauth)
97 return AUTHSASL_ERROR;
98
99 if (initresponse && !*initresponse)
100 initresponse=NULL;
101
102 if (initresponse)
103 {
104 uid=strdup(initresponse);
105
106 if (!uid)
107 return AUTHSASL_ERROR;
108
109 n=authsasl_frombase64(uid);
110
111 if (n < 0)
112 {
113 free(uid);
114 return AUTHSASL_ABORTED;
115 }
116 uid[n]=0;
117
118 if (strcmp(uid, externalauth))
119 {
120 free(uid);
121 return AUTHSASL_ERROR;
122 }
123 free(uid);
124 }
125 else
126 {
127 uid=callback_func("", callback_arg);
128
129 if (*uid == '*')
130 {
131 free(uid);
132 return (AUTHSASL_ABORTED);
133 }
134
135 n=authsasl_frombase64(uid);
136
137 if (n < 0)
138 {
139 free(uid);
140 return AUTHSASL_ABORTED;
141 }
142 uid[n]=0;
143
144 if (uid[0])
145 {
146 free(uid);
147 return AUTHSASL_ABORTED;
148 }
149 free(uid);
150 }
151
152 if ((*authtype_ptr=strdup("EXTERNAL")) == NULL)
153 return AUTHSASL_ABORTED;
154
155 if ((*authdata_ptr=strdup(externalauth)) == NULL)
156 {
157 free(*authtype_ptr);
158 return AUTHSASL_ABORTED;
159 }
160
161 return 0;
162 }
163
auth_sasl_extract_userid(const char * authtype,const char * authdata)164 char *auth_sasl_extract_userid(const char *authtype,
165 const char *authdata)
166 {
167 struct cram_callback_info cci;
168 char *p;
169 char *t;
170 char *d;
171
172 if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
173 {
174 char *q;
175
176 p=strdup(authdata);
177
178 if (!p)
179 return NULL;
180
181 q=strchr(p, '\n');
182 if (q) *q=0;
183 return p;
184 }
185
186 if ((t=strdup(authtype)) == NULL)
187 return NULL;
188
189 if ((d=strdup(authdata)) == NULL)
190 {
191 free(t);
192 return NULL;
193 }
194
195 if (auth_get_cram_silent(t, d, &cci))
196 {
197 free(d);
198 free(t);
199 return (NULL);
200 }
201
202 p=strdup(cci.user);
203 free(d);
204 free(t);
205 return p;
206 }
207