]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/external_acl/kerberos_ldap_group/support_sasl.cc
SourceFormat Enforcement
[thirdparty/squid.git] / helpers / external_acl / kerberos_ldap_group / support_sasl.cc
1 /*
2 * -----------------------------------------------------------------------------
3 *
4 * Author: Markus Moeller (markus_moeller at compuserve.com)
5 *
6 * Copyright (C) 2007 Markus Moeller. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * -----------------------------------------------------------------------------
23 */
24
25 #include "squid.h"
26 #include "util.h"
27
28 #ifdef HAVE_LDAP
29
30 #include "support.h"
31
32 #ifdef HAVE_SASL_H
33 #include <sasl.h>
34 #elif defined(HAVE_SASL_SASL_H)
35 #include <sasl/sasl.h>
36 #elif defined(HAVE_SASL_DARWIN)
37 typedef struct sasl_interact {
38 unsigned long id; /* same as client/user callback ID */
39 const char *challenge; /* presented to user (e.g. OTP challenge) */
40 const char *prompt; /* presented to user (e.g. "Username: ") */
41 const char *defresult; /* default result string */
42 const void *result; /* set to point to result */
43 unsigned len; /* set to length of result */
44 } sasl_interact_t;
45
46 #define SASL_CB_USER 0x4001 /* client user identity to login as */
47 #define SASL_CB_AUTHNAME 0x4002 /* client authentication name */
48 #define SASL_CB_PASS 0x4004 /* client passphrase-based secret */
49 #define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result */
50 #define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */
51 #define SASL_CB_GETREALM 0x4008 /* realm to attempt authentication in */
52 #define SASL_CB_LIST_END 0 /* end of list */
53 #endif
54
55 #if defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H) || defined(HAVE_SASL_DARWIN)
56 void *lutil_sasl_defaults(
57 LDAP * ld,
58 char *mech,
59 char *realm,
60 char *authcid,
61 char *passwd,
62 char *authzid);
63
64 LDAP_SASL_INTERACT_PROC lutil_sasl_interact;
65
66 int lutil_sasl_interact(
67 LDAP * ld,
68 unsigned flags,
69 void *defaults,
70 void *in);
71
72 void lutil_sasl_freedefs(
73 void *defaults);
74
75 /*
76 * SASL definitions for openldap support
77 */
78
79 typedef struct lutil_sasl_defaults_s {
80 char *mech;
81 char *realm;
82 char *authcid;
83 char *passwd;
84 char *authzid;
85 char **resps;
86 int nresps;
87 } lutilSASLdefaults;
88
89 void *
90 lutil_sasl_defaults(
91 LDAP * ld,
92 char *mech,
93 char *realm,
94 char *authcid,
95 char *passwd,
96 char *authzid)
97 {
98 lutilSASLdefaults *defaults;
99
100 defaults = (lutilSASLdefaults *) xmalloc(sizeof(lutilSASLdefaults));
101
102 if (defaults == NULL)
103 return NULL;
104
105 defaults->mech = mech ? xstrdup(mech) : NULL;
106 defaults->realm = realm ? xstrdup(realm) : NULL;
107 defaults->authcid = authcid ? xstrdup(authcid) : NULL;
108 defaults->passwd = passwd ? xstrdup(passwd) : NULL;
109 defaults->authzid = authzid ? xstrdup(authzid) : NULL;
110
111 if (defaults->mech == NULL) {
112 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
113 }
114 if (defaults->realm == NULL) {
115 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
116 }
117 if (defaults->authcid == NULL) {
118 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid);
119 }
120 if (defaults->authzid == NULL) {
121 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid);
122 }
123 defaults->resps = NULL;
124 defaults->nresps = 0;
125
126 return defaults;
127 }
128
129 static int
130 interaction(
131 unsigned flags,
132 sasl_interact_t * interact,
133 lutilSASLdefaults * defaults)
134 {
135 const char *dflt = interact->defresult;
136
137 flags = flags;
138 switch (interact->id) {
139 case SASL_CB_GETREALM:
140 if (defaults)
141 dflt = defaults->realm;
142 break;
143 case SASL_CB_AUTHNAME:
144 if (defaults)
145 dflt = defaults->authcid;
146 break;
147 case SASL_CB_PASS:
148 if (defaults)
149 dflt = defaults->passwd;
150 break;
151 case SASL_CB_USER:
152 if (defaults)
153 dflt = defaults->authzid;
154 break;
155 case SASL_CB_NOECHOPROMPT:
156 break;
157 case SASL_CB_ECHOPROMPT:
158 break;
159 }
160
161 if (dflt && !*dflt)
162 dflt = NULL;
163
164 /* input must be empty */
165 interact->result = (dflt && *dflt) ? dflt : "";
166 interact->len = (unsigned) strlen((const char *) interact->result);
167
168 return LDAP_SUCCESS;
169 }
170
171 int
172 lutil_sasl_interact(
173 LDAP * ld,
174 unsigned flags,
175 void *defaults,
176 void *in)
177 {
178 sasl_interact_t *interact = (sasl_interact_t *) in;
179
180 if (ld == NULL)
181 return LDAP_PARAM_ERROR;
182
183 while (interact->id != SASL_CB_LIST_END) {
184 int rc = interaction(flags, interact, (lutilSASLdefaults *) defaults);
185
186 if (rc)
187 return rc;
188 ++interact;
189 }
190
191 return LDAP_SUCCESS;
192 }
193
194 void
195 lutil_sasl_freedefs(
196 void *defaults)
197 {
198 lutilSASLdefaults *defs = (lutilSASLdefaults *) defaults;
199
200 if (defs->mech)
201 xfree(defs->mech);
202 if (defs->realm)
203 xfree(defs->realm);
204 if (defs->authcid)
205 xfree(defs->authcid);
206 if (defs->passwd)
207 xfree(defs->passwd);
208 if (defs->authzid)
209 xfree(defs->authzid);
210 if (defs->resps)
211 xfree(defs->resps);
212
213 xfree(defs);
214 }
215
216 int
217 tool_sasl_bind(LDAP * ld, char *binddn, char *ssl)
218 {
219 /*
220 * unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
221 * unsigned sasl_flags = LDAP_SASL_QUIET;
222 */
223 /*
224 * Avoid SASL messages
225 */
226 #ifdef HAVE_SUN_LDAP_SDK
227 unsigned sasl_flags = LDAP_SASL_INTERACTIVE;
228 #else
229 unsigned sasl_flags = LDAP_SASL_QUIET;
230 #endif
231 char *sasl_realm = NULL;
232 char *sasl_authc_id = NULL;
233 char *sasl_authz_id = NULL;
234 #ifdef HAVE_SUN_LDAP_SDK
235 char *sasl_mech = (char *) "GSSAPI";
236 #else
237 char *sasl_mech = NULL;
238 #endif
239 /*
240 * Force encryption
241 */
242 char *sasl_secprops;
243 /*
244 * char *sasl_secprops = (char *)"maxssf=56";
245 * char *sasl_secprops = NULL;
246 */
247 struct berval passwd = {0, NULL};
248 void *defaults;
249 int rc = LDAP_SUCCESS;
250
251 if (ssl)
252 sasl_secprops = (char *) "maxssf=0";
253 else
254 sasl_secprops = (char *) "maxssf=56";
255 /* sasl_secprops = (char *)"maxssf=0"; */
256 /* sasl_secprops = (char *)"maxssf=56"; */
257
258 if (sasl_secprops != NULL) {
259 rc = ldap_set_option(ld, LDAP_OPT_X_SASL_SECPROPS,
260 (void *) sasl_secprops);
261 if (rc != LDAP_SUCCESS) {
262 error((char *) "%s| %s: ERROR: Could not set LDAP_OPT_X_SASL_SECPROPS: %s: %s\n", LogTime(), PROGRAM, sasl_secprops, ldap_err2string(rc));
263 return rc;
264 }
265 }
266 defaults = lutil_sasl_defaults(ld,
267 sasl_mech,
268 sasl_realm,
269 sasl_authc_id,
270 passwd.bv_val,
271 sasl_authz_id);
272
273 rc = ldap_sasl_interactive_bind_s(ld, binddn,
274 sasl_mech, NULL, NULL,
275 sasl_flags, lutil_sasl_interact, defaults);
276
277 lutil_sasl_freedefs(defaults);
278 if (rc != LDAP_SUCCESS) {
279 error((char *) "%s| %s: ERROR: ldap_sasl_interactive_bind_s error: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
280 }
281 return rc;
282 }
283 #else
284 void dummy(void);
285 void
286 dummy(void)
287 {
288 fprintf(stderr, "%s| %s: ERROR: Dummy function\n", LogTime(), PROGRAM);
289 }
290
291 #endif
292 #endif