support_sasl.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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
45typedef 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
64void *lutil_sasl_defaults(
65 LDAP * ld,
66 char *mech,
67 char *realm,
68 char *authcid,
69 char *passwd,
70 char *authzid);
71
72LDAP_SASL_INTERACT_PROC lutil_sasl_interact;
73
74int lutil_sasl_interact(
75 LDAP * ld,
76 unsigned flags,
77 void *defaults,
78 void *in);
79
80void lutil_sasl_freedefs(
81 void *defaults);
82
83/*
84 * SASL definitions for openldap support
85 */
86
87typedef 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
97void *
98lutil_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 == nullptr)
111 return nullptr;
112
113 defaults->mech = mech ? xstrdup(mech) : nullptr;
114 defaults->realm = realm ? xstrdup(realm) : nullptr;
115 defaults->authcid = authcid ? xstrdup(authcid) : nullptr;
116 defaults->passwd = passwd ? xstrdup(passwd) : nullptr;
117 defaults->authzid = authzid ? xstrdup(authzid) : nullptr;
118
119 if (defaults->mech == nullptr) {
120 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
121 }
122 if (defaults->realm == nullptr) {
123 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
124 }
125 if (defaults->authcid == nullptr) {
126 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid);
127 }
128 if (defaults->authzid == nullptr) {
129 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid);
130 }
131 defaults->resps = nullptr;
132 defaults->nresps = 0;
133
134 return defaults;
135}
136
137static int
138interaction(
139 unsigned,
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 = nullptr;
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
178int
179lutil_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 == nullptr)
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
201void
202lutil_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
217int
218tool_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 = nullptr;
233 char *sasl_authc_id = nullptr;
234 char *sasl_authz_id = nullptr;
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 = {};
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 != nullptr) {
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, nullptr, nullptr,
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
281void dummy(void);
282void
283dummy(void)
284{
285 fprintf(stderr, "%s| %s: ERROR: Dummy function\n", LogTime(), PROGRAM);
286}
287
288#endif
289#endif
290
void error(char *format,...)
#define PROGRAM
Definition: support.h:166
const char * LogTime(void)
static LDAP * ld
Definition: ldap_backend.cc:57
static const char * binddn
#define xfree
#define xstrdup
#define xmalloc
static unsigned char challenge[NTLM_NONCE_LEN]
Comm::AcceptLimiter dummy
Definition: stub_libcomm.cc:16

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors