• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/etc/uams/uams_krb4/
1/*
2 * $Id: kuam.c,v 1.4 2001-06-25 20:13:45 rufustfirefly Exp $
3 *
4 * Copyright (c) 1990,1994 Regents of The University of Michigan.
5 * All Rights Reserved.  See COPYRIGHT.
6 */
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif /* HAVE_CONFIG_H */
11
12#ifdef UAM_AFSKRB
13
14#include <mit-copyright.h>
15#include <krb.h>
16#include <des.h>
17#include <prot.h>
18
19#include <stdio.h>
20#include <string.h>
21#include <errno.h>
22
23/* use the bsd time.h struct defs for PC too! */
24#include <sys/time.h>
25#include <sys/types.h>
26
27int     swap_bytes;
28
29/*
30 * krb_get_in_tkt() gets a ticket for a given principal to use a given
31 * service and stores the returned ticket and session key for future
32 * use.
33 *
34 * The "user", "instance", and "realm" arguments give the identity of
35 * the client who will use the ticket.  The "service" and "sinstance"
36 * arguments give the identity of the server that the client wishes
37 * to use.  (The realm of the server is the same as the Kerberos server
38 * to whom the request is sent.)  The "life" argument indicates the
39 * desired lifetime of the ticket; the "key_proc" argument is a pointer
40 * to the routine used for getting the client's private key to decrypt
41 * the reply from Kerberos.  The "decrypt_proc" argument is a pointer
42 * to the routine used to decrypt the reply from Kerberos; and "arg"
43 * is an argument to be passed on to the "key_proc" routine.
44 *
45 * If all goes well, krb_get_in_tkt() returns INTK_OK, otherwise it
46 * returns an error code:  If an AUTH_MSG_ERR_REPLY packet is returned
47 * by Kerberos, then the error code it contains is returned.  Other
48 * error codes returned by this routine include INTK_PROT to indicate
49 * wrong protocol version, INTK_BADPW to indicate bad password (if
50 * decrypted ticket didn't make sense), INTK_ERR if the ticket was for
51 * the wrong server or the ticket store couldn't be initialized.
52 *
53 * The format of the message sent to Kerberos is as follows:
54 *
55 * Size			Variable		Field
56 * ----			--------		-----
57 *
58 * 1 byte		KRB_PROT_VERSION	protocol version number
59 * 1 byte		AUTH_MSG_KDC_REQUEST |	message type
60 *			HOST_BYTE_ORDER		local byte order in lsb
61 * string		user			client's name
62 * string		instance		client's instance
63 * string		realm			client's realm
64 * 4 bytes		tlocal.tv_sec		timestamp in seconds
65 * 1 byte		life			desired lifetime
66 * string		service			service's name
67 * string		sinstance		service's instance
68 */
69
70kuam_get_in_tkt(user, instance, realm, service, sinstance, life, rpkt )
71    char	*user;
72    char	*instance;
73    char	*realm;
74    char	*service;
75    char	*sinstance;
76    int		life;
77    KTEXT	rpkt;
78{
79    KTEXT_ST pkt_st;
80    KTEXT pkt = &pkt_st;	/* Packet to KDC */
81    KTEXT_ST cip_st;
82    KTEXT cip = &cip_st;	/* Returned Ciphertext */
83    KTEXT_ST tkt_st;
84    KTEXT tkt = &tkt_st;	/* Current ticket */
85    unsigned char *v = pkt->dat; /* Prot vers no */
86    unsigned char *t = (pkt->dat+1); /* Prot msg type */
87    int msg_byte_order;
88    int kerror;
89    struct timeval t_local;
90    u_int32_t rep_err_code;
91
92
93    /* BUILD REQUEST PACKET */
94
95    /* Set up the fixed part of the packet */
96    *v = (unsigned char) KRB_PROT_VERSION;
97    *t = (unsigned char) AUTH_MSG_KDC_REQUEST;
98    *t |= HOST_BYTE_ORDER;
99
100    /* Now for the variable info */
101    (void) strcpy((char *)(pkt->dat+2),user); /* aname */
102    pkt->length = 3 + strlen(user);
103    (void) strcpy((char *)(pkt->dat+pkt->length),
104		  instance);	/* instance */
105    pkt->length += 1 + strlen(instance);
106    (void) strcpy((char *)(pkt->dat+pkt->length),realm); /* realm */
107    pkt->length += 1 + strlen(realm);
108
109    (void) gettimeofday(&t_local,(struct timezone *) 0);
110    /* timestamp */
111    memcpy((pkt->dat+pkt->length), &(t_local.tv_sec), 4);
112    pkt->length += 4;
113
114    *(pkt->dat+(pkt->length)++) = (char) life;
115    (void) strcpy((char *)(pkt->dat+pkt->length),service);
116    pkt->length += 1 + strlen(service);
117    (void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
118    pkt->length += 1 + strlen(sinstance);
119
120    rpkt->length = 0;
121
122    /* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
123
124    if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
125
126    /* check packet version of the returned packet */
127    if (pkt_version(rpkt) != KRB_PROT_VERSION)
128        return(INTK_PROT);
129
130    /* Check byte order */
131    msg_byte_order = pkt_msg_type(rpkt) & 1;
132    swap_bytes = 0;
133    if (msg_byte_order != HOST_BYTE_ORDER) {
134        swap_bytes++;
135    }
136
137    switch (pkt_msg_type(rpkt) & ~1) {
138    case AUTH_MSG_KDC_REPLY:
139        break;
140    case AUTH_MSG_ERR_REPLY:
141        memcpy(&rep_err_code,pkt_err_code(rpkt),4);
142        if (swap_bytes) swap_u_long(rep_err_code);
143        return((int)rep_err_code);
144    default:
145        return(INTK_PROT);
146    }
147
148    return( INTK_OK );
149}
150
151kuam_set_in_tkt( user, instance, realm, service, sinstance, ptr)
152    char	*user, *instance, *realm, *service, *sinstance, *ptr;
153{
154    KTEXT_ST		tkt_st;
155    KTEXT		tkt = &tkt_st;
156    struct timeval	t_local;
157    int			lifetime, kvno, kerror;
158    int32_t		kdc_time;
159    C_Block		ses;
160    char		s_name[ SNAME_SZ ], s_instance[ INST_SZ ];
161    char		rlm[ REALM_SZ ];
162
163    /* extract session key */
164    memcpy(ses, ptr, 8);
165    ptr += 8;
166
167    /* extract server's name */
168    (void) strcpy(s_name,ptr);
169    ptr += strlen(s_name) + 1;
170
171    /* extract server's instance */
172    (void) strcpy(s_instance,ptr);
173    ptr += strlen(s_instance) + 1;
174
175    /* extract server's realm */
176    (void) strcpy(rlm,ptr);
177    ptr += strlen(rlm) + 1;
178
179    /* extract ticket lifetime, server key version, ticket length */
180    /* be sure to avoid sign extension on lifetime! */
181    lifetime = (unsigned char) ptr[0];
182    kvno = (unsigned char) ptr[1];
183    tkt->length = (unsigned char) ptr[2];
184    ptr += 3;
185
186    /* extract ticket itself */
187    memcpy( tkt->dat, ptr, tkt->length);
188    ptr += tkt->length;
189
190    if (strcmp(s_name, service) || strcmp(s_instance, sinstance) ||
191        strcmp(rlm, realm))	/* not what we asked for */
192	return(INTK_ERR);	/* we need a better code here XXX */
193
194    /* check KDC time stamp */
195    memcpy(&kdc_time, ptr, 4); /* Time (coarse) */
196    if (swap_bytes) swap_u_long(kdc_time);
197
198    ptr += 4;
199
200    (void) gettimeofday(&t_local,(struct timezone *) 0);
201    if (abs((int)(t_local.tv_sec - kdc_time)) > CLOCK_SKEW) {
202        return(RD_AP_TIME);		/* XXX should probably be better
203					   code */
204    }
205
206    /* initialize ticket cache */
207    if (in_tkt(user,instance) != KSUCCESS)
208	return(INTK_ERR);
209
210    /* stash ticket, session key, etc. for future use */
211    if (kerror = save_credentials(s_name, s_instance, rlm, ses,
212				  lifetime, kvno, tkt, t_local.tv_sec))
213	return(kerror);
214
215    return(INTK_OK);
216}
217
218#endif /* UAM_AFSKRB */
219