Print this page
3882 remove xmod & friends
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libsasl/lib/client.c
+++ new/usr/src/lib/libsasl/lib/client.c
1 1 /*
2 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 3 * Use is subject to license terms.
4 4 */
5 5 #pragma ident "%Z%%M% %I% %E% SMI"
6 6
7 7 /* SASL server API implementation
8 8 * Rob Siemborski
9 9 * Tim Martin
10 10 * $Id: client.c,v 1.61 2003/04/16 19:36:00 rjs3 Exp $
11 11 */
12 12 /*
13 13 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
14 14 *
15 15 * Redistribution and use in source and binary forms, with or without
16 16 * modification, are permitted provided that the following conditions
17 17 * are met:
18 18 *
19 19 * 1. Redistributions of source code must retain the above copyright
20 20 * notice, this list of conditions and the following disclaimer.
21 21 *
22 22 * 2. Redistributions in binary form must reproduce the above copyright
23 23 * notice, this list of conditions and the following disclaimer in
24 24 * the documentation and/or other materials provided with the
25 25 * distribution.
26 26 *
27 27 * 3. The name "Carnegie Mellon University" must not be used to
28 28 * endorse or promote products derived from this software without
29 29 * prior written permission. For permission or any other legal
30 30 * details, please contact
31 31 * Office of Technology Transfer
32 32 * Carnegie Mellon University
33 33 * 5000 Forbes Avenue
34 34 * Pittsburgh, PA 15213-3890
35 35 * (412) 268-4387, fax: (412) 268-7395
36 36 * tech-transfer@andrew.cmu.edu
37 37 *
38 38 * 4. Redistributions of any form whatsoever must retain the following
39 39 * acknowledgment:
40 40 * "This product includes software developed by Computing Services
41 41 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
42 42 *
43 43 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
44 44 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
45 45 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
46 46 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47 47 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
48 48 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
49 49 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
50 50 */
51 51
52 52 #include <config.h>
53 53 #include <stdio.h>
54 54 #include <stdlib.h>
55 55 #include <limits.h>
56 56 #include <ctype.h>
57 57 #include <string.h>
58 58 #ifdef HAVE_UNISTD_H
59 59 #include <unistd.h>
60 60 #endif
61 61
62 62 /* SASL Headers */
63 63 #include "sasl.h"
64 64 #include "saslplug.h"
65 65 #include "saslutil.h"
66 66 #include "saslint.h"
67 67
68 68 #ifdef _SUN_SDK_
69 69 DEFINE_STATIC_MUTEX(init_client_mutex);
70 70 DEFINE_STATIC_MUTEX(client_active_mutex);
71 71 /*
72 72 * client_plug_mutex ensures only one client plugin is init'ed at a time
73 73 * If a plugin is loaded more than once, the glob_context may be overwritten
74 74 * which may lead to a memory leak. We keep glob_context with each mech
75 75 * to avoid this problem.
76 76 */
77 77 DEFINE_STATIC_MUTEX(client_plug_mutex);
78 78 #else
79 79 static cmech_list_t *cmechlist; /* global var which holds the list */
80 80
81 81 static sasl_global_callbacks_t global_callbacks;
82 82
83 83 static int _sasl_client_active = 0;
84 84 #endif /* _SUN_SDK_ */
85 85
86 86 #ifdef _SUN_SDK_
87 87 static int init_mechlist(_sasl_global_context_t *gctx)
88 88 {
89 89 cmech_list_t *cmechlist = gctx->cmechlist;
90 90 #else
91 91 static int init_mechlist()
92 92 {
93 93 #endif /* _SUN_SDK_ */
94 94
95 95 cmechlist->mutex = sasl_MUTEX_ALLOC();
96 96 if(!cmechlist->mutex) return SASL_FAIL;
97 97
98 98 #ifdef _SUN_SDK_
99 99 cmechlist->utils=
100 100 _sasl_alloc_utils(gctx, NULL, &gctx->client_global_callbacks);
101 101 #else
102 102 cmechlist->utils=_sasl_alloc_utils(NULL, &global_callbacks);
103 103 #endif /* _SUN_SDK_ */
104 104 if (cmechlist->utils==NULL)
105 105 return SASL_NOMEM;
106 106
107 107 cmechlist->mech_list=NULL;
108 108 cmechlist->mech_length=0;
109 109
110 110 return SASL_OK;
111 111 }
112 112
113 113 #ifdef _SUN_SDK_
114 114 static int client_done(_sasl_global_context_t *gctx) {
115 115 cmech_list_t *cmechlist = gctx->cmechlist;
116 116 _sasl_path_info_t *path_info, *p;
117 117 #else
118 118 static int client_done(void) {
119 119 #endif /* _SUN_SDK_ */
120 120 cmechanism_t *cm;
121 121 cmechanism_t *cprevm;
122 122
123 123 #ifdef _SUN_SDK_
124 124 if(!gctx->sasl_client_active)
125 125 return SASL_NOTINIT;
126 126 if (LOCK_MUTEX(&client_active_mutex) < 0) {
127 127 return (SASL_FAIL);
128 128 }
129 129 gctx->sasl_client_active--;
130 130
131 131 if(gctx->sasl_client_active) {
132 132 /* Don't de-init yet! Our refcount is nonzero. */
133 133 UNLOCK_MUTEX(&client_active_mutex);
134 134 return SASL_CONTINUE;
135 135 }
136 136 #else
137 137 if(!_sasl_client_active)
138 138 return SASL_NOTINIT;
139 139 else
140 140 _sasl_client_active--;
141 141
142 142 if(_sasl_client_active) {
143 143 /* Don't de-init yet! Our refcount is nonzero. */
144 144 return SASL_CONTINUE;
145 145 }
146 146 #endif /* _SUN_SDK_ */
147 147
148 148 cm=cmechlist->mech_list; /* m point to begging of the list */
149 149 while (cm!=NULL)
150 150 {
151 151 cprevm=cm;
152 152 cm=cm->next;
153 153
154 154 if (cprevm->plug->mech_free) {
155 155 #ifdef _SUN_SDK_
156 156 cprevm->plug->mech_free(cprevm->glob_context, cmechlist->utils);
157 157 #else
158 158 cprevm->plug->mech_free(cprevm->plug->glob_context,
159 159 cmechlist->utils);
160 160 #endif /* _SUN_SDK_ */
161 161 }
162 162
163 163 sasl_FREE(cprevm->plugname);
164 164 sasl_FREE(cprevm);
165 165 }
166 166 sasl_MUTEX_FREE(cmechlist->mutex);
167 167 _sasl_free_utils(&cmechlist->utils);
168 168 sasl_FREE(cmechlist);
169 169
170 170 #ifdef _SUN_SDK_
171 171 gctx->cmechlist = NULL;
172 172 p = gctx->cplug_path_info;
173 173 while((path_info = p) != NULL) {
174 174 sasl_FREE(path_info->path);
175 175 p = path_info->next;
176 176 sasl_FREE(path_info);
177 177 }
178 178 gctx->cplug_path_info = NULL;
179 179 UNLOCK_MUTEX(&client_active_mutex);
180 180 #else
181 181 cmechlist = NULL;
182 182 #endif /* _SUN_SDK_ */
183 183
184 184 return SASL_OK;
185 185 }
186 186
187 187 int sasl_client_add_plugin(const char *plugname,
188 188 sasl_client_plug_init_t *entry_point)
189 189 {
190 190 #ifdef _SUN_SDK_
↓ open down ↓ |
190 lines elided |
↑ open up ↑ |
191 191 return (_sasl_client_add_plugin(_sasl_gbl_ctx(), plugname, entry_point));
192 192 }
193 193
194 194 int _sasl_client_add_plugin(void *ctx,
195 195 const char *plugname,
196 196 sasl_client_plug_init_t *entry_point)
197 197 {
198 198 cmech_list_t *cmechlist;
199 199 #ifdef _INTEGRATED_SOLARIS_
200 200 _sasl_global_context_t *gctx = ctx == NULL ? _sasl_gbl_ctx() : ctx;
201 - /* EXPORT DELETE START */
202 - /* CRYPT DELETE START */
203 201 int sun_reg;
204 - /* CRYPT DELETE END */
205 - /* EXPORT DELETE END */
206 202 #endif /* _INTEGRATED_SOLARIS_ */
207 203 int i;
208 204 cmechanism_t *m;
209 205 #endif /* _SUN_SDK_ */
210 206 int plugcount;
211 207 sasl_client_plug_t *pluglist;
212 208 cmechanism_t *mech;
213 209 int result;
214 210 int version;
215 211 int lupe;
216 212
217 213 if(!plugname || !entry_point) return SASL_BADPARAM;
218 214
219 215 #ifdef _SUN_SDK_
220 216 cmechlist = gctx->cmechlist;
221 217
222 218 if (cmechlist == NULL) return SASL_BADPARAM;
223 219
224 220 /* Check to see if this plugin has already been registered */
225 221 m = cmechlist->mech_list;
226 222 for (i = 0; i < cmechlist->mech_length; i++) {
227 223 if (strcmp(plugname, m->plugname) == 0) {
228 224 return SASL_OK;
229 225 }
230 226 m = m->next;
231 227 }
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
232 228
233 229 result = LOCK_MUTEX(&client_plug_mutex);
234 230 if (result != SASL_OK)
235 231 return result;
236 232
237 233 #endif /* _SUN_SDK_ */
238 234
239 235 result = entry_point(cmechlist->utils, SASL_CLIENT_PLUG_VERSION, &version,
240 236 &pluglist, &plugcount);
241 237
242 - /* EXPORT DELETE START */
243 - /* CRYPT DELETE START */
244 238 #ifdef _INTEGRATED_SOLARIS_
245 239 sun_reg = _is_sun_reg(pluglist);
246 240 #endif /* _INTEGRATED_SOLARIS_ */
247 - /* CRYPT DELETE END */
248 - /* EXPORT DELETE END */
249 241 if (result != SASL_OK)
250 242 {
251 243 #ifdef _SUN_SDK_
252 244 UNLOCK_MUTEX(&client_plug_mutex);
253 245 __sasl_log(gctx, gctx->client_global_callbacks.callbacks, SASL_LOG_WARN,
254 246 "entry_point failed in sasl_client_add_plugin for %s",
255 247 plugname);
256 248 #else
257 249 _sasl_log(NULL, SASL_LOG_WARN,
258 250 "entry_point failed in sasl_client_add_plugin for %s",
259 251 plugname);
260 252 #endif /* _SUN_SDK_ */
261 253 return result;
262 254 }
263 255
264 256 if (version != SASL_CLIENT_PLUG_VERSION)
265 257 {
266 258 #ifdef _SUN_SDK_
267 259 UNLOCK_MUTEX(&client_plug_mutex);
268 260 __sasl_log(gctx, gctx->client_global_callbacks.callbacks, SASL_LOG_WARN,
269 261 "version conflict in sasl_client_add_plugin for %s", plugname);
270 262 #else
271 263 _sasl_log(NULL, SASL_LOG_WARN,
272 264 "version conflict in sasl_client_add_plugin for %s", plugname);
273 265 #endif /* _SUN_SDK_ */
274 266 return SASL_BADVERS;
275 267 }
276 268
277 269 #ifdef _SUN_SDK_
278 270 /* Check plugins to make sure mech_name is non-NULL */
279 271 for (lupe=0;lupe < plugcount ;lupe++) {
280 272 if (pluglist[lupe].mech_name == NULL)
281 273 break;
282 274 }
283 275 if (lupe < plugcount) {
284 276 UNLOCK_MUTEX(&client_plug_mutex);
285 277 __sasl_log(gctx, gctx->client_global_callbacks.callbacks,
286 278 SASL_LOG_ERR, "invalid client plugin %s", plugname);
287 279 return SASL_BADPROT;
288 280 }
289 281 #endif /* _SUN_SDK_ */
290 282
291 283 for (lupe=0;lupe< plugcount ;lupe++)
292 284 {
293 285 mech = sasl_ALLOC(sizeof(cmechanism_t));
294 286 #ifdef _SUN_SDK_
295 287 if (! mech) {
296 288 UNLOCK_MUTEX(&client_plug_mutex);
297 289 return SASL_NOMEM;
298 290 }
299 291 mech->glob_context = pluglist->glob_context;
300 292 #else
301 293 if (! mech) return SASL_NOMEM;
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
302 294 #endif /* _SUN_SDK_ */
303 295
304 296 mech->plug=pluglist++;
305 297 if(_sasl_strdup(plugname, &mech->plugname, NULL) != SASL_OK) {
306 298 #ifdef _SUN_SDK_
307 299 UNLOCK_MUTEX(&client_plug_mutex);
308 300 #endif /* _SUN_SDK_ */
309 301 sasl_FREE(mech);
310 302 return SASL_NOMEM;
311 303 }
312 - /* EXPORT DELETE START */
313 - /* CRYPT DELETE START */
314 304 #ifdef _INTEGRATED_SOLARIS_
315 305 mech->sun_reg = sun_reg;
316 306 #endif /* _INTEGRATED_SOLARIS_ */
317 - /* CRYPT DELETE END */
318 - /* EXPORT DELETE END */
319 307 mech->version = version;
320 308 mech->next = cmechlist->mech_list;
321 309 cmechlist->mech_list = mech;
322 310 cmechlist->mech_length++;
323 311 }
324 312 #ifdef _SUN_SDK_
325 313 UNLOCK_MUTEX(&client_plug_mutex);
326 314 #endif /* _SUN_SDK_ */
327 315
328 316 return SASL_OK;
329 317 }
330 318
331 319 static int
332 320 client_idle(sasl_conn_t *conn)
333 321 {
334 322 cmechanism_t *m;
335 323 #ifdef _SUN_SDK_
336 324 _sasl_global_context_t *gctx = conn == NULL ? _sasl_gbl_ctx() : conn->gctx;
337 325 cmech_list_t *cmechlist = gctx->cmechlist;
338 326 #endif /* _SUN_SDK_ */
339 327
340 328 if (! cmechlist)
341 329 return 0;
342 330
343 331 for (m = cmechlist->mech_list;
344 332 m;
345 333 m = m->next)
346 334 if (m->plug->idle
347 335 #ifdef _SUN_SDK_
348 336 && m->plug->idle(m->glob_context,
349 337 #else
350 338 && m->plug->idle(m->plug->glob_context,
351 339 #endif /* _SUN_SDK_ */
352 340 conn,
353 341 conn ? ((sasl_client_conn_t *)conn)->cparams : NULL))
354 342 return 1;
355 343 return 0;
356 344 }
357 345
358 346 #ifdef _SUN_SDK_
359 347 static int _load_client_plugins(_sasl_global_context_t *gctx)
360 348 {
361 349 int ret;
362 350 const add_plugin_list_t _ep_list[] = {
363 351 { "sasl_client_plug_init", (add_plugin_t *)_sasl_client_add_plugin },
364 352 { "sasl_canonuser_init", (add_plugin_t *)_sasl_canonuser_add_plugin },
365 353 { NULL, NULL }
366 354 };
367 355 const sasl_callback_t *callbacks = gctx->client_global_callbacks.callbacks;
368 356
369 357 ret = _sasl_load_plugins(gctx, 0, _ep_list,
370 358 _sasl_find_getpath_callback(callbacks),
371 359 _sasl_find_verifyfile_callback(callbacks));
372 360 return (ret);
373 361 }
374 362 #endif /* _SUN_SDK_ */
375 363
376 364 /* initialize the SASL client drivers
377 365 * callbacks -- base callbacks for all client connections
378 366 * returns:
379 367 * SASL_OK -- Success
380 368 * SASL_NOMEM -- Not enough memory
381 369 * SASL_BADVERS -- Mechanism version mismatch
382 370 * SASL_BADPARAM -- error in config file
383 371 * SASL_NOMECH -- No mechanisms available
384 372 * ...
385 373 */
386 374
387 375 int sasl_client_init(const sasl_callback_t *callbacks)
388 376 {
389 377 #ifdef _SUN_SDK_
390 378 return _sasl_client_init(NULL, callbacks);
391 379 }
392 380
393 381 int _sasl_client_init(void *ctx,
394 382 const sasl_callback_t *callbacks)
395 383 {
396 384 int ret;
397 385 _sasl_global_context_t *gctx = ctx == NULL ? _sasl_gbl_ctx() : ctx;
398 386
399 387 if (gctx == NULL)
400 388 gctx = _sasl_gbl_ctx();
401 389
402 390 ret = LOCK_MUTEX(&init_client_mutex);
403 391 if (ret < 0) {
404 392 return (SASL_FAIL);
405 393 }
406 394 ret = LOCK_MUTEX(&client_active_mutex);
407 395 if (ret < 0) {
408 396 UNLOCK_MUTEX(&init_client_mutex);
409 397 return (SASL_FAIL);
410 398 }
411 399 if(gctx->sasl_client_active) {
412 400 /* We're already active, just increase our refcount */
413 401 /* xxx do something with the callback structure? */
414 402 gctx->sasl_client_active++;
415 403 UNLOCK_MUTEX(&client_active_mutex);
416 404 UNLOCK_MUTEX(&init_client_mutex);
417 405 return SASL_OK;
418 406 }
419 407
420 408 gctx->client_global_callbacks.callbacks = callbacks;
421 409 gctx->client_global_callbacks.appname = NULL;
422 410
423 411 gctx->cmechlist=sasl_ALLOC(sizeof(cmech_list_t));
424 412 if (gctx->cmechlist==NULL) {
425 413 UNLOCK_MUTEX(&init_client_mutex);
426 414 UNLOCK_MUTEX(&client_active_mutex);
427 415 return SASL_NOMEM;
428 416 }
429 417
430 418 gctx->sasl_client_active = 1;
431 419 UNLOCK_MUTEX(&client_active_mutex);
432 420
433 421 /* load plugins */
434 422 ret=init_mechlist(gctx);
435 423
436 424 if (ret!=SASL_OK) {
437 425 client_done(gctx);
438 426 UNLOCK_MUTEX(&init_client_mutex);
439 427 return ret;
440 428 }
441 429 _sasl_client_add_plugin(gctx, "EXTERNAL", &external_client_plug_init);
442 430
443 431 ret = _sasl_common_init(gctx, &gctx->client_global_callbacks, 0);
444 432 #else
445 433 int sasl_client_init(const sasl_callback_t *callbacks)
446 434 {
447 435 int ret;
448 436 const add_plugin_list_t ep_list[] = {
449 437 { "sasl_client_plug_init", (add_plugin_t *)sasl_client_add_plugin },
450 438 { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin },
451 439 { NULL, NULL }
452 440 };
453 441
454 442 if(_sasl_client_active) {
455 443 /* We're already active, just increase our refcount */
456 444 /* xxx do something with the callback structure? */
457 445 _sasl_client_active++;
458 446 return SASL_OK;
459 447 }
460 448
461 449 global_callbacks.callbacks = callbacks;
462 450 global_callbacks.appname = NULL;
463 451
464 452 cmechlist=sasl_ALLOC(sizeof(cmech_list_t));
465 453 if (cmechlist==NULL) return SASL_NOMEM;
466 454
467 455 /* We need to call client_done if we fail now */
468 456 _sasl_client_active = 1;
469 457
470 458 /* load plugins */
471 459 ret=init_mechlist();
472 460 if (ret!=SASL_OK) {
473 461 client_done();
474 462 return ret;
475 463 }
476 464
477 465 sasl_client_add_plugin("EXTERNAL", &external_client_plug_init);
478 466
479 467 ret = _sasl_common_init(&global_callbacks);
480 468 #endif /* _SUN_SDK_ */
481 469
482 470 if (ret == SASL_OK)
483 471 #ifdef _SUN_SDK_
484 472 ret = _load_client_plugins(gctx);
485 473 #else
486 474 ret = _sasl_load_plugins(ep_list,
487 475 _sasl_find_getpath_callback(callbacks),
488 476 _sasl_find_verifyfile_callback(callbacks));
489 477 #endif /* _SUN_SDK_ */
490 478
491 479 #ifdef _SUN_SDK_
492 480 if (ret == SASL_OK)
493 481 /* If sasl_client_init returns error, sasl_done() need not be called */
494 482 ret = _sasl_build_mechlist(gctx);
495 483 if (ret == SASL_OK) {
496 484 gctx->sasl_client_cleanup_hook = &client_done;
497 485 gctx->sasl_client_idle_hook = &client_idle;
498 486 } else {
499 487 client_done(gctx);
500 488 }
501 489 UNLOCK_MUTEX(&init_client_mutex);
502 490 #else
503 491 if (ret == SASL_OK) {
504 492 _sasl_client_cleanup_hook = &client_done;
505 493 _sasl_client_idle_hook = &client_idle;
506 494
507 495 ret = _sasl_build_mechlist();
508 496 } else {
509 497 client_done();
510 498 }
511 499 #endif /* _SUN_SDK_ */
512 500
513 501 return ret;
514 502 }
515 503
516 504 static void client_dispose(sasl_conn_t *pconn)
517 505 {
518 506 sasl_client_conn_t *c_conn=(sasl_client_conn_t *) pconn;
519 507 #ifdef _SUN_SDK_
520 508 sasl_free_t *free_func = c_conn->cparams->utils->free;
521 509 #endif /* _SUN_SDK_ */
522 510
523 511 if (c_conn->mech && c_conn->mech->plug->mech_dispose) {
524 512 c_conn->mech->plug->mech_dispose(pconn->context,
525 513 c_conn->cparams->utils);
526 514 }
527 515
528 516 pconn->context = NULL;
529 517
530 518 if (c_conn->clientFQDN)
531 519 #ifdef _SUN_SDK_
532 520 free_func(c_conn->clientFQDN);
533 521 #else
534 522 sasl_FREE(c_conn->clientFQDN);
535 523 #endif /* _SUN_SDK_ */
536 524
537 525 if (c_conn->cparams) {
538 526 _sasl_free_utils(&(c_conn->cparams->utils));
539 527 #ifdef _SUN_SDK_
540 528 free_func(c_conn->cparams);
541 529 #else
542 530 sasl_FREE(c_conn->cparams);
543 531 #endif /* _SUN_SDK_ */
544 532 }
545 533
546 534 _sasl_conn_dispose(pconn);
547 535 }
548 536
549 537 /* initialize a client exchange based on the specified mechanism
550 538 * service -- registered name of the service using SASL (e.g. "imap")
551 539 * serverFQDN -- the fully qualified domain name of the server
552 540 * iplocalport -- client IPv4/IPv6 domain literal string with port
553 541 * (if NULL, then mechanisms requiring IPaddr are disabled)
554 542 * ipremoteport -- server IPv4/IPv6 domain literal string with port
555 543 * (if NULL, then mechanisms requiring IPaddr are disabled)
556 544 * prompt_supp -- list of client interactions supported
557 545 * may also include sasl_getopt_t context & call
558 546 * NULL prompt_supp = user/pass via SASL_INTERACT only
559 547 * NULL proc = interaction supported via SASL_INTERACT
560 548 * secflags -- security flags (see above)
561 549 * in/out:
562 550 * pconn -- connection negotiation structure
563 551 * pointer to NULL => allocate new
564 552 * non-NULL => recycle storage and go for next available mech
565 553 *
566 554 * Returns:
567 555 * SASL_OK -- success
568 556 * SASL_NOMECH -- no mechanism meets requested properties
569 557 * SASL_NOMEM -- not enough memory
570 558 */
571 559 int sasl_client_new(const char *service,
572 560 const char *serverFQDN,
573 561 const char *iplocalport,
574 562 const char *ipremoteport,
575 563 const sasl_callback_t *prompt_supp,
576 564 unsigned flags,
577 565 sasl_conn_t **pconn)
578 566 {
579 567 #ifdef _SUN_SDK_
580 568 return _sasl_client_new(NULL, service, serverFQDN, iplocalport,
581 569 ipremoteport, prompt_supp, flags, pconn);
582 570 }
583 571 int _sasl_client_new(void *ctx,
584 572 const char *service,
585 573 const char *serverFQDN,
586 574 const char *iplocalport,
587 575 const char *ipremoteport,
588 576 const sasl_callback_t *prompt_supp,
589 577 unsigned flags,
590 578 sasl_conn_t **pconn)
591 579 {
592 580 _sasl_global_context_t *gctx = ctx == NULL ? _sasl_gbl_ctx() : ctx;
593 581 #endif /* _SUN_SDK_ */
594 582 int result;
595 583 char name[MAXHOSTNAMELEN];
596 584 sasl_client_conn_t *conn;
597 585 sasl_utils_t *utils;
598 586
599 587 #ifdef _SUN_SDK_
600 588 if (gctx == NULL)
601 589 gctx = _sasl_gbl_ctx();
602 590
603 591 if(gctx->sasl_client_active==0) return SASL_NOTINIT;
604 592 #else
605 593 if(_sasl_client_active==0) return SASL_NOTINIT;
606 594 #endif /* _SUN_SDK_ */
607 595
608 596 /* Remember, iplocalport and ipremoteport can be NULL and be valid! */
609 597 if (!pconn || !service || !serverFQDN)
610 598 return SASL_BADPARAM;
611 599
612 600 *pconn=sasl_ALLOC(sizeof(sasl_client_conn_t));
613 601 if (*pconn==NULL) {
614 602 #ifdef _SUN_SDK_
615 603 __sasl_log(gctx, gctx->client_global_callbacks.callbacks, SASL_LOG_ERR,
616 604 "Out of memory allocating connection context");
617 605 #else
618 606 _sasl_log(NULL, SASL_LOG_ERR,
619 607 "Out of memory allocating connection context");
620 608 #endif /* _SUN_SDK_ */
621 609 return SASL_NOMEM;
622 610 }
623 611 memset(*pconn, 0, sizeof(sasl_client_conn_t));
624 612
625 613 #ifdef _SUN_SDK_
626 614 (*pconn)->gctx = gctx;
627 615 #endif /* _SUN_SDK_ */
628 616
629 617 (*pconn)->destroy_conn = &client_dispose;
630 618
631 619 conn = (sasl_client_conn_t *)*pconn;
632 620
633 621 conn->mech = NULL;
634 622
635 623 conn->cparams=sasl_ALLOC(sizeof(sasl_client_params_t));
636 624 if (conn->cparams==NULL)
637 625 MEMERROR(*pconn);
638 626 memset(conn->cparams,0,sizeof(sasl_client_params_t));
639 627
640 628 result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_CLIENT,
641 629 &client_idle, serverFQDN,
642 630 iplocalport, ipremoteport,
643 631 #ifdef _SUN_SDK_
644 632 prompt_supp, &gctx->client_global_callbacks);
645 633 #else
646 634 prompt_supp, &global_callbacks);
647 635 #endif /* _SUN_SDK_ */
648 636
649 637 if (result != SASL_OK) RETURN(*pconn, result);
650 638
651 639 #ifdef _SUN_SDK_
652 640 utils=_sasl_alloc_utils(gctx, *pconn, &gctx->client_global_callbacks);
653 641 #else
654 642 utils=_sasl_alloc_utils(*pconn, &global_callbacks);
655 643 #endif /* _SUN_SDK_ */
656 644 if (utils==NULL)
657 645 MEMERROR(*pconn);
658 646
659 647 utils->conn= *pconn;
660 648
661 649 /* Setup the non-lazy parts of cparams, the rest is done in
662 650 * sasl_client_start */
663 651 conn->cparams->utils = utils;
664 652 conn->cparams->canon_user = &_sasl_canon_user;
665 653 conn->cparams->flags = flags;
666 654 conn->cparams->prompt_supp = (*pconn)->callbacks;
667 655
668 656 /* get the clientFQDN (serverFQDN was set in _sasl_conn_init) */
669 657 memset(name, 0, sizeof(name));
670 658 gethostname(name, MAXHOSTNAMELEN);
671 659
672 660 result = _sasl_strdup(name, &conn->clientFQDN, NULL);
673 661
674 662 if(result == SASL_OK) return SASL_OK;
675 663
676 664 #ifdef _SUN_SDK_
677 665 conn->cparams->iplocalport = (*pconn)->iplocalport;
678 666 conn->cparams->iploclen = strlen((*pconn)->iplocalport);
679 667 conn->cparams->ipremoteport = (*pconn)->ipremoteport;
680 668 conn->cparams->ipremlen = strlen((*pconn)->ipremoteport);
681 669 #endif /* _SUN_SDK_ */
682 670
683 671 /* result isn't SASL_OK */
684 672 _sasl_conn_dispose(*pconn);
685 673 sasl_FREE(*pconn);
686 674 *pconn = NULL;
687 675 #ifdef _SUN_SDK_
688 676 __sasl_log(gctx, gctx->client_global_callbacks.callbacks, SASL_LOG_ERR,
689 677 "Out of memory in sasl_client_new");
690 678 #else
691 679 _sasl_log(NULL, SASL_LOG_ERR, "Out of memory in sasl_client_new");
692 680 #endif /* _SUN_SDK_ */
693 681 return result;
694 682 }
695 683
696 684 static int have_prompts(sasl_conn_t *conn,
697 685 const sasl_client_plug_t *mech)
698 686 {
699 687 static const unsigned long default_prompts[] = {
700 688 SASL_CB_AUTHNAME,
701 689 SASL_CB_PASS,
702 690 SASL_CB_LIST_END
703 691 };
704 692
705 693 const unsigned long *prompt;
706 694 int (*pproc)();
707 695 void *pcontext;
708 696 int result;
709 697
710 698 for (prompt = (mech->required_prompts
711 699 ? mech->required_prompts :
712 700 default_prompts);
713 701 *prompt != SASL_CB_LIST_END;
714 702 prompt++) {
715 703 result = _sasl_getcallback(conn, *prompt, &pproc, &pcontext);
716 704 if (result != SASL_OK && result != SASL_INTERACT)
717 705 return 0; /* we don't have this required prompt */
718 706 }
719 707
720 708 return 1; /* we have all the prompts */
721 709 }
722 710
723 711 /* select a mechanism for a connection
724 712 * mechlist -- mechanisms server has available (punctuation ignored)
725 713 * secret -- optional secret from previous session
726 714 * output:
727 715 * prompt_need -- on SASL_INTERACT, list of prompts needed to continue
728 716 * clientout -- the initial client response to send to the server
729 717 * mech -- set to mechanism name
730 718 *
731 719 * Returns:
732 720 * SASL_OK -- success
733 721 * SASL_NOMEM -- not enough memory
734 722 * SASL_NOMECH -- no mechanism meets requested properties
735 723 * SASL_INTERACT -- user interaction needed to fill in prompt_need list
736 724 */
737 725
738 726 /* xxx confirm this with rfc 2222
739 727 * SASL mechanism allowable characters are "AZaz-_"
740 728 * seperators can be any other characters and of any length
741 729 * even variable lengths between
742 730 *
743 731 * Apps should be encouraged to simply use space or comma space
744 732 * though
745 733 */
746 734 int sasl_client_start(sasl_conn_t *conn,
747 735 const char *mechlist,
748 736 sasl_interact_t **prompt_need,
749 737 const char **clientout,
750 738 unsigned *clientoutlen,
751 739 const char **mech)
752 740 {
753 741 sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn;
754 742 char name[SASL_MECHNAMEMAX + 1];
755 743 cmechanism_t *m=NULL,*bestm=NULL;
756 744 size_t pos=0,place;
757 745 size_t list_len;
758 746 sasl_ssf_t bestssf = 0, minssf = 0;
759 747 int result;
760 748 #ifdef _SUN_SDK_
761 749 _sasl_global_context_t *gctx = (conn == NULL) ?
762 750 _sasl_gbl_ctx() : conn->gctx;
763 751 cmech_list_t *cmechlist;
764 752
765 753 if(gctx->sasl_client_active==0) return SASL_NOTINIT;
766 754 cmechlist = gctx->cmechlist;
767 755 #else
768 756 if(_sasl_client_active==0) return SASL_NOTINIT;
769 757 #endif /* _SUN_SDK_ */
770 758
771 759 if (!conn) return SASL_BADPARAM;
772 760
773 761 /* verify parameters */
774 762 if (mechlist == NULL)
775 763 PARAMERROR(conn);
776 764
777 765 /* if prompt_need != NULL we've already been here
778 766 and just need to do the continue step again */
779 767
780 768 /* do a step */
781 769 /* FIXME: Hopefully they only give us our own prompt_need back */
782 770 if (prompt_need && *prompt_need != NULL) {
783 771 goto dostep;
784 772 }
785 773
786 774 #ifdef _SUN_SDK_
787 775 if (c_conn->mech != NULL) {
788 776 if (c_conn->mech->plug->mech_dispose != NULL) {
789 777 c_conn->mech->plug->mech_dispose(conn->context,
790 778 c_conn->cparams->utils);
791 779 c_conn->mech = NULL;
792 780 }
793 781 }
794 782 memset(&conn->oparams, 0, sizeof(sasl_out_params_t));
795 783
796 784 (void) _load_client_plugins(gctx);
797 785 #endif /* _SUN_SDK_ */
798 786
799 787 if(conn->props.min_ssf < conn->external.ssf) {
800 788 minssf = 0;
801 789 } else {
802 790 minssf = conn->props.min_ssf - conn->external.ssf;
803 791 }
804 792
805 793 /* parse mechlist */
806 794 list_len = strlen(mechlist);
807 795
808 796 while (pos<list_len)
809 797 {
810 798 place=0;
811 799 while ((pos<list_len) && (isalnum((unsigned char)mechlist[pos])
812 800 || mechlist[pos] == '_'
813 801 || mechlist[pos] == '-')) {
814 802 name[place]=mechlist[pos];
815 803 pos++;
816 804 place++;
817 805 if (SASL_MECHNAMEMAX < place) {
818 806 place--;
819 807 while(pos<list_len && (isalnum((unsigned char)mechlist[pos])
820 808 || mechlist[pos] == '_'
821 809 || mechlist[pos] == '-'))
822 810 pos++;
823 811 }
824 812 }
825 813 pos++;
826 814 name[place]=0;
827 815
828 816 if (! place) continue;
829 817
830 818 /* foreach in server list */
831 819 for (m = cmechlist->mech_list; m != NULL; m = m->next) {
832 820 int myflags;
833 821
834 822 /* Is this the mechanism the server is suggesting? */
835 823 if (strcasecmp(m->plug->mech_name, name))
↓ open down ↓ |
507 lines elided |
↑ open up ↑ |
836 824 continue; /* no */
837 825
838 826 /* Do we have the prompts for it? */
839 827 if (!have_prompts(conn, m->plug))
840 828 break;
841 829
842 830 /* Is it strong enough? */
843 831 if (minssf > m->plug->max_ssf)
844 832 break;
845 833
846 - /* EXPORT DELETE START */
847 - /* CRYPT DELETE START */
848 834 #ifdef _INTEGRATED_SOLARIS_
849 835 /* If not SUN supplied mech, it has no strength */
850 836 if (minssf > 0 && !m->sun_reg)
851 837 break;
852 838 #endif /* _INTEGRATED_SOLARIS_ */
853 - /* CRYPT DELETE END */
854 - /* EXPORT DELETE END */
855 839
856 840 /* Does it meet our security properties? */
857 841 myflags = conn->props.security_flags;
858 842
859 843 /* if there's an external layer this is no longer plaintext */
860 844 if ((conn->props.min_ssf <= conn->external.ssf) &&
861 845 (conn->external.ssf > 1)) {
862 846 myflags &= ~SASL_SEC_NOPLAINTEXT;
863 847 }
864 848
865 849 if (((myflags ^ m->plug->security_flags) & myflags) != 0) {
866 850 break;
867 851 }
868 852
869 853 /* Can we meet it's features? */
870 854 if ((m->plug->features & SASL_FEAT_NEEDSERVERFQDN)
871 855 && !conn->serverFQDN) {
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
872 856 break;
873 857 }
874 858
875 859 /* Can it meet our features? */
876 860 if ((conn->flags & SASL_NEED_PROXY) &&
877 861 !(m->plug->features & SASL_FEAT_ALLOWS_PROXY)) {
878 862 break;
879 863 }
880 864
881 865 #ifdef PREFER_MECH
882 - /* EXPORT DELETE START */
883 - /* CRYPT DELETE START */
884 866 #ifdef _INTEGRATED_SOLARIS_
885 867 if (strcasecmp(m->plug->mech_name, PREFER_MECH) &&
886 868 bestm && (m->sun_reg && m->plug->max_ssf <= bestssf) ||
887 869 (m->plug->max_ssf == 0)) {
888 870 #else
889 - /* CRYPT DELETE END */
890 - /* EXPORT DELETE END */
891 871 if (strcasecmp(m->plug->mech_name, PREFER_MECH) &&
892 872 bestm && m->plug->max_ssf <= bestssf) {
893 -
894 - /* EXPORT DELETE START */
895 - /* CRYPT DELETE START */
896 873 #endif /* _INTEGRATED_SOLARIS_ */
897 - /* CRYPT DELETE END */
898 - /* EXPORT DELETE END */
899 874
900 875 /* this mechanism isn't our favorite, and it's no better
901 876 than what we already have! */
902 877 break;
903 878 }
904 879 #else
905 - /* EXPORT DELETE START */
906 - /* CRYPT DELETE START */
907 880 #ifdef _INTEGRATED_SOLARIS_
908 881 if (bestm && m->sun_reg && m->plug->max_ssf <= bestssf) {
909 882 #else
910 - /* CRYPT DELETE END */
911 - /* EXPORT DELETE END */
912 883
913 884 if (bestm && m->plug->max_ssf <= bestssf) {
914 - /* EXPORT DELETE START */
915 - /* CRYPT DELETE START */
916 885 #endif /* _INTEGRATED_SOLARIS_ */
917 - /* CRYPT DELETE END */
918 - /* EXPORT DELETE END */
919 886
920 887 /* this mechanism is no better than what we already have! */
921 888 break;
922 889 }
923 890 #endif
924 891
925 892 /* compare security flags, only take new mechanism if it has
926 893 * all the security flags of the previous one.
927 894 *
928 895 * From the mechanisms we ship with, this yields the order:
929 896 *
930 897 * SRP
931 898 * GSSAPI + KERBEROS_V4
932 899 * DIGEST + OTP
933 900 * CRAM + EXTERNAL
934 901 * PLAIN + LOGIN + ANONYMOUS
935 902 *
936 903 * This might be improved on by comparing the numeric value of
937 904 * the bitwise-or'd security flags, which splits DIGEST/OTP,
938 905 * CRAM/EXTERNAL, and PLAIN/LOGIN from ANONYMOUS, but then we
939 906 * are depending on the numeric values of the flags (which may
940 907 * change, and their ordering could be considered dumb luck.
941 908 */
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
942 909
943 910 if (bestm &&
944 911 ((m->plug->security_flags ^ bestm->plug->security_flags) &
945 912 bestm->plug->security_flags)) {
946 913 break;
947 914 }
948 915
949 916 if (mech) {
950 917 *mech = m->plug->mech_name;
951 918 }
952 - /* EXPORT DELETE START */
953 - /* CRYPT DELETE START */
954 919 #ifdef _INTEGRATED_SOLARIS_
955 920 bestssf = m->sun_reg ? m->plug->max_ssf : 0;
956 921 #else
957 - /* CRYPT DELETE END */
958 - /* EXPORT DELETE END */
959 922 bestssf = m->plug->max_ssf;
960 - /* EXPORT DELETE START */
961 - /* CRYPT DELETE START */
962 923 #endif /* _INTEGRATED_SOLARIS_ */
963 - /* CRYPT DELETE END */
964 - /* EXPORT DELETE END */
965 924 bestm = m;
966 925 break;
967 926 }
968 927 }
969 928
970 929 if (bestm == NULL) {
971 930 #ifdef _INTEGRATED_SOLARIS_
972 931 sasl_seterror(conn, 0, gettext("No worthy mechs found"));
973 932 #else
974 933 sasl_seterror(conn, 0, "No worthy mechs found");
975 934 #endif /* _INTEGRATED_SOLARIS_ */
976 935 result = SASL_NOMECH;
977 936 goto done;
978 937 }
979 938
980 939 /* make (the rest of) cparams */
981 940 c_conn->cparams->service = conn->service;
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
982 941 c_conn->cparams->servicelen = strlen(conn->service);
983 942
984 943 c_conn->cparams->serverFQDN = conn->serverFQDN;
985 944 c_conn->cparams->slen = strlen(conn->serverFQDN);
986 945
987 946 c_conn->cparams->clientFQDN = c_conn->clientFQDN;
988 947 c_conn->cparams->clen = strlen(c_conn->clientFQDN);
989 948
990 949 c_conn->cparams->external_ssf = conn->external.ssf;
991 950 c_conn->cparams->props = conn->props;
992 - /* EXPORT DELETE START */
993 - /* CRYPT DELETE START */
994 951 #ifdef _INTEGRATED_SOLARIS_
995 952 if (!bestm->sun_reg) {
996 953 c_conn->cparams->props.min_ssf = 0;
997 954 c_conn->cparams->props.max_ssf = 0;
998 955 }
999 956 c_conn->base.sun_reg = bestm->sun_reg;
1000 957 #endif /* _INTEGRATED_SOLARIS_ */
1001 - /* CRYPT DELETE END */
1002 - /* EXPORT DELETE END */
1003 958 c_conn->mech = bestm;
1004 959
1005 960 /* init that plugin */
1006 961 #ifdef _SUN_SDK_
1007 962 result = c_conn->mech->plug->mech_new(c_conn->mech->glob_context,
1008 963 #else
1009 964 result = c_conn->mech->plug->mech_new(c_conn->mech->plug->glob_context,
1010 965 #endif /* _SUN_SDK_ */
1011 966 c_conn->cparams,
1012 967 &(conn->context));
1013 968 if(result != SASL_OK) goto done;
1014 969
1015 970 /* do a step -- but only if we can do a client-send-first */
1016 971 dostep:
1017 972 if(clientout) {
1018 973 if(c_conn->mech->plug->features & SASL_FEAT_SERVER_FIRST) {
1019 974 *clientout = NULL;
1020 975 *clientoutlen = 0;
1021 976 result = SASL_CONTINUE;
1022 977 } else {
1023 978 result = sasl_client_step(conn, NULL, 0, prompt_need,
1024 979 clientout, clientoutlen);
1025 980 }
1026 981 }
1027 982 else
1028 983 result = SASL_CONTINUE;
1029 984
1030 985 done:
1031 986 RETURN(conn, result);
1032 987 }
1033 988
1034 989 /* do a single authentication step.
1035 990 * serverin -- the server message received by the client, MUST have a NUL
1036 991 * sentinel, not counted by serverinlen
1037 992 * output:
1038 993 * prompt_need -- on SASL_INTERACT, list of prompts needed to continue
1039 994 * clientout -- the client response to send to the server
1040 995 *
1041 996 * returns:
1042 997 * SASL_OK -- success
1043 998 * SASL_INTERACT -- user interaction needed to fill in prompt_need list
1044 999 * SASL_BADPROT -- server protocol incorrect/cancelled
1045 1000 * SASL_BADSERV -- server failed mutual auth
1046 1001 */
1047 1002
1048 1003 int sasl_client_step(sasl_conn_t *conn,
1049 1004 const char *serverin,
1050 1005 unsigned serverinlen,
1051 1006 sasl_interact_t **prompt_need,
1052 1007 const char **clientout,
1053 1008 unsigned *clientoutlen)
1054 1009 {
1055 1010 sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn;
1056 1011 int result;
1057 1012
1058 1013 #ifdef _SUN_SDK_
1059 1014 _sasl_global_context_t *gctx = (conn == NULL) ?
1060 1015 _sasl_gbl_ctx() : conn->gctx;
1061 1016
1062 1017 if(gctx->sasl_client_active==0) return SASL_NOTINIT;
1063 1018 #else
1064 1019 if(_sasl_client_active==0) return SASL_NOTINIT;
1065 1020 #endif /* _SUN_SDK_ */
1066 1021 if(!conn) return SASL_BADPARAM;
1067 1022
1068 1023 /* check parameters */
1069 1024 if ((serverin==NULL) && (serverinlen>0))
1070 1025 PARAMERROR(conn);
1071 1026
1072 1027 /* Don't do another step if the plugin told us that we're done */
1073 1028 if (conn->oparams.doneflag) {
1074 1029 _sasl_log(conn, SASL_LOG_ERR, "attempting client step after doneflag");
1075 1030 return SASL_FAIL;
1076 1031 }
1077 1032
1078 1033 if(clientout) *clientout = NULL;
1079 1034 if(clientoutlen) *clientoutlen = 0;
1080 1035
1081 1036 /* do a step */
1082 1037 result = c_conn->mech->plug->mech_step(conn->context,
1083 1038 c_conn->cparams,
1084 1039 serverin,
1085 1040 serverinlen,
1086 1041 prompt_need,
1087 1042 clientout, clientoutlen,
1088 1043 &conn->oparams);
1089 1044
1090 1045 if (result == SASL_OK) {
1091 1046 /* So we're done on this end, but if both
1092 1047 * 1. the mech does server-send-last
1093 1048 * 2. the protocol does not
1094 1049 * we need to return no data */
1095 1050 if(!*clientout && !(conn->flags & SASL_SUCCESS_DATA)) {
1096 1051 *clientout = "";
1097 1052 *clientoutlen = 0;
1098 1053 }
1099 1054
1100 1055 if(!conn->oparams.maxoutbuf) {
1101 1056 conn->oparams.maxoutbuf = conn->props.maxbufsize;
1102 1057 }
1103 1058
1104 1059 if(conn->oparams.user == NULL || conn->oparams.authid == NULL) {
1105 1060 #ifdef _SUN_SDK_
1106 1061 _sasl_log(conn, SASL_LOG_ERR,
1107 1062 "mech did not call canon_user for both authzid and authid");
1108 1063 #else
1109 1064 sasl_seterror(conn, 0,
1110 1065 "mech did not call canon_user for both authzid and authid");
1111 1066 #endif /* _SUN_SDK_ */
1112 1067 result = SASL_BADPROT;
1113 1068 }
1114 1069 }
1115 1070
1116 1071 RETURN(conn,result);
1117 1072 }
1118 1073
1119 1074 /* returns the length of all the mechanisms
1120 1075 * added up
1121 1076 */
1122 1077
1123 1078 #ifdef _SUN_SDK_
1124 1079 static unsigned mech_names_len(_sasl_global_context_t *gctx)
1125 1080 {
1126 1081 cmech_list_t *cmechlist = gctx->cmechlist;
1127 1082 #else
1128 1083 static unsigned mech_names_len()
1129 1084 {
1130 1085 #endif /* _SUN_SDK_ */
1131 1086 cmechanism_t *listptr;
1132 1087 unsigned result = 0;
1133 1088
1134 1089 for (listptr = cmechlist->mech_list;
1135 1090 listptr;
1136 1091 listptr = listptr->next)
1137 1092 result += strlen(listptr->plug->mech_name);
1138 1093
1139 1094 return result;
1140 1095 }
1141 1096
1142 1097
1143 1098 int _sasl_client_listmech(sasl_conn_t *conn,
1144 1099 const char *prefix,
1145 1100 const char *sep,
1146 1101 const char *suffix,
1147 1102 const char **result,
1148 1103 unsigned *plen,
1149 1104 int *pcount)
1150 1105 {
1151 1106 cmechanism_t *m=NULL;
1152 1107 sasl_ssf_t minssf = 0;
1153 1108 int ret;
1154 1109 unsigned int resultlen;
1155 1110 int flag;
1156 1111 const char *mysep;
1157 1112 #ifdef _SUN_SDK_
1158 1113 _sasl_global_context_t *gctx = conn == NULL ? _sasl_gbl_ctx() : conn->gctx;
1159 1114 cmech_list_t *cmechlist;
1160 1115
1161 1116 if(gctx->sasl_client_active==0) return SASL_NOTINIT;
1162 1117 cmechlist = gctx->cmechlist;
1163 1118 #else
1164 1119 if(_sasl_client_active == 0) return SASL_NOTINIT;
1165 1120 #endif /* _SUN_SDK_ */
1166 1121 if (!conn) return SASL_BADPARAM;
1167 1122 if(conn->type != SASL_CONN_CLIENT) PARAMERROR(conn);
1168 1123
1169 1124 if (! result)
1170 1125 PARAMERROR(conn);
1171 1126
1172 1127 #ifdef _SUN_SDK_
1173 1128 (void) _load_client_plugins(gctx);
1174 1129 #endif /* _SUN_SDK_ */
1175 1130
1176 1131 if (plen != NULL)
1177 1132 *plen = 0;
1178 1133 if (pcount != NULL)
1179 1134 *pcount = 0;
1180 1135
1181 1136 if (sep) {
1182 1137 mysep = sep;
1183 1138 } else {
1184 1139 mysep = " ";
1185 1140 }
1186 1141
1187 1142 if(conn->props.min_ssf < conn->external.ssf) {
1188 1143 minssf = 0;
1189 1144 } else {
1190 1145 minssf = conn->props.min_ssf - conn->external.ssf;
1191 1146 }
1192 1147
1193 1148 if (! cmechlist || cmechlist->mech_length <= 0)
1194 1149 INTERROR(conn, SASL_NOMECH);
1195 1150
1196 1151 resultlen = (prefix ? strlen(prefix) : 0)
1197 1152 + (strlen(mysep) * (cmechlist->mech_length - 1))
1198 1153 #ifdef _SUN_SDK_
1199 1154 + mech_names_len(gctx)
1200 1155 #else
1201 1156 + mech_names_len()
1202 1157 #endif /* _SUN_SDK_ */
1203 1158 + (suffix ? strlen(suffix) : 0)
1204 1159 + 1;
1205 1160 ret = _buf_alloc(&conn->mechlist_buf,
1206 1161 &conn->mechlist_buf_len, resultlen);
1207 1162 if(ret != SASL_OK) MEMERROR(conn);
1208 1163
1209 1164 if (prefix)
1210 1165 strcpy (conn->mechlist_buf,prefix);
1211 1166 else
1212 1167 *(conn->mechlist_buf) = '\0';
1213 1168
↓ open down ↓ |
201 lines elided |
↑ open up ↑ |
1214 1169 flag = 0;
1215 1170 for (m = cmechlist->mech_list; m != NULL; m = m->next) {
1216 1171 /* do we have the prompts for it? */
1217 1172 if (!have_prompts(conn, m->plug))
1218 1173 continue;
1219 1174
1220 1175 /* is it strong enough? */
1221 1176 if (minssf > m->plug->max_ssf)
1222 1177 continue;
1223 1178
1224 - /* EXPORT DELETE START */
1225 - /* CRYPT DELETE START */
1226 1179 #ifdef _INTEGRATED_SOLARIS_
1227 1180 /* If not SUN supplied mech, it has no strength */
1228 1181 if (minssf > 0 && !m->sun_reg)
1229 1182 continue;
1230 1183 #endif /* _INTEGRATED_SOLARIS_ */
1231 - /* CRYPT DELETE END */
1232 - /* EXPORT DELETE END */
1233 1184
1234 1185 /* does it meet our security properties? */
1235 1186 if (((conn->props.security_flags ^ m->plug->security_flags)
1236 1187 & conn->props.security_flags) != 0) {
1237 1188 continue;
1238 1189 }
1239 1190
1240 1191 /* Can we meet it's features? */
1241 1192 if ((m->plug->features & SASL_FEAT_NEEDSERVERFQDN)
1242 1193 && !conn->serverFQDN) {
1243 1194 continue;
1244 1195 }
1245 1196
1246 1197 /* Can it meet our features? */
1247 1198 if ((conn->flags & SASL_NEED_PROXY) &&
1248 1199 !(m->plug->features & SASL_FEAT_ALLOWS_PROXY)) {
1249 1200 break;
1250 1201 }
1251 1202
1252 1203 /* Okay, we like it, add it to the list! */
1253 1204
1254 1205 if (pcount != NULL)
1255 1206 (*pcount)++;
1256 1207
1257 1208 /* print seperator */
1258 1209 if (flag) {
1259 1210 strcat(conn->mechlist_buf, mysep);
1260 1211 } else {
1261 1212 flag = 1;
1262 1213 }
1263 1214
1264 1215 /* now print the mechanism name */
1265 1216 strcat(conn->mechlist_buf, m->plug->mech_name);
1266 1217 }
1267 1218
1268 1219 if (suffix)
1269 1220 strcat(conn->mechlist_buf,suffix);
1270 1221
1271 1222 if (plen!=NULL)
1272 1223 *plen=strlen(conn->mechlist_buf);
1273 1224
1274 1225 *result = conn->mechlist_buf;
1275 1226
1276 1227 return SASL_OK;
1277 1228 }
1278 1229
1279 1230 #ifdef _SUN_SDK_
1280 1231 sasl_string_list_t *_sasl_client_mechs(_sasl_global_context_t *gctx)
1281 1232 {
1282 1233 cmech_list_t *cmechlist = gctx->cmechlist;
1283 1234 #else
1284 1235 sasl_string_list_t *_sasl_client_mechs(void)
1285 1236 {
1286 1237 #endif /* _SUN_SDK_ */
1287 1238 cmechanism_t *listptr;
1288 1239 sasl_string_list_t *retval = NULL, *next=NULL;
1289 1240
1290 1241 #ifdef _SUN_SDK_
1291 1242 if(!gctx->sasl_client_active) return NULL;
1292 1243 #else
1293 1244 if(!_sasl_client_active) return NULL;
1294 1245 #endif /* _SUN_SDK_ */
1295 1246
1296 1247 /* make list */
1297 1248 for (listptr = cmechlist->mech_list; listptr; listptr = listptr->next) {
1298 1249 next = sasl_ALLOC(sizeof(sasl_string_list_t));
1299 1250
1300 1251 if(!next && !retval) return NULL;
1301 1252 else if(!next) {
1302 1253 next = retval->next;
1303 1254 do {
1304 1255 sasl_FREE(retval);
1305 1256 retval = next;
1306 1257 next = retval->next;
1307 1258 } while(next);
1308 1259 return NULL;
1309 1260 }
1310 1261
1311 1262 next->d = listptr->plug->mech_name;
1312 1263
1313 1264 if(!retval) {
1314 1265 next->next = NULL;
1315 1266 retval = next;
1316 1267 } else {
1317 1268 next->next = retval;
1318 1269 retval = next;
1319 1270 }
1320 1271 }
1321 1272
1322 1273 return retval;
1323 1274 }
↓ open down ↓ |
81 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX