Squid Web Cache v8/master
Loading...
Searching...
No Matches
support_sasl.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2026 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 along
27 * with this program; if not, see <https://www.gnu.org/licenses/>.
28 *
29 * -----------------------------------------------------------------------------
30 */
31
32#include "squid.h"
33#include "util.h"
34
35#if HAVE_LDAP
36
37#include "support.h"
38
39#if HAVE_SASL_H
40#include <sasl.h>
41#elif HAVE_SASL_SASL_H
42#include <sasl/sasl.h>
43#endif
44
45#if HAVE_SASL_H || HAVE_SASL_SASL_H
46void *lutil_sasl_defaults(
47 LDAP * ld,
48 char *mech,
49 char *realm,
50 char *authcid,
51 char *passwd,
52 char *authzid);
53
54LDAP_SASL_INTERACT_PROC lutil_sasl_interact;
55
56int lutil_sasl_interact(
57 LDAP * ld,
58 unsigned flags,
59 void *defaults,
60 void *in);
61
62void lutil_sasl_freedefs(
63 void *defaults);
64
65/*
66 * SASL definitions for openldap support
67 */
68
69typedef struct lutil_sasl_defaults_s {
70 char *mech;
71 char *realm;
72 char *authcid;
73 char *passwd;
74 char *authzid;
75 char **resps;
76 int nresps;
77} lutilSASLdefaults;
78
79void *
80lutil_sasl_defaults(
81 LDAP * ld,
82 char *mech,
83 char *realm,
84 char *authcid,
85 char *passwd,
86 char *authzid)
87{
88 lutilSASLdefaults *defaults;
89
90 defaults = (lutilSASLdefaults *) xmalloc(sizeof(lutilSASLdefaults));
91
92 if (defaults == nullptr)
93 return nullptr;
94
95 defaults->mech = mech ? xstrdup(mech) : nullptr;
96 defaults->realm = realm ? xstrdup(realm) : nullptr;
97 defaults->authcid = authcid ? xstrdup(authcid) : nullptr;
98 defaults->passwd = passwd ? xstrdup(passwd) : nullptr;
99 defaults->authzid = authzid ? xstrdup(authzid) : nullptr;
100
101 if (defaults->mech == nullptr) {
102 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
103 }
104 if (defaults->realm == nullptr) {
105 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
106 }
107 if (defaults->authcid == nullptr) {
108 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid);
109 }
110 if (defaults->authzid == nullptr) {
111 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid);
112 }
113 defaults->resps = nullptr;
114 defaults->nresps = 0;
115
116 return defaults;
117}
118
119static int
120interaction(
121 unsigned,
122 sasl_interact_t * interact,
123 lutilSASLdefaults * defaults)
124{
125 const char *dflt = interact->defresult;
126
127 switch (interact->id) {
128 case SASL_CB_GETREALM:
129 if (defaults)
130 dflt = defaults->realm;
131 break;
132 case SASL_CB_AUTHNAME:
133 if (defaults)
134 dflt = defaults->authcid;
135 break;
136 case SASL_CB_PASS:
137 if (defaults)
138 dflt = defaults->passwd;
139 break;
140 case SASL_CB_USER:
141 if (defaults)
142 dflt = defaults->authzid;
143 break;
144 case SASL_CB_NOECHOPROMPT:
145 break;
146 case SASL_CB_ECHOPROMPT:
147 break;
148 }
149
150 if (dflt && !*dflt)
151 dflt = nullptr;
152
153 /* input must be empty */
154 interact->result = (dflt && *dflt) ? dflt : "";
155 interact->len = (unsigned) strlen((const char *) interact->result);
156
157 return LDAP_SUCCESS;
158}
159
160int
161lutil_sasl_interact(
162 LDAP * ld,
163 unsigned flags,
164 void *defaults,
165 void *in)
166{
167 sasl_interact_t *interact = (sasl_interact_t *) in;
168
169 if (ld == nullptr)
170 return LDAP_PARAM_ERROR;
171
172 while (interact->id != SASL_CB_LIST_END) {
173 int rc = interaction(flags, interact, (lutilSASLdefaults *) defaults);
174
175 if (rc)
176 return rc;
177 ++interact;
178 }
179
180 return LDAP_SUCCESS;
181}
182
183void
184lutil_sasl_freedefs(
185 void *defaults)
186{
187 if (const auto defs = static_cast<lutilSASLdefaults*>(defaults)) {
188 xfree(defs->mech);
189 xfree(defs->realm);
190 xfree(defs->authcid);
191 xfree(defs->passwd);
192 xfree(defs->authzid);
193 xfree(defs->resps);
194
195 xfree(defs);
196 }
197}
198
199int
200tool_sasl_bind(LDAP * ld, char *binddn, char *ssl)
201{
202 /*
203 * unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
204 * unsigned sasl_flags = LDAP_SASL_QUIET;
205 */
206 /*
207 * Avoid SASL messages
208 */
209#if HAVE_SUN_LDAP_SDK
210 unsigned sasl_flags = LDAP_SASL_INTERACTIVE;
211#else
212 unsigned sasl_flags = LDAP_SASL_QUIET;
213#endif
214 char *sasl_realm = nullptr;
215 char *sasl_authc_id = nullptr;
216 char *sasl_authz_id = nullptr;
217 char *sasl_mech = (char *) "GSSAPI";
218 /*
219 * Force encryption
220 */
221 char *sasl_secprops;
222 /*
223 * char *sasl_secprops = (char *)"maxssf=56";
224 * char *sasl_secprops = nullptr;
225 */
226 struct berval passwd = {};
227 void *defaults;
228 int rc = LDAP_SUCCESS;
229
230 if (ssl)
231 sasl_secprops = (char *) "maxssf=0";
232 else
233 sasl_secprops = (char *) "maxssf=56";
234 /* sasl_secprops = (char *)"maxssf=0"; */
235 /* sasl_secprops = (char *)"maxssf=56"; */
236
237 if (sasl_secprops != nullptr) {
238 rc = ldap_set_option(ld, LDAP_OPT_X_SASL_SECPROPS,
239 (void *) sasl_secprops);
240 if (rc != LDAP_SUCCESS) {
241 error((char *) "%s| %s: ERROR: Could not set LDAP_OPT_X_SASL_SECPROPS: %s: %s\n", LogTime(), PROGRAM, sasl_secprops, ldap_err2string(rc));
242 return rc;
243 }
244 }
245 defaults = lutil_sasl_defaults(ld,
246 sasl_mech,
247 sasl_realm,
248 sasl_authc_id,
249 passwd.bv_val,
250 sasl_authz_id);
251
252 rc = ldap_sasl_interactive_bind_s(ld, binddn,
253 sasl_mech, nullptr, nullptr,
254 sasl_flags, lutil_sasl_interact, defaults);
255
256 lutil_sasl_freedefs(defaults);
257 if (rc != LDAP_SUCCESS) {
258 error((char *) "%s| %s: ERROR: ldap_sasl_interactive_bind_s error: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
259 }
260 return rc;
261}
262#else
263void dummy(void);
264void
265dummy(void)
266{
267 fprintf(stderr, "%s| %s: ERROR: Dummy function\n", LogTime(), PROGRAM);
268}
269
270#endif
271#endif
272
void error(char *format,...)
#define PROGRAM
Definition support.h:168
const char * LogTime(void)
static LDAP * ld
static const char * binddn
#define xfree
#define xstrdup
#define xmalloc
Comm::AcceptLimiter dummy