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("$Heimdal: spx.c 22071 2007-11-14 20:04:50Z lha $"
41 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
44 * "Digital Equipment Corporation authorizes the reproduction,
45 * distribution and modification of this software subject to the following
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>
76 #ifdef HAVE_ARPA_TELNET_H
77 #include <arpa/telnet.h>
80 #include "gssapi_defs.h"
93 extern auth_debug_mode
;
95 static unsigned char str_data
[1024] = { IAC
, SB
, TELOPT_AUTHENTICATION
, 0,
97 static unsigned char str_name
[1024] = { IAC
, SB
, TELOPT_AUTHENTICATION
,
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;
124 gss_buffer_desc fullname_buffer
;
125 gss_OID fullname_type
;
126 gss_cred_id_t gss_delegated_cred_handle
;
128 /*******************************************************************/
139 unsigned char *p
= str_data
+ 4;
140 unsigned char *cd
= (unsigned char *)d
;
143 c
= strlen((char *)cd
);
146 printf("%s:%d: [%d] (%d)",
147 str_data
[3] == TELQUAL_IS
? ">>>IS" : ">>>REPLY",
157 if ((*p
++ = *cd
++) == IAC
)
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
));
172 gss_cred_id_t tmp_cred_handle
;
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
,
185 major_status
= gss_acquire_cred(&status
,
193 if (major_status
!= GSS_S_COMPLETE
) return(0);
195 str_data
[3] = TELQUAL_IS
;
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;
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
) {
230 major_status
= gss_import_name(&status
,
236 major_status
= gss_display_name(&status
,
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;
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 */
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
,
294 printf("%s\n", status_string
.value
);
298 if (!auth_sendname(UserNameRequested
, strlen(UserNameRequested
))) {
302 if (!Data(ap
, SPX_AUTH
, output_token
.value
, output_token
.length
)) {
310 spx_is(ap
, data
, cnt
)
316 des_cblock datablock
;
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
,
339 major_status
= gss_acquire_cred(&status
,
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
,
381 &gss_delegated_cred_handle
);
384 if (major_status
!= GSS_S_COMPLETE
) {
386 major_status
= gss_display_name(&status
,
390 Data(ap
, SPX_REJECT
, "auth failed", -1);
391 auth_finished(ap
, AUTH_REJECT
);
395 major_status
= gss_display_name(&status
,
401 Data(ap
, SPX_ACCEPT
, output_token
.value
, output_token
.length
);
402 auth_finished(ap
, AUTH_USER
);
406 Data(ap
, SPX_REJECT
, 0, 0);
413 spx_reply(ap
, data
, cnt
)
425 printf("[ SPX refuses authentication because %.*s ]\r\n",
428 printf("[ SPX refuses authentication ]\r\n");
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 */
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
,
461 printf("[ SPX mutual response fails ... '%s' ]\r\n",
462 status_string
.value
);
467 auth_finished(ap
, AUTH_USER
);
476 spx_status(ap
, name
, name_sz
, 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;
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
);
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
,
511 if (level
< AUTH_USER
)
514 major_status
= gss__check_acl(&status
, &fullname_buffer
,
517 if (major_status
== GSS_S_COMPLETE
) {
518 strlcpy(name
, UserNameRequested
, name_sz
);
526 #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
527 #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
530 spx_printsub(data
, cnt
, buf
, buflen
)
531 unsigned char *data
, *buf
;
536 buf
[buflen
-1] = '\0'; /* make sure it's NULL terminated */
540 case SPX_REJECT
: /* Rejected (reason might follow) */
541 strlcpy((char *)buf
, " REJECT ", buflen
);
544 case SPX_ACCEPT
: /* Accepted (name might follow) */
545 strlcpy((char *)buf
, " ACCEPT ", buflen
);
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');
557 case SPX_AUTH
: /* Authentication data follows */
558 strlcpy((char *)buf
, " AUTH", buflen
);
562 snprintf(buf
, buflen
, " %d (unknown)", data
[3]);
565 for (i
= 4; i
< cnt
; i
++) {
566 snprintf(buf
, buflen
, " %d", data
[i
]);
583 for (i
= 0; i
< 8; i
++)
584 printf(" %3d", key
[i
]);