2
* $Id: kuam.c,v 1.4 2001/06/25 20:13:45 rufustfirefly Exp $
4
* Copyright (c) 1990,1994 Regents of The University of Michigan.
5
* All Rights Reserved. See COPYRIGHT.
10
#endif /* HAVE_CONFIG_H */
14
#include <mit-copyright.h>
23
/* use the bsd time.h struct defs for PC too! */
25
#include <sys/types.h>
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
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.
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.
53
* The format of the message sent to Kerberos is as follows:
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
70
kuam_get_in_tkt(user, instance, realm, service, sinstance, life, rpkt )
80
KTEXT pkt = &pkt_st; /* Packet to KDC */
82
KTEXT cip = &cip_st; /* Returned Ciphertext */
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 */
89
struct timeval t_local;
90
u_int32_t rep_err_code;
93
/* BUILD REQUEST PACKET */
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;
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);
109
(void) gettimeofday(&t_local,(struct timezone *) 0);
111
memcpy((pkt->dat+pkt->length), &(t_local.tv_sec), 4);
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);
122
/* SEND THE REQUEST AND RECEIVE THE RETURN PACKET */
124
if (kerror = send_to_kdc(pkt, rpkt, realm)) return(kerror);
126
/* check packet version of the returned packet */
127
if (pkt_version(rpkt) != KRB_PROT_VERSION)
130
/* Check byte order */
131
msg_byte_order = pkt_msg_type(rpkt) & 1;
133
if (msg_byte_order != HOST_BYTE_ORDER) {
137
switch (pkt_msg_type(rpkt) & ~1) {
138
case AUTH_MSG_KDC_REPLY:
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);
151
kuam_set_in_tkt( user, instance, realm, service, sinstance, ptr)
152
char *user, *instance, *realm, *service, *sinstance, *ptr;
156
struct timeval t_local;
157
int lifetime, kvno, kerror;
160
char s_name[ SNAME_SZ ], s_instance[ INST_SZ ];
161
char rlm[ REALM_SZ ];
163
/* extract session key */
167
/* extract server's name */
168
(void) strcpy(s_name,ptr);
169
ptr += strlen(s_name) + 1;
171
/* extract server's instance */
172
(void) strcpy(s_instance,ptr);
173
ptr += strlen(s_instance) + 1;
175
/* extract server's realm */
176
(void) strcpy(rlm,ptr);
177
ptr += strlen(rlm) + 1;
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];
186
/* extract ticket itself */
187
memcpy( tkt->dat, ptr, tkt->length);
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 */
194
/* check KDC time stamp */
195
memcpy(&kdc_time, ptr, 4); /* Time (coarse) */
196
if (swap_bytes) swap_u_long(kdc_time);
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
206
/* initialize ticket cache */
207
if (in_tkt(user,instance) != KSUCCESS)
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))
218
#endif /* UAM_AFSKRB */