Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 81342
Collapse All | Expand All

(-)cyrus-sasl-2.1.20.orig/configure.in (-4 / +38 lines)
Lines 543-568 Link Here
543
  ntlm=$enableval,
543
  ntlm=$enableval,
544
  ntlm=no)
544
  ntlm=no)
545
545
546
if test "$with_openssl" = no; then
546
AC_ARG_WITH(ntlm_impl, [  --with-ntlm_impl={cyrus|samba}          Choose specific NTLMSSP implementation [cyrus] ],
547
  ntlm_impl=$withval,
548
  ntlm_impl=cyrus)
549
550
if test "$with_openssl" = no -a "$ntlm_impl" = cyrus; then
547
  AC_WARN([OpenSSL not found -- NTLM will be disabled])
551
  AC_WARN([OpenSSL not found -- NTLM will be disabled])
548
  ntlm=no
552
  ntlm=no
549
fi
553
fi
550
554
551
AC_MSG_CHECKING(NTLM)
555
AC_MSG_CHECKING(NTLM)
552
if test "$ntlm" != no; then
556
if test "$ntlm" != no; then
553
  AC_MSG_RESULT(enabled)
557
  AC_MSG_RESULT(with implementation ${ntlm_impl})
554
  NTLM_LIBS="-lcrypto $LIB_RSAREF"
558
559
  if test "$ntlm_impl" = samba; then
560
    NTLM_LIBS=""
561
    NTLM_OBJS="ntlm_samba.lo"
562
    NTLM_STATIC_OBJS="ntlm_samba.o"
563
  else
564
    NTLM_LIBS="-lcrypto $LIB_RSAREF"
565
    NTLM_OBJS="ntlm.lo"
566
    NTLM_STATIC_OBJS="ntlm.o"
567
  fi
568
555
  AC_SUBST(NTLM_LIBS)
569
  AC_SUBST(NTLM_LIBS)
570
  AC_SUBST(NTLM_OBJS)
556
571
557
  SASL_MECHS="$SASL_MECHS libntlm.la"
572
  SASL_MECHS="$SASL_MECHS libntlm.la"
558
  if test "$enable_static" = yes; then
573
  if test "$enable_static" = yes; then
559
    SASL_STATIC_OBJS="$SASL_STATIC_OBJS ../plugins/ntlm.o"
574
    SASL_STATIC_OBJS="$SASL_STATIC_OBJS ../plugins/$NTLM_STATIC_OBJS"
560
    AC_DEFINE(STATIC_NTLM,[],[Link NTLM Staticly])
575
    AC_DEFINE(STATIC_NTLM,[],[Link NTLM Staticly])
561
  fi
576
  fi
562
else
577
else
563
  AC_MSG_RESULT(disabled)
578
  AC_MSG_RESULT(disabled)
564
fi
579
fi
565
580
581
dnl GSSSPNEGO
582
AC_ARG_ENABLE(gssspnego, [  --enable-gssspnego           enable unsupported GSSSPNEGO authentication [no] ],
583
  gssspnego=$enableval,
584
  gssspnego=no)
585
586
AC_MSG_CHECKING(GSSSPNEGO)
587
if test "$gssspnego" != no; then
588
  AC_MSG_RESULT(enabled)
589
  AC_SUBST(GSSSPNEGO_LIBS)
590
591
  SASL_MECHS="$SASL_MECHS libgssspnego.la"
592
  if test "$enable_static" = yes; then
593
    SASL_STATIC_OBJS="$SASL_STATIC_OBJS ../plugins/gssspnego.o"
594
    AC_DEFINE(STATIC_GSSSPNEGO,[],[Link GSSSPNEGO Staticly])
595
  fi
596
else
597
  AC_MSG_RESULT(disabled)
598
fi
599
566
600
567
# make the option show up so people don't whine that it is only in the
601
# make the option show up so people don't whine that it is only in the
568
# saslauthd configure script --help
602
# saslauthd configure script --help
(-)cyrus-sasl-2.1.20.orig/plugins/Makefile.am (-5 / +12 lines)
Lines 55-60 Link Here
55
login_version = 2:20:0
55
login_version = 2:20:0
56
plain_version = 2:20:0
56
plain_version = 2:20:0
57
ntlm_version = 2:20:0
57
ntlm_version = 2:20:0
58
gssspnego_version = 2:20:0
58
otp_version = 2:20:0
59
otp_version = 2:20:0
59
sql_version = 2:20:0
60
sql_version = 2:20:0
60
srp_version = 2:20:0
61
srp_version = 2:20:0
Lines 77-83 Link Here
77
sasl_LTLIBRARIES = @SASL_MECHS@
78
sasl_LTLIBRARIES = @SASL_MECHS@
78
EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
79
EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
79
	libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
80
	libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
80
	libntlm.la libsasldb.la libsql.la
81
	libntlm.la libgssspnego.la libsasldb.la libsql.la
81
82
82
libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
83
libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
83
libplain_la_LDFLAGS = -version-info $(plain_version)
84
libplain_la_LDFLAGS = -version-info $(plain_version)
Lines 124-133 Link Here
124
libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
125
libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
125
libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
126
libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
126
127
127
libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources)
128
libntlm_la_SOURCES = smb_helper.c smb_helper.h ntlm_init.c $(common_sources)
129
EXTRA_libntlm_la_SOURCES = ntlm.c ntlm_samba.c
128
libntlm_la_LDFLAGS = -version-info $(ntlm_version)
130
libntlm_la_LDFLAGS = -version-info $(ntlm_version)
129
libntlm_la_DEPENDENCIES = $(COMPAT_OBJS)
131
libntlm_la_DEPENDENCIES = $(COMPAT_OBJS) $(NTLM_OBJS)
130
libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS)
132
libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS) $(NTLM_OBJS)
133
134
libgssspnego_la_SOURCES = smb_helper.c smb_helper.h gssspnego.c gssspnego_init.c $(common_sources)
135
libgssspnego_la_LDFLAGS = -version-info $(gssspnego_version)
136
libgssspnego_la_DEPENDENCIES = $(COMPAT_OBJS)
137
libgssspnego_la_LIBADD = $(GSSSPNEGO_LIBS) $(COMPAT_OBJS)
131
138
132
# Auxprop Plugins
139
# Auxprop Plugins
133
libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
140
libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
Lines 145-151 Link Here
145
152
146
init_src=anonymous_init.c crammd5_init.c digestmd5_init.c gssapiv2_init.c \
153
init_src=anonymous_init.c crammd5_init.c digestmd5_init.c gssapiv2_init.c \
147
kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
154
kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
148
sasldb_init.c sql_init.c
155
gssspnego_init.c sasldb_init.c sql_init.c
149
156
150
157
151
CLEANFILES=$(init_src)
158
CLEANFILES=$(init_src)
(-)cyrus-sasl-2.1.20.orig/plugins/gssspnego.c (+557 lines)
Line 0 Link Here
1
/* GSS SPNEGO plugin
2
 * Volker Lendecke
3
 */
4
/* 
5
 * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer. 
13
 *
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in
16
 *    the documentation and/or other materials provided with the
17
 *    distribution.
18
 *
19
 * 3. The name "Carnegie Mellon University" must not be used to
20
 *    endorse or promote products derived from this software without
21
 *    prior written permission. For permission or any other legal
22
 *    details, please contact  
23
 *      Office of Technology Transfer
24
 *      Carnegie Mellon University
25
 *      5000 Forbes Avenue
26
 *      Pittsburgh, PA  15213-3890
27
 *      (412) 268-4387, fax: (412) 268-7395
28
 *      tech-transfer@andrew.cmu.edu
29
 *
30
 * 4. Redistributions of any form whatsoever must retain the following
31
 *    acknowledgment:
32
 *    "This product includes software developed by Computing Services
33
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
34
 *
35
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
36
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
37
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
38
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
39
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
40
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
41
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42
 */
43
44
#include <config.h>
45
#include <stdio.h>
46
#include <string.h> 
47
#include <sasl.h>
48
#include <saslplug.h>
49
#include <syslog.h>
50
51
#include <sys/types.h>
52
#include <sys/wait.h>
53
#include <unistd.h>
54
55
#include "plugin_common.h"
56
#include "smb_helper.h"
57
58
#ifdef macintosh 
59
#include <sasl_gssspnego_plugin_decl.h> 
60
#endif 
61
62
/*****************************  Common Section  *****************************/
63
64
static const char plugin_id[] = "$Id: gssspnego.c,v 1.61 2003/03/26 17:18:04 rjs3 Exp $";
65
66
/*****************************  Server Section  *****************************/
67
68
struct gssspnego_context {
69
	struct smb_helper *helper;
70
};
71
72
static int gssspnego_server_mech_new(void *glob_context __attribute__((unused)), 
73
				 sasl_server_params_t *sparams,
74
				 const char *challenge __attribute__((unused)),
75
				 unsigned challen __attribute__((unused)),
76
				 void **conn_context)
77
{
78
	char * argv[] = { "ntlm_auth",
79
			  "--helper-protocol=gss-spnego",
80
			  NULL };
81
82
	struct gssspnego_context *context =
83
		malloc(sizeof(struct gssspnego_context));
84
85
	if (context == NULL) {
86
		syslog(LOG_DEBUG, "gssspnego_server_mech_new: No memory\n");
87
		MEMERROR(sparams->utils);
88
		return SASL_NOMEM;
89
	}
90
91
	memset(context, 0, sizeof(struct gssspnego_context));
92
93
	*conn_context = context;
94
95
	return fork_helper(&context->helper, "ntlm_auth",
96
				argv, sparams->utils);
97
}
98
99
static int gssspnego_server_mech_step(void *conn_context,
100
				      sasl_server_params_t *params,
101
				      const char *clientin,
102
				      unsigned clientinlen,
103
				      const char **serverout,
104
				      unsigned *serveroutlen,
105
				      sasl_out_params_t *oparams)
106
{
107
	struct gssspnego_context *context =
108
		(struct gssspnego_context *)conn_context;
109
110
	unsigned char childbuf[1025];
111
	unsigned childbuflen;
112
113
	unsigned char *childarg;
114
	unsigned base64len;
115
116
	static unsigned char bin[1025];
117
118
	int result;
119
120
	if (clientinlen == 0) {
121
122
		/* This should only happen on the first request, we
123
                   need the initial mechanism offer from the child. */
124
125
		strncpy(childbuf, "YR", sizeof(childbuf)-1);
126
		childbuflen = strlen(childbuf);
127
128
	} else {
129
130
		strncpy(childbuf, "KK ", sizeof(childbuf)-1);
131
132
		if (params->utils->encode64(clientin, clientinlen,
133
					    childbuf+3, sizeof(childbuf)-4,
134
					    &childbuflen) != SASL_OK) {
135
			syslog(LOG_DEBUG,
136
			       "Could not convert clientin to base64\n");
137
			return SASL_FAIL;
138
		}
139
	}
140
141
	if ((result = interact_helper(context->helper,
142
					childbuf,
143
					sizeof(childbuf),
144
					&childbuflen)) != SASL_OK)
145
		return result;
146
147
	/* The child's reply contains 3 parts:
148
	   - The code: TT, AF or NA
149
	   - The blob to send to the client, coded in base64
150
	   - The argument:
151
	         For TT it's a dummy '*'
152
		 For AF it's domain\\user
153
		 For NA it's the NT error code
154
	*/
155
156
	childarg = strchr(childbuf+3, ' ');
157
158
	if (childarg == NULL) {
159
		syslog(LOG_DEBUG, "Got invalid response from child\n");
160
		return SASL_FAIL;
161
	}
162
163
	base64len = (childarg - childbuf) - 3;
164
165
	if (params->utils->decode64(childbuf+3, base64len,
166
				    bin, sizeof(bin)-1,
167
				    serveroutlen) != SASL_OK) {
168
		syslog(LOG_DEBUG, "Could not decode child's base64\n");
169
		return SASL_FAIL;
170
	}
171
	*serverout = bin;
172
	childarg++;
173
174
	if ( strncmp(childbuf, "TT ", 3) == 0) {
175
		/* Next round */
176
		return SASL_CONTINUE;
177
	}
178
	if (strncmp(childbuf, "NA ", 3) == 0) {
179
		/* Not Authenticated */
180
		kill_helper(context->helper);
181
		return SASL_BADAUTH;
182
	}
183
184
	if (strncmp(childbuf, "AF ", 3) == 0) {
185
		/* Authentication Fine */
186
		char *domain = childarg;
187
		char *user = strchr(domain, '\\');
188
		int status;
189
190
		kill_helper(context->helper);
191
192
		if (user == NULL) {
193
			syslog(LOG_DEBUG,
194
			       "Could not find user/domain in AF\n");
195
			return SASL_FAIL;
196
		}
197
		*user++ = 0;
198
		if ( (status = params->canon_user(params->utils->conn,
199
						  user, 0, SASL_CU_AUTHID,
200
						  oparams)) != SASL_OK ) {
201
			syslog(LOG_DEBUG, "canon_user for AUTHID failed\n");
202
			return status;
203
		}
204
205
		if ( (status = params->canon_user(params->utils->conn,
206
						  user, 0, SASL_CU_AUTHZID,
207
						  oparams)) != SASL_OK ) {
208
			syslog(LOG_DEBUG, "canon_user for AUTHZID failed\n");
209
			return status;
210
		}
211
					    
212
		oparams->doneflag = 1;
213
		oparams->mech_ssf = 0;
214
		oparams->maxoutbuf = 0;
215
		oparams->encode_context = NULL;
216
		oparams->encode = NULL;
217
		oparams->decode_context = NULL;
218
		oparams->decode = NULL;
219
220
		return SASL_OK;
221
	}
222
223
	syslog(LOG_DEBUG, "Child's response unknown\n");
224
	return SASL_FAIL;
225
}
226
227
static void gssspnego_server_mech_dispose(void *conn_context,
228
					  const sasl_utils_t *utils __attribute__((unused)))
229
{
230
	struct gssspnego_context *context =
231
		(struct gssspnego_context *)conn_context;
232
233
	kill_helper(context->helper);
234
235
	return;
236
}
237
238
static sasl_server_plug_t gssspnego_server_plugins[] = 
239
{
240
    {
241
	"GSS-SPNEGO",			/* mech_name */
242
	0,				/* max_ssf */
243
	SASL_SEC_NOANONYMOUS
244
	| SASL_SEC_NOPLAINTEXT,		/* security_flags */
245
	SASL_FEAT_SERVER_FIRST,		/* features */
246
	NULL,				/* glob_context */
247
	&gssspnego_server_mech_new,		/* mech_new */
248
	&gssspnego_server_mech_step,	/* mech_step */
249
	&gssspnego_server_mech_dispose,	/* mech_dispose */
250
	NULL,				/* mech_free */
251
	NULL,				/* setpass */
252
	NULL,				/* user_query */
253
	NULL,				/* idle */
254
	NULL,				/* mech_avail */
255
	NULL				/* spare */
256
    }
257
};
258
259
int gssspnego_server_plug_init(const sasl_utils_t *utils,
260
			   int maxversion,
261
			   int *out_version,
262
			   sasl_server_plug_t **pluglist,
263
			   int *plugcount)
264
{
265
    if (maxversion < SASL_SERVER_PLUG_VERSION) {
266
	SETERROR(utils, "GSSSPNEGO version mismatch");
267
	return SASL_BADVERS;
268
    }
269
    
270
    *out_version = SASL_SERVER_PLUG_VERSION;
271
    *pluglist = gssspnego_server_plugins;
272
    *plugcount = 1;  
273
    
274
    return SASL_OK;
275
}
276
277
/*****************************  Client Section  *****************************/
278
279
static int gssspnego_new_client_helper(struct gssspnego_context *context,
280
				       sasl_client_params_t *params,
281
				       sasl_interact_t **prompt_need,
282
				       sasl_out_params_t *oparams)
283
{
284
	int auth_result = SASL_OK;
285
	int domain_result = SASL_OK;
286
	static const char *authid = NULL;
287
	static const char *domain = NULL;
288
289
	char child_user_arg[512];
290
	char child_domain_arg[512];
291
292
	int result;
293
294
	char *argv[] = { "ntlm_auth",
295
			 "--helper-protocol=gss-spnego-client",
296
			 child_user_arg,
297
			 child_domain_arg,
298
			 NULL };
299
300
	if (authid == NULL) {
301
		auth_result = _plug_get_authid(params->utils,
302
					       &authid, prompt_need);
303
304
		if ( (auth_result != SASL_OK) &&
305
		     (auth_result != SASL_INTERACT) &&
306
		     (authid == NULL) )
307
			return auth_result;
308
	}
309
310
	if (domain == NULL) {
311
		domain_result = _plug_get_realm(params->utils, NULL,
312
						&domain, prompt_need);
313
		if ( (domain_result != SASL_OK) &&
314
		     (domain_result != SASL_INTERACT) &&
315
		     (domain == NULL) )
316
			return domain_result;
317
	}
318
319
	/* free prompts we got */
320
	if (prompt_need && *prompt_need) {
321
		params->utils->free(*prompt_need);
322
		*prompt_need = NULL;
323
	}
324
325
	if ( (auth_result == SASL_INTERACT) ||
326
	     (domain_result == SASL_INTERACT) ) {
327
		result = _plug_make_prompts(params->utils, prompt_need,
328
					    NULL, NULL,
329
					    (auth_result == SASL_INTERACT) ?
330
					    "Username" : NULL, NULL,
331
					    NULL, NULL,
332
					    NULL, NULL, NULL,
333
					    NULL,
334
					    (domain_result == SASL_INTERACT) ?
335
					    "Realm (Domain)" : NULL, NULL);
336
337
		if (result != SASL_OK)
338
			return result;
339
		return SASL_INTERACT;
340
	}
341
342
	oparams->user   = strdup(authid);
343
	oparams->ulen   = strlen(authid);
344
	oparams->authid = strdup(authid);
345
	oparams->alen   = oparams->ulen;
346
347
	snprintf(child_user_arg, sizeof(child_user_arg)-1,
348
		 "--username=%s", authid);
349
	snprintf(child_domain_arg, sizeof(child_domain_arg)-1,
350
		 "--domain=%s", domain);
351
352
	return fork_helper(&context->helper, "ntlm_auth",
353
				argv, params->utils);
354
}
355
356
static int gssspnego_client_mech_new(void *glob_context __attribute__((unused)),
357
				     sasl_client_params_t *params,
358
				     void **conn_context)
359
{
360
	struct gssspnego_context *context =
361
		malloc(sizeof(struct gssspnego_context));
362
363
	if (context == NULL) {
364
		MEMERROR(params->utils);
365
		return SASL_NOMEM;
366
	}
367
368
	memset(context, 0, sizeof(struct gssspnego_context));
369
370
	*conn_context = context;
371
372
	return SASL_OK;
373
}
374
375
static int gssspnego_client_mech_step(void *conn_context,
376
				  sasl_client_params_t *params,
377
				  const char *serverin,
378
				  unsigned serverinlen,
379
				  sasl_interact_t **prompt_need,
380
				  const char **clientout,
381
				  unsigned *clientoutlen,
382
				  sasl_out_params_t *oparams)
383
{
384
	struct gssspnego_context *context =
385
		(struct gssspnego_context *)conn_context;
386
387
	unsigned char childbuf[1025];
388
	unsigned childbuflen;
389
390
	int result;
391
392
	static sasl_secret_t *password;
393
	static int must_free_password;
394
	static int must_send_password = 0;
395
396
	if (context->helper == NULL) {
397
		result = gssspnego_new_client_helper(context, params,
398
						     prompt_need, oparams);
399
400
		if (result != SASL_OK)
401
			return result;
402
	}
403
404
	if (must_send_password != 0) {
405
406
		must_send_password = 0;
407
408
	send_password:
409
410
		strncpy(childbuf, "PW ", sizeof(childbuf)-1);
411
412
		if (params->utils->encode64(password->data, password->len,
413
					    childbuf+3, sizeof(childbuf)-3,
414
					    &childbuflen) != SASL_OK) {
415
			syslog(LOG_DEBUG,
416
			       "Could not convert password to base64\n");
417
			return SASL_FAIL;
418
		}
419
420
		if ((result = interact_helper(context->helper,
421
						childbuf,
422
						sizeof(childbuf),
423
						&childbuflen)) != SASL_OK)
424
			return result;
425
426
		if (strncmp(childbuf, "OK", 2) != 0) {
427
			syslog(LOG_DEBUG, "Child did not accept our password\n");
428
			return SASL_FAIL;
429
		}
430
	}
431
432
	strncpy(childbuf, "TT ", sizeof(childbuf)-1);
433
434
	if (params->utils->encode64(serverin, serverinlen,
435
				    childbuf+3, sizeof(childbuf)-4,
436
				    &childbuflen) != SASL_OK) {
437
		syslog(LOG_DEBUG,
438
		       "Could not convert serverin to base64\n");
439
		return SASL_FAIL;
440
	}
441
442
	if ((result = interact_helper(context->helper,
443
					childbuf,
444
					sizeof(childbuf),
445
					&childbuflen)) != SASL_OK)
446
		return result;
447
448
	/* The child's reply can be:
449
	   "PW" -> It wants a password
450
	   "KK <base64>" -> Send <base64> to the server
451
	   "AF" -> Authenticated
452
	   "NA" -> Not Authenticated
453
	*/
454
455
	if (strncmp(childbuf, "PW", 2) == 0) {
456
457
		result = _plug_get_password(params->utils, &password,
458
					    &must_free_password, prompt_need);
459
460
		if ( (result != SASL_OK) &&
461
		     (result != SASL_INTERACT) )
462
			return result;
463
464
		/* free prompts we got */
465
		if (prompt_need && *prompt_need) {
466
			params->utils->free(*prompt_need);
467
			*prompt_need = NULL;
468
		}
469
470
		if (result == SASL_OK)
471
			goto send_password;
472
473
		result = _plug_make_prompts(params->utils, prompt_need,
474
					    NULL, NULL,
475
					    NULL, NULL,
476
					    "Password", NULL,
477
					    NULL, NULL, NULL,
478
					    NULL, NULL, NULL);
479
		if (result != SASL_OK)
480
			return result;
481
		return SASL_INTERACT;
482
483
	}
484
485
	if (strncmp(childbuf, "KK ", 3) == 0) {
486
		static char bin[2048];
487
488
		if (params->utils->decode64(childbuf+3, childbuflen-3,
489
					    bin, sizeof(bin)-1,
490
					    clientoutlen) != SASL_OK) {
491
			syslog(LOG_DEBUG, "Could not decode child's base64\n");
492
			return SASL_FAIL;
493
		}
494
		*clientout = bin;
495
		return SASL_CONTINUE;
496
	}
497
498
	if ( (strncmp(childbuf, "AF", 2) == 0) ||
499
	     (strncmp(childbuf, "NA", 2) == 0) ) {
500
		
501
		kill_helper(context->helper);
502
503
		*clientout = NULL;
504
		*clientoutlen = 0;
505
506
		/* set oparams */
507
		oparams->doneflag = 1;
508
		oparams->mech_ssf = 0;
509
		oparams->maxoutbuf = 0;
510
		oparams->encode_context = NULL;
511
		oparams->encode = NULL;
512
		oparams->decode_context = NULL;
513
		oparams->decode = NULL;
514
515
		return (strncmp(childbuf, "AF", 2) == 0) ?
516
			SASL_OK : SASL_BADAUTH;
517
	}
518
519
	return SASL_FAIL;
520
}
521
522
static sasl_client_plug_t gssspnego_client_plugins[] = 
523
{
524
    {
525
	"GSS-SPNEGO",			/* mech_name */
526
	0,				/* max_ssf */
527
	SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT,		/* security_flags */
528
	SASL_FEAT_SERVER_FIRST, /* features */
529
	NULL,				/* required_prompts */
530
	NULL,				/* glob_context */
531
	&gssspnego_client_mech_new,	/* mech_new */
532
	&gssspnego_client_mech_step,	/* mech_step */
533
	NULL,				/* mech_dispose */
534
	NULL,				/* mech_free */
535
	NULL,				/* idle */
536
	NULL,				/* spare */
537
	NULL				/* spare */
538
    }
539
};
540
541
int gssspnego_client_plug_init(sasl_utils_t *utils,
542
			   int maxversion,
543
			   int *out_version,
544
			   sasl_client_plug_t **pluglist,
545
			   int *plugcount)
546
{
547
    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
548
	SETERROR(utils, "GSSSPNEGO version mismatch");
549
	return SASL_BADVERS;
550
    }
551
    
552
    *out_version = SASL_CLIENT_PLUG_VERSION;
553
    *pluglist = gssspnego_client_plugins;
554
    *plugcount = 1;
555
    
556
    return SASL_OK;
557
}
(-)cyrus-sasl-2.1.20.orig/plugins/makeinit.sh (-1 / +1 lines)
Lines 1-4 Link Here
1
for mech in anonymous crammd5 digestmd5 gssapiv2 kerberos4 login ntlm otp plain srp; do
1
for mech in anonymous crammd5 digestmd5 gssapiv2 kerberos4 login ntlm gssspnego otp plain srp; do
2
2
3
echo "
3
echo "
4
#include <config.h>
4
#include <config.h>
(-)cyrus-sasl-2.1.20.orig/plugins/ntlm_samba.c (+561 lines)
Line 0 Link Here
1
/* NTLM (via ntlm_auth) plugin
2
 * Volker Lendecke, Andrew Bartlett
3
 */
4
/* 
5
 * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer. 
13
 *
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in
16
 *    the documentation and/or other materials provided with the
17
 *    distribution.
18
 *
19
 * 3. The name "Carnegie Mellon University" must not be used to
20
 *    endorse or promote products derived from this software without
21
 *    prior written permission. For permission or any other legal
22
 *    details, please contact  
23
 *      Office of Technology Transfer
24
 *      Carnegie Mellon University
25
 *      5000 Forbes Avenue
26
 *      Pittsburgh, PA  15213-3890
27
 *      (412) 268-4387, fax: (412) 268-7395
28
 *      tech-transfer@andrew.cmu.edu
29
 *
30
 * 4. Redistributions of any form whatsoever must retain the following
31
 *    acknowledgment:
32
 *    "This product includes software developed by Computing Services
33
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
34
 *
35
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
36
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
37
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
38
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
39
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
40
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
41
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42
 */
43
44
#include <config.h>
45
#include <stdio.h>
46
#include <string.h> 
47
#include <sasl.h>
48
#include <saslplug.h>
49
#include <syslog.h>
50
51
#include <sys/types.h>
52
#include <sys/wait.h>
53
#include <unistd.h>
54
55
#include "plugin_common.h"
56
#include "smb_helper.h"
57
58
#ifdef macintosh 
59
#include <sasl_ntlm_plugin_decl.h> 
60
#endif 
61
62
/*****************************  Common Section  *****************************/
63
64
static const char plugin_id[] = "$Id: ntlm.c,v 1.61 2003/03/26 17:18:04 rjs3 Exp $";
65
66
/*****************************  Server Section  *****************************/
67
68
struct ntlm_context {
69
	struct smb_helper *helper;
70
	int first;
71
	sasl_secret_t *password;	/* user password */
72
	unsigned int free_password; /* set if we need to free password */
73
	unsigned int sent_password; /* set if we have told ntlm_auth the password already */
74
	const char *authid;
75
	const char *domain;
76
};
77
78
static int ntlm_server_mech_new(void *glob_context __attribute__((unused)), 
79
				 sasl_server_params_t *sparams,
80
				 const char *challenge __attribute__((unused)),
81
				 unsigned challen __attribute__((unused)),
82
				 void **conn_context)
83
{
84
	char * argv[] = { "ntlm_auth",
85
			  "--helper-protocol=squid-2.5-ntlmssp",
86
			  NULL };
87
88
	struct ntlm_context *context =
89
		malloc(sizeof(struct ntlm_context));
90
	
91
	if (context == NULL) {
92
		syslog(LOG_DEBUG, "ntlm_server_mech_new: No memory\n");
93
		MEMERROR(sparams->utils);
94
		return SASL_NOMEM;
95
	}
96
97
	memset(context, 0, sizeof(struct ntlm_context));
98
	context->first = 1;
99
100
	*conn_context = context;
101
102
	return fork_helper(&context->helper, "ntlm_auth",
103
				argv, sparams->utils);
104
}
105
106
static int ntlm_server_mech_step(void *conn_context,
107
				      sasl_server_params_t *params,
108
				      const char *clientin,
109
				      unsigned clientinlen,
110
				      const char **serverout,
111
				      unsigned *serveroutlen,
112
				      sasl_out_params_t *oparams)
113
{
114
	struct ntlm_context *context =
115
		(struct ntlm_context *)conn_context;
116
117
	unsigned char childbuf[1025];
118
	unsigned childbuflen;
119
120
	unsigned base64len;
121
122
	static unsigned char bin[1025];
123
124
	int result;
125
126
	if (context->first) {
127
		strncpy(childbuf, "YR ", sizeof(childbuf)-1);
128
		context->first = 0;
129
	} else {
130
		strncpy(childbuf, "KK ", sizeof(childbuf)-1);
131
	}
132
133
	if (params->utils->encode64(clientin, clientinlen,
134
				    childbuf+3, sizeof(childbuf)-4,
135
				    &childbuflen) != SASL_OK) {
136
		syslog(LOG_DEBUG,
137
		       "Could not convert clientin to base64\n");
138
		return SASL_FAIL;
139
	}
140
141
	if ((result = interact_helper(context->helper,
142
					childbuf,
143
					sizeof(childbuf),
144
					&childbuflen)) != SASL_OK)
145
		return result;
146
	
147
	/* The child's reply contains 3 parts:
148
	   - The code: TT, AF or NA
149
	   - The blob to send to the client, coded in base64
150
	   - or for AF it's domain\\user
151
	        for NA it's the NT error code
152
	*/
153
154
	if (strlen(childbuf) < 3) {
155
		syslog(LOG_DEBUG, "Got invalid response from child (parse of ntlm_auth output failure)\n");
156
		return SASL_FAIL;
157
	}
158
159
	base64len = strlen(childbuf) - 3;
160
161
	if ( strncmp(childbuf, "TT ", 3) == 0) {
162
		if (params->utils->decode64(childbuf+3, base64len,
163
					    bin, sizeof(bin)-1,
164
					    serveroutlen) != SASL_OK) {
165
			syslog(LOG_DEBUG, "Could not decode child's base64\n");
166
			return SASL_FAIL;
167
		}
168
		*serverout = bin;
169
170
		/* Next round */
171
		return SASL_CONTINUE;
172
	}
173
	if (strncmp(childbuf, "NA ", 3) == 0) {
174
		/* Not Authenticated */
175
		kill_helper(context->helper);
176
		return SASL_BADAUTH;
177
	}
178
179
	if (strncmp(childbuf, "AF ", 3) == 0) {
180
		/* Authentication Fine */
181
		char *user = childbuf + 3;
182
		int status;
183
184
		kill_helper(context->helper);
185
186
		if ( (status = params->canon_user(params->utils->conn,
187
						  user, 0, SASL_CU_AUTHID,
188
						  oparams)) != SASL_OK ) {
189
			syslog(LOG_DEBUG, "canon_user for AUTHID [%s] failed\n", user);
190
			return status;
191
		}
192
193
		if ( (status = params->canon_user(params->utils->conn,
194
						  user, 0, SASL_CU_AUTHZID,
195
						  oparams)) != SASL_OK ) {
196
			syslog(LOG_DEBUG, "canon_user for AUTHZID [%s] failed\n", user);
197
			return status;
198
		}
199
					    
200
		oparams->doneflag = 1;
201
		oparams->mech_ssf = 0;
202
		oparams->maxoutbuf = 0;
203
		oparams->encode_context = NULL;
204
		oparams->encode = NULL;
205
		oparams->decode_context = NULL;
206
		oparams->decode = NULL;
207
208
		return SASL_OK;
209
	}
210
211
	syslog(LOG_DEBUG, "Child's response unknown\n");
212
	return SASL_FAIL;
213
}
214
215
static void ntlm_server_mech_dispose(void *conn_context,
216
					  const sasl_utils_t *utils __attribute__((unused)))
217
{
218
	struct ntlm_context *context =
219
		(struct ntlm_context *)conn_context;
220
221
	kill_helper(context->helper);
222
223
	return;
224
}
225
226
static sasl_server_plug_t ntlm_server_plugins[] = 
227
{
228
    {
229
	"NTLM",			/* mech_name */
230
	0,				/* max_ssf */
231
	SASL_SEC_NOANONYMOUS
232
	| SASL_SEC_NOPLAINTEXT,		/* security_flags */
233
	SASL_FEAT_WANT_CLIENT_FIRST,		/* features */
234
	NULL,				/* glob_context */
235
	&ntlm_server_mech_new,		/* mech_new */
236
	&ntlm_server_mech_step,	/* mech_step */
237
	&ntlm_server_mech_dispose,	/* mech_dispose */
238
	NULL,				/* mech_free */
239
	NULL,				/* setpass */
240
	NULL,				/* user_query */
241
	NULL,				/* idle */
242
	NULL,				/* mech_avail */
243
	NULL				/* spare */
244
    }
245
};
246
247
int ntlm_server_plug_init(const sasl_utils_t *utils,
248
			   int maxversion,
249
			   int *out_version,
250
			   sasl_server_plug_t **pluglist,
251
			   int *plugcount)
252
{
253
    if (maxversion < SASL_SERVER_PLUG_VERSION) {
254
	SETERROR(utils, "NTLM version mismatch");
255
	return SASL_BADVERS;
256
    }
257
    
258
    *out_version = SASL_SERVER_PLUG_VERSION;
259
    *pluglist = ntlm_server_plugins;
260
    *plugcount = 1;  
261
    
262
    return SASL_OK;
263
}
264
265
/*****************************  Client Section  *****************************/
266
267
static int ntlm_new_client_helper(struct ntlm_context *context,
268
				       sasl_client_params_t *params,
269
				       sasl_interact_t **prompt_need,
270
				       sasl_out_params_t *oparams)
271
{
272
	int auth_result = SASL_OK;
273
	int domain_result = SASL_OK;
274
275
	int pass_result = SASL_OK;
276
	int result;
277
278
	char child_user_arg[512];
279
	char child_domain_arg[512];
280
281
	const char *domains[] = {
282
		"",
283
		NULL
284
	};
285
286
	char *argv[] = { "ntlm_auth",
287
			 "--helper-protocol=ntlmssp-client-1",
288
			 child_user_arg,
289
			 child_domain_arg,
290
			 NULL };
291
292
	if (context->authid == NULL) {
293
		auth_result = _plug_get_authid(params->utils,
294
					       &context->authid, prompt_need);
295
296
		if ( (auth_result != SASL_OK) &&
297
		     (auth_result != SASL_INTERACT) &&
298
		     (context->authid == NULL) )
299
			return auth_result;
300
	}
301
302
	if (context->domain == NULL) {
303
		domain_result = _plug_get_realm(params->utils, domains,
304
						&context->domain, prompt_need);
305
		if ( (domain_result != SASL_OK) &&
306
		     (domain_result != SASL_INTERACT) &&
307
		     (context->domain == NULL) )
308
			return domain_result;
309
	}
310
	
311
	if (context->password == NULL) {
312
		pass_result = _plug_get_password(params->utils, &context->password,
313
					    &context->free_password, prompt_need);
314
		
315
		if ( (pass_result != SASL_OK) &&
316
		     (pass_result != SASL_INTERACT) 
317
		     && (context->password == NULL))
318
			return pass_result;
319
	}
320
		
321
	/* free prompts we got */
322
	if (prompt_need && *prompt_need) {
323
		params->utils->free(*prompt_need);
324
		*prompt_need = NULL;
325
	}
326
327
	if ( (auth_result == SASL_INTERACT) ||
328
	     (domain_result == SASL_INTERACT) ) {
329
		result = _plug_make_prompts(params->utils, prompt_need,
330
					    NULL, NULL,
331
					    (auth_result == SASL_INTERACT) ?
332
					    "Username" : NULL, NULL,
333
					    pass_result == SASL_INTERACT ?
334
					    "Password" : NULL, NULL,
335
					    NULL, NULL, NULL,
336
					    NULL,
337
					    (domain_result == SASL_INTERACT) ?
338
					    "Realm (Domain)" : NULL, NULL);
339
340
		if (result != SASL_OK)
341
			return result;
342
		return SASL_INTERACT;
343
	}
344
345
	if (!context->password) {
346
	    PARAMERROR(params->utils);
347
	    return SASL_BADPARAM;
348
	}
349
350
	oparams->user   = strdup(context->authid);
351
	oparams->ulen   = strlen(context->authid);
352
	oparams->authid = strdup(context->authid);
353
	oparams->alen   = oparams->ulen;
354
355
	snprintf(child_user_arg, sizeof(child_user_arg)-1,
356
		 "--username=%s", context->authid);
357
	snprintf(child_domain_arg, sizeof(child_domain_arg)-1,
358
		 "--domain=%s", context->domain);
359
360
	return fork_helper(&context->helper, "ntlm_auth",
361
				argv, params->utils);
362
}
363
364
static int ntlm_client_mech_new(void *glob_context __attribute__((unused)),
365
				     sasl_client_params_t *params,
366
				     void **conn_context)
367
{
368
	struct ntlm_context *context =
369
		malloc(sizeof(struct ntlm_context));
370
371
	if (context == NULL) {
372
		MEMERROR(params->utils);
373
		return SASL_NOMEM;
374
	}
375
376
	memset(context, 0, sizeof(struct ntlm_context));
377
	context->first = 1;
378
379
	*conn_context = context;
380
381
	return SASL_OK;
382
}
383
384
static int ntlm_client_mech_step(void *conn_context,
385
				  sasl_client_params_t *params,
386
				  const char *serverin,
387
				  unsigned serverinlen,
388
				  sasl_interact_t **prompt_need,
389
				  const char **clientout,
390
				  unsigned *clientoutlen,
391
				  sasl_out_params_t *oparams)
392
{
393
	struct ntlm_context *context =
394
		(struct ntlm_context *)conn_context;
395
396
	unsigned char childbuf[1025];
397
	unsigned childbuflen;
398
399
	int result;
400
401
	if (context->helper == NULL) {
402
		result = ntlm_new_client_helper(context, params,
403
						prompt_need, oparams);
404
405
		if (result != SASL_OK)
406
			return result;
407
	}
408
409
	if (!context->sent_password) {
410
411
		strncpy(childbuf, "PW ", sizeof(childbuf)-1);
412
		
413
		if (params->utils->encode64(context->password->data, context->password->len,
414
					    childbuf+3, sizeof(childbuf)-3,
415
					    &childbuflen) != SASL_OK) {
416
			syslog(LOG_DEBUG,
417
			       "Could not convert password to base64\n");
418
			return SASL_FAIL;
419
		}
420
		
421
		if ((result = interact_helper(context->helper,
422
						childbuf,
423
						sizeof(childbuf),
424
						&childbuflen)) != SASL_OK)
425
			return result;
426
		
427
		if (strncmp(childbuf, "OK", 2) != 0) {
428
			syslog(LOG_DEBUG, "Child did not accept our password\n");
429
			return SASL_FAIL;
430
		}
431
		context->sent_password = 1;
432
	}
433
434
	if (context->first) {
435
		strncpy(childbuf, "YR", sizeof(childbuf)-1);
436
		context->first = 0;
437
	} else {
438
		strncpy(childbuf, "TT", sizeof(childbuf)-1);
439
	}
440
441
	if (serverinlen) {
442
		strncpy(childbuf+2, " ", sizeof(childbuf)-3);
443
		if (params->utils->encode64(serverin, serverinlen,
444
					    childbuf+3, sizeof(childbuf)-4,
445
					    &childbuflen) != SASL_OK) {
446
			syslog(LOG_DEBUG,
447
			       "Could not convert serverin to base64\n");
448
			return SASL_FAIL;
449
		}
450
	}
451
452
	if ((result = interact_helper(context->helper,
453
					childbuf,
454
					sizeof(childbuf),
455
					&childbuflen)) != SASL_OK)
456
		return result;
457
458
	/* The child's reply can be:
459
	   "PW" -> It wants a password (but we premptivly deal with that above)
460
	   "YR <base64>" -> Send (initial) <base64> to the server
461
	   "KK <base64>" -> Send <base64> to the server
462
	   "AF" -> Authenticated
463
	   "NA" -> Not Authenticated
464
	*/
465
466
	if ((strncmp(childbuf, "YR ", 3) == 0) || (strncmp(childbuf, "KK ", 3) == 0)) {
467
		static char bin[2048];
468
469
		if (params->utils->decode64(childbuf+3, childbuflen-3,
470
					    bin, sizeof(bin)-1,
471
					    clientoutlen) != SASL_OK) {
472
			syslog(LOG_DEBUG, "Could not decode child's base64\n");
473
			return SASL_FAIL;
474
		}
475
		*clientout = bin;
476
		return SASL_CONTINUE;
477
	}
478
479
	if ( (strncmp(childbuf, "AF", 2) == 0) ||
480
	     (strncmp(childbuf, "NA", 2) == 0) ) {
481
		
482
		kill_helper(context->helper);
483
484
		*clientout = NULL;
485
		*clientoutlen = 0;
486
487
		/* set oparams */
488
		oparams->doneflag = 1;
489
		oparams->mech_ssf = 0;
490
		oparams->maxoutbuf = 0;
491
		oparams->encode_context = NULL;
492
		oparams->encode = NULL;
493
		oparams->decode_context = NULL;
494
		oparams->decode = NULL;
495
496
		return (strncmp(childbuf, "AF", 2) == 0) ?
497
			SASL_OK : SASL_BADAUTH;
498
	}
499
500
	return SASL_FAIL;
501
}
502
503
static void ntlm_client_mech_dispose(void *conn_context,
504
				     const sasl_utils_t *utils __attribute__((unused)))
505
{
506
	struct ntlm_context *context =
507
		(struct ntlm_context *)conn_context;
508
509
	kill_helper(context->helper);
510
511
	return;
512
}
513
514
static void ntlm_client_mech_free(void *conn_context,
515
				  const sasl_utils_t *utils __attribute__((unused)))
516
{
517
	struct ntlm_context *context =
518
		(struct ntlm_context *)conn_context;
519
520
	if (context->free_password)
521
		_plug_free_secret(utils, &context->password);
522
523
	return;
524
}
525
526
static sasl_client_plug_t ntlm_client_plugins[] = 
527
{
528
    {
529
	"NTLM", 			/* mech_name */
530
	0,				/* max_ssf */
531
	SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT,		/* security_flags */
532
	SASL_FEAT_WANT_CLIENT_FIRST, /* features */
533
	NULL,				/* required_prompts */
534
	NULL,				/* glob_context */
535
	&ntlm_client_mech_new,	        /* mech_new */
536
	&ntlm_client_mech_step,	        /* mech_step */
537
	&ntlm_client_mech_dispose,	/* mech_dispose */
538
        &ntlm_client_mech_free, 	/* mech_free */
539
	NULL,				/* idle */
540
	NULL,				/* spare */
541
	NULL				/* spare */
542
    }
543
};
544
545
int ntlm_client_plug_init(sasl_utils_t *utils,
546
			   int maxversion,
547
			   int *out_version,
548
			   sasl_client_plug_t **pluglist,
549
			   int *plugcount)
550
{
551
    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
552
	SETERROR(utils, "NTLM version mismatch");
553
	return SASL_BADVERS;
554
    }
555
    
556
    *out_version = SASL_CLIENT_PLUG_VERSION;
557
    *pluglist = ntlm_client_plugins;
558
    *plugcount = 1;
559
    
560
    return SASL_OK;
561
}
(-)cyrus-sasl-2.1.20.orig/plugins/smb_helper.c (+168 lines)
Line 0 Link Here
1
/* Interface functions to samba's ntlm_auth helper
2
 * Volker Lendecke, Andrew Bartlett
3
 *
4
 * $Id:$
5
 */
6
/* 
7
 * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer. 
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. The name "Carnegie Mellon University" must not be used to
22
 *    endorse or promote products derived from this software without
23
 *    prior written permission. For permission or any other legal
24
 *    details, please contact  
25
 *      Office of Technology Transfer
26
 *      Carnegie Mellon University
27
 *      5000 Forbes Avenue
28
 *      Pittsburgh, PA  15213-3890
29
 *      (412) 268-4387, fax: (412) 268-7395
30
 *      tech-transfer@andrew.cmu.edu
31
 *
32
 * 4. Redistributions of any form whatsoever must retain the following
33
 *    acknowledgment:
34
 *    "This product includes software developed by Computing Services
35
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36
 *
37
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44
 */
45
46
#include <sys/types.h>
47
#include <unistd.h>
48
#include <stdlib.h>
49
#include <stdio.h>
50
#include <syslog.h>
51
52
#include <sasl.h>
53
#include <saslplug.h>
54
55
#include "plugin_common.h"
56
#include "smb_helper.h"
57
58
int fork_helper(struct smb_helper **new_helper,
59
		      const char *prog,
60
		      char * const argv[],
61
		      const sasl_utils_t *utils)
62
{
63
	int pipe_in[2];
64
	int pipe_out[2];
65
66
	struct smb_helper *helper = malloc(sizeof(struct smb_helper));
67
68
	if (helper == NULL) {
69
		syslog(LOG_DEBUG, "fork_helper: No memory\n");
70
		MEMERROR(utils);
71
		return SASL_NOMEM;
72
	}
73
	
74
	*new_helper = helper;
75
76
	if ( (pipe(pipe_in) < 0) || (pipe(pipe_out) < 0) ) {
77
		syslog(LOG_DEBUG, "fork_helper: could not open pipes\n");
78
		utils->seterror(utils->conn, 0, "Could not allocate pipe\n");
79
		return SASL_FAIL;
80
	}
81
82
	helper->child_pid = fork();
83
84
	if (helper->child_pid == -1) {
85
		syslog(LOG_DEBUG, "fork_helper: Could not fork\n");
86
		utils->seterror(utils->conn, 0, "Could not fork\n");
87
		return SASL_FAIL;
88
	}
89
90
	if (helper->child_pid == 0) {
91
92
		/* Set up the pipes correctly */
93
94
		close(0);
95
		close(1);
96
		dup2(pipe_out[0], 0);
97
		close(pipe_out[0]);
98
		close(pipe_out[1]);
99
		dup2(pipe_in[1], 1);
100
		close(pipe_in[0]);
101
		close(pipe_in[1]);
102
103
		execvp(prog, argv);
104
105
		/* We should never get here ... */
106
		exit(1);
107
108
	} else {
109
110
		helper->pipe_in = fdopen(pipe_in[0], "r");
111
		close(pipe_in[1]);
112
		helper->pipe_out = fdopen(pipe_out[1], "w");
113
		close(pipe_out[0]);
114
	}
115
116
	return SASL_OK;
117
}
118
119
int interact_helper(struct smb_helper *helper,
120
				unsigned char *childbuf,
121
				unsigned max_childbuflen,
122
				unsigned *childbuflen)
123
{
124
	syslog(LOG_DEBUG, "interact_helper: Sending %d bytes do child: %s\n",
125
	       *childbuflen, childbuf);
126
127
	fprintf(helper->pipe_out, "%s\n", childbuf);
128
	fflush(helper->pipe_out);
129
130
	if (fgets(childbuf, max_childbuflen-1, helper->pipe_in) == NULL) {
131
		syslog(LOG_DEBUG, "interact_helper: Did not get a response from helper\n");
132
		return SASL_FAIL;
133
	}
134
	
135
	*childbuflen = strlen(childbuf)-1;
136
	childbuf[*childbuflen] = '\0'; /* Strip trailing \n */
137
138
	syslog(LOG_DEBUG, "interact_helper: Got %d bytes from helper: %s\n",
139
	       *childbuflen, childbuf);
140
141
	if ( *childbuflen < 2 ) {
142
		syslog(LOG_DEBUG, "interact_helper: Got invalid response from helper\n");
143
		return SASL_FAIL;
144
	}
145
146
	if ((*childbuflen <= 3) && (strncmp(childbuf, "BH", 2) == 0)) {
147
		syslog(LOG_DEBUG, "interact_helper: Broke Helper somehow...\n");
148
		return SASL_FAIL;
149
	}
150
	return SASL_OK;
151
}
152
153
void kill_helper(struct smb_helper *helper)
154
{
155
	int status;
156
	
157
	if ((helper == NULL) || (helper->child_pid == 0))
158
		return;
159
160
	fclose(helper->pipe_out);
161
	fclose(helper->pipe_in);
162
163
	waitpid(helper->child_pid, &status, 0);
164
	syslog(LOG_DEBUG, "kill_helper: Helper died with status %d\n", status);
165
166
	helper->child_pid = 0;
167
	free(helper);
168
}
(-)cyrus-sasl-2.1.20.orig/plugins/smb_helper.h (+73 lines)
Line 0 Link Here
1
/* Interface functions to samba's ntlm_auth helper
2
 * Volker Lendecke, Andrew Bartlett
3
 *
4
 * $Id:$
5
 */
6
/* 
7
 * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer. 
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. The name "Carnegie Mellon University" must not be used to
22
 *    endorse or promote products derived from this software without
23
 *    prior written permission. For permission or any other legal
24
 *    details, please contact  
25
 *      Office of Technology Transfer
26
 *      Carnegie Mellon University
27
 *      5000 Forbes Avenue
28
 *      Pittsburgh, PA  15213-3890
29
 *      (412) 268-4387, fax: (412) 268-7395
30
 *      tech-transfer@andrew.cmu.edu
31
 *
32
 * 4. Redistributions of any form whatsoever must retain the following
33
 *    acknowledgment:
34
 *    "This product includes software developed by Computing Services
35
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36
 *
37
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44
 */
45
46
#ifndef _SMB_HELPER_H_
47
#define _SMB_HELPER_H_
48
49
#include <sys/types.h>
50
#include <stdio.h>
51
52
#include <sasl.h>
53
#include <saslplug.h>
54
55
struct smb_helper {
56
	pid_t child_pid;
57
	FILE *pipe_in;
58
	FILE *pipe_out;
59
};
60
61
int fork_helper(struct smb_helper **helper,
62
			const char *prog,
63
			char * const argv[],
64
			const sasl_utils_t *utils);
65
66
int interact_helper(struct smb_helper *helper,
67
				unsigned char *childbuf,
68
				unsigned max_childbuflen,
69
				unsigned *childbuflen);
70
71
void kill_helper(struct smb_helper *helper);
72
73
#endif

Return to bug 81342