1 /* $NetBSD: spx.c,v 1.6 2005/04/09 22:43:51 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
36 static char sccsid
[] = "@(#)spx.c 8.2 (Berkeley) 5/30/95";
38 __RCSID("$NetBSD: spx.c,v 1.6 2005/04/09 22:43:51 christos Exp $");
44 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
47 * "Digital Equipment Corporation authorizes the reproduction,
48 * distribution and modification of this software subject to the following
51 * 1. Any partial or whole copy of this software, or any modification
52 * thereof, must include this copyright notice in its entirety.
54 * 2. This software is supplied "as is" with no warranty of any kind,
55 * expressed or implied, for any purpose, including any warranty of fitness
56 * or merchantibility. DIGITAL assumes no responsibility for the use or
57 * reliability of this software, nor promises to provide any form of
58 * support for it on any basis.
60 * 3. Distribution of this software is authorized only if no profit or
61 * remuneration of any kind is received in exchange for such distribution.
63 * 4. This software produces public key authentication certificates
64 * bearing an expiration date established by DIGITAL and RSA Data
65 * Security, Inc. It may cease to generate certificates after the expiration
66 * date. Any modification of this software that changes or defeats
67 * the expiration date or its effect is unauthorized.
69 * 5. Software that will renew or extend the expiration date of
70 * authentication certificates produced by this software may be obtained
71 * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
72 * 94065, (415)595-8782, or from DIGITAL"
76 #include <sys/types.h>
77 #include <arpa/telnet.h>
79 #include "gssapi_defs.h"
92 extern auth_debug_mode
;
94 static unsigned char str_data
[1024] = { IAC
, SB
, TELOPT_AUTHENTICATION
, 0,
96 static unsigned char str_name
[1024] = { IAC
, SB
, TELOPT_AUTHENTICATION
,
99 #define SPX_AUTH 0 /* Authentication data follows */
100 #define SPX_REJECT 1 /* Rejected (reason might follow) */
101 #define SPX_ACCEPT 2 /* Accepted */
104 static Block session_key
= { 0 };
105 #endif /* ENCRYPTION */
106 static Schedule sched
;
107 static Block challenge
= { 0 };
110 /*******************************************************************/
112 gss_OID_set actual_mechs
;
113 gss_OID actual_mech_type
, output_name_type
;
114 int major_status
, status
, msg_ctx
= 0, new_status
;
115 int req_flags
= 0, ret_flags
, lifetime_rec
;
116 gss_cred_id_t gss_cred_handle
;
117 gss_ctx_id_t actual_ctxhandle
, context_handle
;
118 gss_buffer_desc output_token
, input_token
, input_name_buffer
;
119 gss_buffer_desc status_string
;
120 gss_name_t desired_targname
, src_name
;
121 gss_channel_bindings input_chan_bindings
;
122 char lhostname
[GSS_C_MAX_PRINTABLE_NAME
];
123 char targ_printable
[GSS_C_MAX_PRINTABLE_NAME
];
124 int to_addr
=0, from_addr
=0;
126 gss_buffer_desc fullname_buffer
;
127 gss_OID fullname_type
;
128 gss_cred_id_t gss_delegated_cred_handle
;
130 /*******************************************************************/
141 unsigned char *p
= str_data
+ 4;
142 unsigned char *cd
= (unsigned char *)d
;
145 c
= strlen((char *)cd
);
148 printf("%s:%d: [%d] (%d)",
149 str_data
[3] == TELQUAL_IS
? ">>>IS" : ">>>REPLY",
159 if ((*p
++ = *cd
++) == IAC
)
164 if (str_data
[3] == TELQUAL_IS
)
165 printsub('>', &str_data
[2], p
- (&str_data
[2]));
166 return(telnet_net_write(str_data
, p
- str_data
));
174 gss_cred_id_t tmp_cred_handle
;
177 str_data
[3] = TELQUAL_REPLY
;
178 gethostname(lhostname
, sizeof(lhostname
));
179 strlcpy(targ_printable
, "SERVICE:rcmd@",
180 sizeof(targ_printable
));
181 strlcat(targ_printable
, lhostname
, sizeof(targ_printable
));
182 input_name_buffer
.length
= strlen(targ_printable
);
183 input_name_buffer
.value
= targ_printable
;
184 major_status
= gss_import_name(&status
,
188 major_status
= gss_acquire_cred(&status
,
196 if (major_status
!= GSS_S_COMPLETE
) return(0);
198 str_data
[3] = TELQUAL_IS
;
210 gss_OID actual_mech_type
, output_name_type
;
211 int msg_ctx
= 0, new_status
, status
;
212 int req_flags
= 0, ret_flags
, lifetime_rec
, major_status
;
213 gss_buffer_desc output_token
, input_token
, input_name_buffer
;
214 gss_buffer_desc output_name_buffer
, status_string
;
215 gss_name_t desired_targname
;
216 gss_channel_bindings input_chan_bindings
;
217 char targ_printable
[GSS_C_MAX_PRINTABLE_NAME
];
218 int from_addr
=0, to_addr
=0, myhostlen
, j
;
219 int deleg_flag
=1, mutual_flag
=0, replay_flag
=0, seq_flag
=0;
222 printf("[ Trying SPX ... ]\n");
223 strlcpy(targ_printable
, "SERVICE:rcmd@", sizeof(targ_printable
));
224 strlcat(targ_printable
, RemoteHostName
, sizeof(targ_printable
));
226 input_name_buffer
.length
= strlen(targ_printable
);
227 input_name_buffer
.value
= targ_printable
;
229 if (!UserNameRequested
) {
233 major_status
= gss_import_name(&status
,
239 major_status
= gss_display_name(&status
,
244 printf("target is '%s'\n", output_name_buffer
.value
); fflush(stdout
);
246 major_status
= gss_release_buffer(&status
, &output_name_buffer
);
248 input_chan_bindings
= (gss_channel_bindings
)
249 malloc(sizeof(gss_channel_bindings_desc
));
251 input_chan_bindings
->initiator_addrtype
= GSS_C_AF_INET
;
252 input_chan_bindings
->initiator_address
.length
= 4;
253 address
= (char *) malloc(4);
254 input_chan_bindings
->initiator_address
.value
= (char *) address
;
255 address
[0] = ((from_addr
& 0xff000000) >> 24);
256 address
[1] = ((from_addr
& 0xff0000) >> 16);
257 address
[2] = ((from_addr
& 0xff00) >> 8);
258 address
[3] = (from_addr
& 0xff);
259 input_chan_bindings
->acceptor_addrtype
= GSS_C_AF_INET
;
260 input_chan_bindings
->acceptor_address
.length
= 4;
261 address
= (char *) malloc(4);
262 input_chan_bindings
->acceptor_address
.value
= (char *) address
;
263 address
[0] = ((to_addr
& 0xff000000) >> 24);
264 address
[1] = ((to_addr
& 0xff0000) >> 16);
265 address
[2] = ((to_addr
& 0xff00) >> 8);
266 address
[3] = (to_addr
& 0xff);
267 input_chan_bindings
->application_data
.length
= 0;
270 if (deleg_flag
) req_flags
= req_flags
| 1;
271 if (mutual_flag
) req_flags
= req_flags
| 2;
272 if (replay_flag
) req_flags
= req_flags
| 4;
273 if (seq_flag
) req_flags
= req_flags
| 8;
275 major_status
= gss_init_sec_context(&status
, /* minor status */
276 GSS_C_NO_CREDENTIAL
, /* cred handle */
277 &actual_ctxhandle
, /* ctx handle */
278 desired_targname
, /* target name */
279 GSS_C_NULL_OID
, /* mech type */
280 req_flags
, /* req flags */
282 input_chan_bindings
, /* chan binding */
283 GSS_C_NO_BUFFER
, /* input token */
284 &actual_mech_type
, /* actual mech */
285 &output_token
, /* output token */
286 &ret_flags
, /* ret flags */
287 &lifetime_rec
); /* time rec */
289 if ((major_status
!= GSS_S_COMPLETE
) &&
290 (major_status
!= GSS_S_CONTINUE_NEEDED
)) {
291 gss_display_status(&new_status
,
297 printf("%s\n", status_string
.value
);
301 if (!auth_sendname(UserNameRequested
, strlen(UserNameRequested
))) {
305 if (!Data(ap
, SPX_AUTH
, (void *)output_token
.value
, output_token
.length
)) {
313 spx_is(ap
, data
, cnt
)
326 input_token
.length
= cnt
;
327 input_token
.value
= (char *) data
;
329 gethostname(lhostname
, sizeof(lhostname
));
331 strlcpy(targ_printable
, "SERVICE:rcmd@",
332 sizeof(targ_printable
));
333 strlcat(targ_printable
, lhostname
, sizeof(targ_printable
));
335 input_name_buffer
.length
= strlen(targ_printable
);
336 input_name_buffer
.value
= targ_printable
;
338 major_status
= gss_import_name(&status
,
343 major_status
= gss_acquire_cred(&status
,
352 major_status
= gss_release_name(&status
, desired_targname
);
354 input_chan_bindings
= (gss_channel_bindings
)
355 malloc(sizeof(gss_channel_bindings_desc
));
357 input_chan_bindings
->initiator_addrtype
= GSS_C_AF_INET
;
358 input_chan_bindings
->initiator_address
.length
= 4;
359 address
= (char *) malloc(4);
360 input_chan_bindings
->initiator_address
.value
= (char *) address
;
361 address
[0] = ((from_addr
& 0xff000000) >> 24);
362 address
[1] = ((from_addr
& 0xff0000) >> 16);
363 address
[2] = ((from_addr
& 0xff00) >> 8);
364 address
[3] = (from_addr
& 0xff);
365 input_chan_bindings
->acceptor_addrtype
= GSS_C_AF_INET
;
366 input_chan_bindings
->acceptor_address
.length
= 4;
367 address
= (char *) malloc(4);
368 input_chan_bindings
->acceptor_address
.value
= (char *) address
;
369 address
[0] = ((to_addr
& 0xff000000) >> 24);
370 address
[1] = ((to_addr
& 0xff0000) >> 16);
371 address
[2] = ((to_addr
& 0xff00) >> 8);
372 address
[3] = (to_addr
& 0xff);
373 input_chan_bindings
->application_data
.length
= 0;
375 major_status
= gss_accept_sec_context(&status
,
385 &gss_delegated_cred_handle
);
388 if (major_status
!= GSS_S_COMPLETE
) {
390 major_status
= gss_display_name(&status
,
394 Data(ap
, SPX_REJECT
, (void *)"auth failed", -1);
395 auth_finished(ap
, AUTH_REJECT
);
399 major_status
= gss_display_name(&status
,
405 Data(ap
, SPX_ACCEPT
, (void *)output_token
.value
, output_token
.length
);
406 auth_finished(ap
, AUTH_USER
);
410 Data(ap
, SPX_REJECT
, 0, 0);
417 spx_reply(ap
, data
, cnt
)
429 printf("[ SPX refuses authentication because %.*s ]\r\n",
432 printf("[ SPX refuses authentication ]\r\n");
436 printf("[ SPX accepts you ]\n");
437 if ((ap
->way
& AUTH_HOW_MASK
) == AUTH_HOW_MUTUAL
) {
439 * Send over the encrypted challenge.
441 input_token
.value
= (char *) data
;
442 input_token
.length
= cnt
;
444 major_status
= gss_init_sec_context(&status
, /* minor stat */
445 GSS_C_NO_CREDENTIAL
, /* cred handle */
446 &actual_ctxhandle
, /* ctx handle */
447 desired_targname
, /* target name */
448 GSS_C_NULL_OID
, /* mech type */
449 req_flags
, /* req flags */
451 input_chan_bindings
, /* chan binding */
452 &input_token
, /* input token */
453 &actual_mech_type
, /* actual mech */
454 &output_token
, /* output token */
455 &ret_flags
, /* ret flags */
456 &lifetime_rec
); /* time rec */
458 if (major_status
!= GSS_S_COMPLETE
) {
459 gss_display_status(&new_status
,
465 printf("[ SPX mutual response fails ... '%s' ]\r\n",
466 status_string
.value
);
471 auth_finished(ap
, AUTH_USER
);
480 spx_status(ap
, name
, l
, level
)
487 gss_buffer_desc fullname_buffer
, acl_file_buffer
;
488 gss_OID fullname_type
;
489 char acl_file
[160], fullname
[160];
490 int major_status
, status
= 0;
491 struct passwd pws
, *pwd
;
495 * hard code fullname to
496 * "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
497 * and acl_file to "~kannan/.sphinx"
500 if (getpwnam_r(UserNameRequested
, &pws
, pwbuf
, sizeof(pwbuf
), &pwd
)
501 != 0 || pwd
== NULL
) {
502 return(AUTH_USER
); /* not authenticated */
505 strlcpy(acl_file
, pwd
->pw_dir
, sizeof(acl_file
));
506 strlcat(acl_file
, "/.sphinx", sizeof(acl_file
));
507 acl_file_buffer
.value
= acl_file
;
508 acl_file_buffer
.length
= strlen(acl_file
);
510 major_status
= gss_display_name(&status
,
515 if (level
< AUTH_USER
)
518 major_status
= gss__check_acl(&status
, &fullname_buffer
,
521 if (major_status
== GSS_S_COMPLETE
) {
522 strlcpy(name
, UserNameRequested
, l
);
530 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
531 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
534 spx_printsub(data
, cnt
, buf
, buflen
)
535 unsigned char *data
, *buf
;
541 buf
[buflen
-1] = '\0'; /* make sure its NULL terminated */
545 case SPX_REJECT
: /* Rejected (reason might follow) */
546 strncpy((char *)buf
, " REJECT ", buflen
);
549 case SPX_ACCEPT
: /* Accepted (name might follow) */
550 strncpy((char *)buf
, " ACCEPT ", buflen
);
555 ADDC(buf
, buflen
, '"');
556 for (i
= 4; i
< cnt
; i
++)
557 ADDC(buf
, buflen
, data
[i
]);
558 ADDC(buf
, buflen
, '"');
559 ADDC(buf
, buflen
, '\0');
562 case SPX_AUTH
: /* Authentication data follows */
563 strncpy((char *)buf
, " AUTH", buflen
);
567 snprintf(lbuf
, sizeof(lbuf
), " %d (unknown)", data
[3]);
568 strncpy((char *)buf
, lbuf
, buflen
);
571 for (i
= 4; i
< cnt
; i
++) {
572 snprintf(lbuf
, sizeof(lbuf
), " %d", data
[i
]);
573 strncpy((char *)buf
, lbuf
, buflen
);
590 for (i
= 0; i
< 8; i
++)
591 printf(" %3d", key
[i
]);