]>
Commit | Line | Data |
---|---|---|
ca02e0ec | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 The Squid Software Foundation and contributors |
ca02e0ec AJ |
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 | ||
b1218840 AJ |
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 | ||
f7f3304a | 33 | #include "squid.h" |
b1218840 AJ |
34 | #include "util.h" |
35 | ||
1a22a39e | 36 | #if HAVE_LDAP |
b1218840 AJ |
37 | |
38 | #include "support.h" | |
39 | ||
1a22a39e | 40 | #if HAVE_SASL_H |
b1218840 | 41 | #include <sasl.h> |
1a22a39e | 42 | #elif HAVE_SASL_SASL_H |
b1218840 | 43 | #include <sasl/sasl.h> |
1a22a39e | 44 | #elif HAVE_SASL_DARWIN |
b1218840 | 45 | typedef struct sasl_interact { |
f53969cc SM |
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 */ | |
b1218840 AJ |
52 | } sasl_interact_t; |
53 | ||
f53969cc SM |
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 */ | |
b1218840 AJ |
61 | #endif |
62 | ||
1a22a39e | 63 | #if HAVE_SASL_H || HAVE_SASL_SASL_H || HAVE_SASL_DARWIN |
b1218840 AJ |
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 | ||
b1218840 AJ |
83 | /* |
84 | * SASL definitions for openldap support | |
85 | */ | |
86 | ||
b1218840 AJ |
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) | |
2e881a6f | 111 | return NULL; |
b1218840 AJ |
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) { | |
2e881a6f | 120 | ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech); |
b1218840 AJ |
121 | } |
122 | if (defaults->realm == NULL) { | |
2e881a6f | 123 | ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm); |
b1218840 AJ |
124 | } |
125 | if (defaults->authcid == NULL) { | |
2e881a6f | 126 | ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid); |
b1218840 AJ |
127 | } |
128 | if (defaults->authzid == NULL) { | |
2e881a6f | 129 | ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid); |
b1218840 AJ |
130 | } |
131 | defaults->resps = NULL; | |
132 | defaults->nresps = 0; | |
133 | ||
134 | return defaults; | |
135 | } | |
136 | ||
137 | static int | |
138 | interaction( | |
ced8def3 | 139 | unsigned, |
b1218840 AJ |
140 | sasl_interact_t * interact, |
141 | lutilSASLdefaults * defaults) | |
142 | { | |
143 | const char *dflt = interact->defresult; | |
144 | ||
b1218840 AJ |
145 | switch (interact->id) { |
146 | case SASL_CB_GETREALM: | |
2e881a6f A |
147 | if (defaults) |
148 | dflt = defaults->realm; | |
149 | break; | |
b1218840 | 150 | case SASL_CB_AUTHNAME: |
2e881a6f A |
151 | if (defaults) |
152 | dflt = defaults->authcid; | |
153 | break; | |
b1218840 | 154 | case SASL_CB_PASS: |
2e881a6f A |
155 | if (defaults) |
156 | dflt = defaults->passwd; | |
2e881a6f | 157 | break; |
b1218840 | 158 | case SASL_CB_USER: |
2e881a6f A |
159 | if (defaults) |
160 | dflt = defaults->authzid; | |
161 | break; | |
b1218840 | 162 | case SASL_CB_NOECHOPROMPT: |
2e881a6f | 163 | break; |
b1218840 | 164 | case SASL_CB_ECHOPROMPT: |
2e881a6f | 165 | break; |
b1218840 AJ |
166 | } |
167 | ||
168 | if (dflt && !*dflt) | |
2e881a6f | 169 | dflt = NULL; |
b1218840 AJ |
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) | |
2e881a6f | 188 | return LDAP_PARAM_ERROR; |
b1218840 AJ |
189 | |
190 | while (interact->id != SASL_CB_LIST_END) { | |
2e881a6f | 191 | int rc = interaction(flags, interact, (lutilSASLdefaults *) defaults); |
b1218840 | 192 | |
2e881a6f A |
193 | if (rc) |
194 | return rc; | |
755494da | 195 | ++interact; |
b1218840 AJ |
196 | } |
197 | ||
198 | return LDAP_SUCCESS; | |
199 | } | |
200 | ||
201 | void | |
202 | lutil_sasl_freedefs( | |
203 | void *defaults) | |
204 | { | |
205 | lutilSASLdefaults *defs = (lutilSASLdefaults *) defaults; | |
206 | ||
4ebcf1ce MM |
207 | xfree(defs->mech); |
208 | xfree(defs->realm); | |
209 | xfree(defs->authcid); | |
210 | xfree(defs->passwd); | |
211 | xfree(defs->authzid); | |
212 | xfree(defs->resps); | |
b1218840 AJ |
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 | */ | |
2e881a6f | 224 | /* |
b1218840 AJ |
225 | * Avoid SASL messages |
226 | */ | |
1a22a39e | 227 | #if HAVE_SUN_LDAP_SDK |
b1218840 AJ |
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; | |
b1218840 | 235 | char *sasl_mech = (char *) "GSSAPI"; |
2e881a6f | 236 | /* |
b1218840 AJ |
237 | * Force encryption |
238 | */ | |
239 | char *sasl_secprops; | |
240 | /* | |
241 | * char *sasl_secprops = (char *)"maxssf=56"; | |
242 | * char *sasl_secprops = NULL; | |
243 | */ | |
2e881a6f | 244 | struct berval passwd = {0, NULL}; |
b1218840 AJ |
245 | void *defaults; |
246 | int rc = LDAP_SUCCESS; | |
247 | ||
248 | if (ssl) | |
2e881a6f | 249 | sasl_secprops = (char *) "maxssf=0"; |
b1218840 | 250 | else |
2e881a6f A |
251 | sasl_secprops = (char *) "maxssf=56"; |
252 | /* sasl_secprops = (char *)"maxssf=0"; */ | |
253 | /* sasl_secprops = (char *)"maxssf=56"; */ | |
b1218840 AJ |
254 | |
255 | if (sasl_secprops != NULL) { | |
2e881a6f A |
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 | } | |
b1218840 AJ |
262 | } |
263 | defaults = lutil_sasl_defaults(ld, | |
2e881a6f A |
264 | sasl_mech, |
265 | sasl_realm, | |
266 | sasl_authc_id, | |
267 | passwd.bv_val, | |
268 | sasl_authz_id); | |
b1218840 AJ |
269 | |
270 | rc = ldap_sasl_interactive_bind_s(ld, binddn, | |
2e881a6f A |
271 | sasl_mech, NULL, NULL, |
272 | sasl_flags, lutil_sasl_interact, defaults); | |
b1218840 AJ |
273 | |
274 | lutil_sasl_freedefs(defaults); | |
275 | if (rc != LDAP_SUCCESS) { | |
2e881a6f | 276 | error((char *) "%s| %s: ERROR: ldap_sasl_interactive_bind_s error: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); |
b1218840 AJ |
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 | |
f53969cc | 290 |