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