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 */