2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 RCSID("$Id: spx.c,v 1.17 1999/09/16 20:41:34 assar Exp $");
40 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
43 * "Digital Equipment Corporation authorizes the reproduction,
44 * distribution and modification of this software subject to the following
47 * 1. Any partial or whole copy of this software, or any modification
48 * thereof, must include this copyright notice in its entirety.
50 * 2. This software is supplied "as is" with no warranty of any kind,
51 * expressed or implied, for any purpose, including any warranty of fitness
52 * or merchantibility. DIGITAL assumes no responsibility for the use or
53 * reliability of this software, nor promises to provide any form of
54 * support for it on any basis.
56 * 3. Distribution of this software is authorized only if no profit or
57 * remuneration of any kind is received in exchange for such distribution.
59 * 4. This software produces public key authentication certificates
60 * bearing an expiration date established by DIGITAL and RSA Data
61 * Security, Inc. It may cease to generate certificates after the expiration
62 * date. Any modification of this software that changes or defeats
63 * the expiration date or its effect is unauthorized.
65 * 5. Software that will renew or extend the expiration date of
66 * authentication certificates produced by this software may be obtained
67 * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
68 * 94065, (415)595-8782, or from DIGITAL"
72 #ifdef HAVE_SYS_TYPES_H
73 #include <sys/types.h>
75 #ifdef HAVE_ARPA_TELNET_H
76 #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 */
103 static des_key_schedule sched;
104 static des_cblock challenge = { 0 };
107 /*******************************************************************/
109 gss_OID_set actual_mechs;
110 gss_OID actual_mech_type, output_name_type;
111 int major_status, status, msg_ctx = 0, new_status;
112 int req_flags = 0, ret_flags, lifetime_rec;
113 gss_cred_id_t gss_cred_handle;
114 gss_ctx_id_t actual_ctxhandle, context_handle;
115 gss_buffer_desc output_token, input_token, input_name_buffer;
116 gss_buffer_desc status_string;
117 gss_name_t desired_targname, src_name;
118 gss_channel_bindings input_chan_bindings;
119 char lhostname[GSS_C_MAX_PRINTABLE_NAME];
120 char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
121 int to_addr=0, from_addr=0;
123 gss_buffer_desc fullname_buffer;
124 gss_OID fullname_type;
125 gss_cred_id_t gss_delegated_cred_handle;
127 /*******************************************************************/
138 unsigned char *p = str_data + 4;
139 unsigned char *cd = (unsigned char *)d;
142 c = strlen((char *)cd);
145 printf("%s:%d: [%d] (%d)",
146 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
156 if ((*p++ = *cd++) == IAC)
161 if (str_data[3] == TELQUAL_IS)
162 printsub('>', &str_data[2], p - (&str_data[2]));
163 return(telnet_net_write(str_data, p - str_data));
171 gss_cred_id_t tmp_cred_handle;
174 str_data[3] = TELQUAL_REPLY;
175 gethostname(lhostname, sizeof(lhostname));
176 snprintf (targ_printable, sizeof(targ_printable),
177 "SERVICE:rcmd@%s", lhostname);
178 input_name_buffer.length = strlen(targ_printable);
179 input_name_buffer.value = targ_printable;
180 major_status = gss_import_name(&status,
184 major_status = gss_acquire_cred(&status,
192 if (major_status != GSS_S_COMPLETE) return(0);
194 str_data[3] = TELQUAL_IS;
206 gss_OID actual_mech_type, output_name_type;
207 int msg_ctx = 0, new_status, status;
208 int req_flags = 0, ret_flags, lifetime_rec, major_status;
209 gss_buffer_desc output_token, input_token, input_name_buffer;
210 gss_buffer_desc output_name_buffer, status_string;
211 gss_name_t desired_targname;
212 gss_channel_bindings input_chan_bindings;
213 char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
214 int from_addr=0, to_addr=0, myhostlen, j;
215 int deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0;
218 printf("[ Trying SPX ... ]\r\n");
219 snprintf (targ_printable, sizeof(targ_printable),
220 "SERVICE:rcmd@%s", RemoteHostName);
222 input_name_buffer.length = strlen(targ_printable);
223 input_name_buffer.value = targ_printable;
225 if (!UserNameRequested) {
229 major_status = gss_import_name(&status,
235 major_status = gss_display_name(&status,
240 printf("target is '%s'\n", output_name_buffer.value); fflush(stdout);
242 major_status = gss_release_buffer(&status, &output_name_buffer);
244 input_chan_bindings = (gss_channel_bindings)
245 malloc(sizeof(gss_channel_bindings_desc));
247 input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
248 input_chan_bindings->initiator_address.length = 4;
249 address = (char *) malloc(4);
250 input_chan_bindings->initiator_address.value = (char *) address;
251 address[0] = ((from_addr & 0xff000000) >> 24);
252 address[1] = ((from_addr & 0xff0000) >> 16);
253 address[2] = ((from_addr & 0xff00) >> 8);
254 address[3] = (from_addr & 0xff);
255 input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
256 input_chan_bindings->acceptor_address.length = 4;
257 address = (char *) malloc(4);
258 input_chan_bindings->acceptor_address.value = (char *) address;
259 address[0] = ((to_addr & 0xff000000) >> 24);
260 address[1] = ((to_addr & 0xff0000) >> 16);
261 address[2] = ((to_addr & 0xff00) >> 8);
262 address[3] = (to_addr & 0xff);
263 input_chan_bindings->application_data.length = 0;
266 if (deleg_flag) req_flags = req_flags | 1;
267 if (mutual_flag) req_flags = req_flags | 2;
268 if (replay_flag) req_flags = req_flags | 4;
269 if (seq_flag) req_flags = req_flags | 8;
271 major_status = gss_init_sec_context(&status, /* minor status */
272 GSS_C_NO_CREDENTIAL, /* cred handle */
273 &actual_ctxhandle, /* ctx handle */
274 desired_targname, /* target name */
275 GSS_C_NULL_OID, /* mech type */
276 req_flags, /* req flags */
278 input_chan_bindings, /* chan binding */
279 GSS_C_NO_BUFFER, /* input token */
280 &actual_mech_type, /* actual mech */
281 &output_token, /* output token */
282 &ret_flags, /* ret flags */
283 &lifetime_rec); /* time rec */
285 if ((major_status != GSS_S_COMPLETE) &&
286 (major_status != GSS_S_CONTINUE_NEEDED)) {
287 gss_display_status(&new_status,
293 printf("%s\n", status_string.value);
297 if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
301 if (!Data(ap, SPX_AUTH, output_token.value, output_token.length)) {
309 spx_is(ap, data, cnt)
315 des_cblock datablock;
322 input_token.length = cnt;
323 input_token.value = (char *) data;
325 gethostname(lhostname, sizeof(lhostname));
327 snprintf(targ_printable, sizeof(targ_printable),
328 "SERVICE:rcmd@%s", lhostname);
330 input_name_buffer.length = strlen(targ_printable);
331 input_name_buffer.value = targ_printable;
333 major_status = gss_import_name(&status,
338 major_status = gss_acquire_cred(&status,
347 major_status = gss_release_name(&status, desired_targname);
349 input_chan_bindings = (gss_channel_bindings)
350 malloc(sizeof(gss_channel_bindings_desc));
352 input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
353 input_chan_bindings->initiator_address.length = 4;
354 address = (char *) malloc(4);
355 input_chan_bindings->initiator_address.value = (char *) address;
356 address[0] = ((from_addr & 0xff000000) >> 24);
357 address[1] = ((from_addr & 0xff0000) >> 16);
358 address[2] = ((from_addr & 0xff00) >> 8);
359 address[3] = (from_addr & 0xff);
360 input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
361 input_chan_bindings->acceptor_address.length = 4;
362 address = (char *) malloc(4);
363 input_chan_bindings->acceptor_address.value = (char *) address;
364 address[0] = ((to_addr & 0xff000000) >> 24);
365 address[1] = ((to_addr & 0xff0000) >> 16);
366 address[2] = ((to_addr & 0xff00) >> 8);
367 address[3] = (to_addr & 0xff);
368 input_chan_bindings->application_data.length = 0;
370 major_status = gss_accept_sec_context(&status,
380 &gss_delegated_cred_handle);
383 if (major_status != GSS_S_COMPLETE) {
385 major_status = gss_display_name(&status,
389 Data(ap, SPX_REJECT, "auth failed", -1);
390 auth_finished(ap, AUTH_REJECT);
394 major_status = gss_display_name(&status,
400 Data(ap, SPX_ACCEPT, output_token.value, output_token.length);
401 auth_finished(ap, AUTH_USER);
405 Data(ap, SPX_REJECT, 0, 0);
412 spx_reply(ap, data, cnt)
424 printf("[ SPX refuses authentication because %.*s ]\r\n",
427 printf("[ SPX refuses authentication ]\r\n");
431 printf("[ SPX accepts you ]\r\n");
432 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
434 * Send over the encrypted challenge.
436 input_token.value = (char *) data;
437 input_token.length = cnt;
439 major_status = gss_init_sec_context(&status, /* minor stat */
440 GSS_C_NO_CREDENTIAL, /* cred handle */
441 &actual_ctxhandle, /* ctx handle */
442 desired_targname, /* target name */
443 GSS_C_NULL_OID, /* mech type */
444 req_flags, /* req flags */
446 input_chan_bindings, /* chan binding */
447 &input_token, /* input token */
448 &actual_mech_type, /* actual mech */
449 &output_token, /* output token */
450 &ret_flags, /* ret flags */
451 &lifetime_rec); /* time rec */
453 if (major_status != GSS_S_COMPLETE) {
454 gss_display_status(&new_status,
460 printf("[ SPX mutual response fails ... '%s' ]\r\n",
461 status_string.value);
466 auth_finished(ap, AUTH_USER);
475 spx_status(ap, name, name_sz, level)
482 gss_buffer_desc fullname_buffer, acl_file_buffer;
483 gss_OID fullname_type;
484 char acl_file[160], fullname[160];
485 int major_status, status = 0;
489 * hard code fullname to
490 * "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
491 * and acl_file to "~kannan/.sphinx"
494 pwd = k_getpwnam(UserNameRequested);
496 return(AUTH_USER); /* not authenticated */
499 snprintf (acl_file, sizeof(acl_file),
500 "%s/.sphinx", pwd->pw_dir);
502 acl_file_buffer.value = acl_file;
503 acl_file_buffer.length = strlen(acl_file);
505 major_status = gss_display_name(&status,
510 if (level < AUTH_USER)
513 major_status = gss__check_acl(&status, &fullname_buffer,
516 if (major_status == GSS_S_COMPLETE) {
517 strlcpy(name, UserNameRequested, name_sz);
525 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
526 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
529 spx_printsub(data, cnt, buf, buflen)
530 unsigned char *data, *buf;
535 buf[buflen-1] = '\0'; /* make sure its NULL terminated */
539 case SPX_REJECT: /* Rejected (reason might follow) */
540 strlcpy((char *)buf, " REJECT ", buflen);
543 case SPX_ACCEPT: /* Accepted (name might follow) */
544 strlcpy((char *)buf, " ACCEPT ", buflen);
549 ADDC(buf, buflen, '"');
550 for (i = 4; i < cnt; i++)
551 ADDC(buf, buflen, data[i]);
552 ADDC(buf, buflen, '"');
553 ADDC(buf, buflen, '\0');
556 case SPX_AUTH: /* Authentication data follows */
557 strlcpy((char *)buf, " AUTH", buflen);
561 snprintf(buf, buflen, " %d (unknown)", data[3]);
564 for (i = 4; i < cnt; i++) {
565 snprintf(buf, buflen, " %d", data[i]);
582 for (i = 0; i < 8; i++)
583 printf(" %3d", key[i]);