No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / appl / telnet / libtelnet / spx.c
blob74689c63dd808c8ed7afb2c031aef9d9f870fca6
1 /*-
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
7 * are met:
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
31 * SUCH DAMAGE.
34 #include <config.h>
36 __RCSID("$Heimdal: spx.c 22071 2007-11-14 20:04:50Z lha $"
37 "$NetBSD$");
39 #ifdef SPX
41 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
42 * ALL RIGHTS RESERVED
44 * "Digital Equipment Corporation authorizes the reproduction,
45 * distribution and modification of this software subject to the following
46 * restrictions:
48 * 1. Any partial or whole copy of this software, or any modification
49 * thereof, must include this copyright notice in its entirety.
51 * 2. This software is supplied "as is" with no warranty of any kind,
52 * expressed or implied, for any purpose, including any warranty of fitness
53 * or merchantibility. DIGITAL assumes no responsibility for the use or
54 * reliability of this software, nor promises to provide any form of
55 * support for it on any basis.
57 * 3. Distribution of this software is authorized only if no profit or
58 * remuneration of any kind is received in exchange for such distribution.
60 * 4. This software produces public key authentication certificates
61 * bearing an expiration date established by DIGITAL and RSA Data
62 * Security, Inc. It may cease to generate certificates after the expiration
63 * date. Any modification of this software that changes or defeats
64 * the expiration date or its effect is unauthorized.
66 * 5. Software that will renew or extend the expiration date of
67 * authentication certificates produced by this software may be obtained
68 * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
69 * 94065, (415)595-8782, or from DIGITAL"
73 #ifdef HAVE_SYS_TYPES_H
74 #include <sys/types.h>
75 #endif
76 #ifdef HAVE_ARPA_TELNET_H
77 #include <arpa/telnet.h>
78 #endif
79 #include <stdio.h>
80 #include "gssapi_defs.h"
81 #include <stdlib.h>
82 #include <string.h>
84 #include <pwd.h>
85 #ifdef SOCKS
86 #include <socks.h>
87 #endif
89 #include "encrypt.h"
90 #include "auth.h"
91 #include "misc.h"
93 extern auth_debug_mode;
95 static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
96 AUTHTYPE_SPX, };
97 static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
98 TELQUAL_NAME, };
100 #define SPX_AUTH 0 /* Authentication data follows */
101 #define SPX_REJECT 1 /* Rejected (reason might follow) */
102 #define SPX_ACCEPT 2 /* Accepted */
104 static des_key_schedule sched;
105 static des_cblock challenge = { 0 };
108 /*******************************************************************/
110 gss_OID_set actual_mechs;
111 gss_OID actual_mech_type, output_name_type;
112 int major_status, status, msg_ctx = 0, new_status;
113 int req_flags = 0, ret_flags, lifetime_rec;
114 gss_cred_id_t gss_cred_handle;
115 gss_ctx_id_t actual_ctxhandle, context_handle;
116 gss_buffer_desc output_token, input_token, input_name_buffer;
117 gss_buffer_desc status_string;
118 gss_name_t desired_targname, src_name;
119 gss_channel_bindings input_chan_bindings;
120 char lhostname[GSS_C_MAX_PRINTABLE_NAME];
121 char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
122 int to_addr=0, from_addr=0;
123 char *address;
124 gss_buffer_desc fullname_buffer;
125 gss_OID fullname_type;
126 gss_cred_id_t gss_delegated_cred_handle;
128 /*******************************************************************/
132 static int
133 Data(ap, type, d, c)
134 Authenticator *ap;
135 int type;
136 void *d;
137 int c;
139 unsigned char *p = str_data + 4;
140 unsigned char *cd = (unsigned char *)d;
142 if (c == -1)
143 c = strlen((char *)cd);
145 if (0) {
146 printf("%s:%d: [%d] (%d)",
147 str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
148 str_data[3],
149 type, c);
150 printd(d, c);
151 printf("\r\n");
153 *p++ = ap->type;
154 *p++ = ap->way;
155 *p++ = type;
156 while (c-- > 0) {
157 if ((*p++ = *cd++) == IAC)
158 *p++ = IAC;
160 *p++ = IAC;
161 *p++ = SE;
162 if (str_data[3] == TELQUAL_IS)
163 printsub('>', &str_data[2], p - (&str_data[2]));
164 return(telnet_net_write(str_data, p - str_data));
168 spx_init(ap, server)
169 Authenticator *ap;
170 int server;
172 gss_cred_id_t tmp_cred_handle;
174 if (server) {
175 str_data[3] = TELQUAL_REPLY;
176 gethostname(lhostname, sizeof(lhostname));
177 snprintf (targ_printable, sizeof(targ_printable),
178 "SERVICE:rcmd@%s", lhostname);
179 input_name_buffer.length = strlen(targ_printable);
180 input_name_buffer.value = targ_printable;
181 major_status = gss_import_name(&status,
182 &input_name_buffer,
183 GSS_C_NULL_OID,
184 &desired_targname);
185 major_status = gss_acquire_cred(&status,
186 desired_targname,
188 GSS_C_NULL_OID_SET,
189 GSS_C_ACCEPT,
190 &tmp_cred_handle,
191 &actual_mechs,
192 &lifetime_rec);
193 if (major_status != GSS_S_COMPLETE) return(0);
194 } else {
195 str_data[3] = TELQUAL_IS;
197 return(1);
201 spx_send(ap)
202 Authenticator *ap;
204 des_cblock enckey;
205 int r;
207 gss_OID actual_mech_type, output_name_type;
208 int msg_ctx = 0, new_status, status;
209 int req_flags = 0, ret_flags, lifetime_rec, major_status;
210 gss_buffer_desc output_token, input_token, input_name_buffer;
211 gss_buffer_desc output_name_buffer, status_string;
212 gss_name_t desired_targname;
213 gss_channel_bindings input_chan_bindings;
214 char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
215 int from_addr=0, to_addr=0, myhostlen, j;
216 int deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0;
217 char *address;
219 printf("[ Trying SPX ... ]\r\n");
220 snprintf (targ_printable, sizeof(targ_printable),
221 "SERVICE:rcmd@%s", RemoteHostName);
223 input_name_buffer.length = strlen(targ_printable);
224 input_name_buffer.value = targ_printable;
226 if (!UserNameRequested) {
227 return(0);
230 major_status = gss_import_name(&status,
231 &input_name_buffer,
232 GSS_C_NULL_OID,
233 &desired_targname);
236 major_status = gss_display_name(&status,
237 desired_targname,
238 &output_name_buffer,
239 &output_name_type);
241 printf("target is '%s'\n", output_name_buffer.value); fflush(stdout);
243 major_status = gss_release_buffer(&status, &output_name_buffer);
245 input_chan_bindings = (gss_channel_bindings)
246 malloc(sizeof(gss_channel_bindings_desc));
248 input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
249 input_chan_bindings->initiator_address.length = 4;
250 address = (char *) malloc(4);
251 input_chan_bindings->initiator_address.value = (char *) address;
252 address[0] = ((from_addr & 0xff000000) >> 24);
253 address[1] = ((from_addr & 0xff0000) >> 16);
254 address[2] = ((from_addr & 0xff00) >> 8);
255 address[3] = (from_addr & 0xff);
256 input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
257 input_chan_bindings->acceptor_address.length = 4;
258 address = (char *) malloc(4);
259 input_chan_bindings->acceptor_address.value = (char *) address;
260 address[0] = ((to_addr & 0xff000000) >> 24);
261 address[1] = ((to_addr & 0xff0000) >> 16);
262 address[2] = ((to_addr & 0xff00) >> 8);
263 address[3] = (to_addr & 0xff);
264 input_chan_bindings->application_data.length = 0;
266 req_flags = 0;
267 if (deleg_flag) req_flags = req_flags | 1;
268 if (mutual_flag) req_flags = req_flags | 2;
269 if (replay_flag) req_flags = req_flags | 4;
270 if (seq_flag) req_flags = req_flags | 8;
272 major_status = gss_init_sec_context(&status, /* minor status */
273 GSS_C_NO_CREDENTIAL, /* cred handle */
274 &actual_ctxhandle, /* ctx handle */
275 desired_targname, /* target name */
276 GSS_C_NULL_OID, /* mech type */
277 req_flags, /* req flags */
278 0, /* time req */
279 input_chan_bindings, /* chan binding */
280 GSS_C_NO_BUFFER, /* input token */
281 &actual_mech_type, /* actual mech */
282 &output_token, /* output token */
283 &ret_flags, /* ret flags */
284 &lifetime_rec); /* time rec */
286 if ((major_status != GSS_S_COMPLETE) &&
287 (major_status != GSS_S_CONTINUE_NEEDED)) {
288 gss_display_status(&new_status,
289 status,
290 GSS_C_MECH_CODE,
291 GSS_C_NULL_OID,
292 &msg_ctx,
293 &status_string);
294 printf("%s\n", status_string.value);
295 return(0);
298 if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
299 return(0);
302 if (!Data(ap, SPX_AUTH, output_token.value, output_token.length)) {
303 return(0);
306 return(1);
309 void
310 spx_is(ap, data, cnt)
311 Authenticator *ap;
312 unsigned char *data;
313 int cnt;
315 Session_Key skey;
316 des_cblock datablock;
317 int r;
319 if (cnt-- < 1)
320 return;
321 switch (*data++) {
322 case SPX_AUTH:
323 input_token.length = cnt;
324 input_token.value = (char *) data;
326 gethostname(lhostname, sizeof(lhostname));
328 snprintf(targ_printable, sizeof(targ_printable),
329 "SERVICE:rcmd@%s", lhostname);
331 input_name_buffer.length = strlen(targ_printable);
332 input_name_buffer.value = targ_printable;
334 major_status = gss_import_name(&status,
335 &input_name_buffer,
336 GSS_C_NULL_OID,
337 &desired_targname);
339 major_status = gss_acquire_cred(&status,
340 desired_targname,
342 GSS_C_NULL_OID_SET,
343 GSS_C_ACCEPT,
344 &gss_cred_handle,
345 &actual_mechs,
346 &lifetime_rec);
348 major_status = gss_release_name(&status, desired_targname);
350 input_chan_bindings = (gss_channel_bindings)
351 malloc(sizeof(gss_channel_bindings_desc));
353 input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
354 input_chan_bindings->initiator_address.length = 4;
355 address = (char *) malloc(4);
356 input_chan_bindings->initiator_address.value = (char *) address;
357 address[0] = ((from_addr & 0xff000000) >> 24);
358 address[1] = ((from_addr & 0xff0000) >> 16);
359 address[2] = ((from_addr & 0xff00) >> 8);
360 address[3] = (from_addr & 0xff);
361 input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
362 input_chan_bindings->acceptor_address.length = 4;
363 address = (char *) malloc(4);
364 input_chan_bindings->acceptor_address.value = (char *) address;
365 address[0] = ((to_addr & 0xff000000) >> 24);
366 address[1] = ((to_addr & 0xff0000) >> 16);
367 address[2] = ((to_addr & 0xff00) >> 8);
368 address[3] = (to_addr & 0xff);
369 input_chan_bindings->application_data.length = 0;
371 major_status = gss_accept_sec_context(&status,
372 &context_handle,
373 gss_cred_handle,
374 &input_token,
375 input_chan_bindings,
376 &src_name,
377 &actual_mech_type,
378 &output_token,
379 &ret_flags,
380 &lifetime_rec,
381 &gss_delegated_cred_handle);
384 if (major_status != GSS_S_COMPLETE) {
386 major_status = gss_display_name(&status,
387 src_name,
388 &fullname_buffer,
389 &fullname_type);
390 Data(ap, SPX_REJECT, "auth failed", -1);
391 auth_finished(ap, AUTH_REJECT);
392 return;
395 major_status = gss_display_name(&status,
396 src_name,
397 &fullname_buffer,
398 &fullname_type);
401 Data(ap, SPX_ACCEPT, output_token.value, output_token.length);
402 auth_finished(ap, AUTH_USER);
403 break;
405 default:
406 Data(ap, SPX_REJECT, 0, 0);
407 break;
412 void
413 spx_reply(ap, data, cnt)
414 Authenticator *ap;
415 unsigned char *data;
416 int cnt;
418 Session_Key skey;
420 if (cnt-- < 1)
421 return;
422 switch (*data++) {
423 case SPX_REJECT:
424 if (cnt > 0) {
425 printf("[ SPX refuses authentication because %.*s ]\r\n",
426 cnt, data);
427 } else
428 printf("[ SPX refuses authentication ]\r\n");
429 auth_send_retry();
430 return;
431 case SPX_ACCEPT:
432 printf("[ SPX accepts you ]\r\n");
433 if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
435 * Send over the encrypted challenge.
437 input_token.value = (char *) data;
438 input_token.length = cnt;
440 major_status = gss_init_sec_context(&status, /* minor stat */
441 GSS_C_NO_CREDENTIAL, /* cred handle */
442 &actual_ctxhandle, /* ctx handle */
443 desired_targname, /* target name */
444 GSS_C_NULL_OID, /* mech type */
445 req_flags, /* req flags */
446 0, /* time req */
447 input_chan_bindings, /* chan binding */
448 &input_token, /* input token */
449 &actual_mech_type, /* actual mech */
450 &output_token, /* output token */
451 &ret_flags, /* ret flags */
452 &lifetime_rec); /* time rec */
454 if (major_status != GSS_S_COMPLETE) {
455 gss_display_status(&new_status,
456 status,
457 GSS_C_MECH_CODE,
458 GSS_C_NULL_OID,
459 &msg_ctx,
460 &status_string);
461 printf("[ SPX mutual response fails ... '%s' ]\r\n",
462 status_string.value);
463 auth_send_retry();
464 return;
467 auth_finished(ap, AUTH_USER);
468 return;
470 default:
471 return;
476 spx_status(ap, name, name_sz, level)
477 Authenticator *ap;
478 char *name;
479 size_t name_sz;
480 int level;
483 gss_buffer_desc fullname_buffer, acl_file_buffer;
484 gss_OID fullname_type;
485 char acl_file[160], fullname[160];
486 int major_status, status = 0;
487 struct passwd *pwd;
490 * hard code fullname to
491 * "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
492 * and acl_file to "~kannan/.sphinx"
495 pwd = k_getpwnam(UserNameRequested);
496 if (pwd == NULL) {
497 return(AUTH_USER); /* not authenticated */
500 snprintf (acl_file, sizeof(acl_file),
501 "%s/.sphinx", pwd->pw_dir);
503 acl_file_buffer.value = acl_file;
504 acl_file_buffer.length = strlen(acl_file);
506 major_status = gss_display_name(&status,
507 src_name,
508 &fullname_buffer,
509 &fullname_type);
511 if (level < AUTH_USER)
512 return(level);
514 major_status = gss__check_acl(&status, &fullname_buffer,
515 &acl_file_buffer);
517 if (major_status == GSS_S_COMPLETE) {
518 strlcpy(name, UserNameRequested, name_sz);
519 return(AUTH_VALID);
520 } else {
521 return(AUTH_USER);
526 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
527 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
529 void
530 spx_printsub(data, cnt, buf, buflen)
531 unsigned char *data, *buf;
532 int cnt, buflen;
534 int i;
536 buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
537 buflen -= 1;
539 switch(data[3]) {
540 case SPX_REJECT: /* Rejected (reason might follow) */
541 strlcpy((char *)buf, " REJECT ", buflen);
542 goto common;
544 case SPX_ACCEPT: /* Accepted (name might follow) */
545 strlcpy((char *)buf, " ACCEPT ", buflen);
546 common:
547 BUMP(buf, buflen);
548 if (cnt <= 4)
549 break;
550 ADDC(buf, buflen, '"');
551 for (i = 4; i < cnt; i++)
552 ADDC(buf, buflen, data[i]);
553 ADDC(buf, buflen, '"');
554 ADDC(buf, buflen, '\0');
555 break;
557 case SPX_AUTH: /* Authentication data follows */
558 strlcpy((char *)buf, " AUTH", buflen);
559 goto common2;
561 default:
562 snprintf(buf, buflen, " %d (unknown)", data[3]);
563 common2:
564 BUMP(buf, buflen);
565 for (i = 4; i < cnt; i++) {
566 snprintf(buf, buflen, " %d", data[i]);
567 BUMP(buf, buflen);
569 break;
573 #endif
575 #ifdef notdef
577 prkey(msg, key)
578 char *msg;
579 unsigned char *key;
581 int i;
582 printf("%s:", msg);
583 for (i = 0; i < 8; i++)
584 printf(" %3d", key[i]);
585 printf("\r\n");
587 #endif