|
|
1.1 root 1: /*
2: * $Source: /usr/src/kerberosIV/krb/RCS/mk_req.c,v $
3: * $Author: kfall $
4: *
5: * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
6: * of Technology.
7: *
8: * For copying and distribution information, please see the file
9: * <mit-copyright.h>.
10: */
11:
12: #ifndef lint
13: static char *rcsid_mk_req_c =
14: "$Header: /usr/src/kerberosIV/krb/RCS/mk_req.c,v 4.18 90/06/25 20:56:56 kfall Exp $";
15: #endif /* lint */
16:
17: #include <mit-copyright.h>
18: #include <des.h>
19: #include <krb.h>
20: #include <prot.h>
21: #include <sys/time.h>
22: #include <strings.h>
23:
24: extern int krb_ap_req_debug;
25: static struct timeval tv_local = { 0, 0 };
26: static int lifetime = DEFAULT_TKT_LIFE;
27:
28: /*
29: * krb_mk_req takes a text structure in which an authenticator is to
30: * be built, the name of a service, an instance, a realm,
31: * and a checksum. It then retrieves a ticket for
32: * the desired service and creates an authenticator in the text
33: * structure passed as the first argument. krb_mk_req returns
34: * KSUCCESS on success and a Kerberos error code on failure.
35: *
36: * The peer procedure on the other end is krb_rd_req. When making
37: * any changes to this routine it is important to make corresponding
38: * changes to krb_rd_req.
39: *
40: * The authenticator consists of the following:
41: *
42: * authent->dat
43: *
44: * unsigned char KRB_PROT_VERSION protocol version no.
45: * unsigned char AUTH_MSG_APPL_REQUEST message type
46: * (least significant
47: * bit of above) HOST_BYTE_ORDER local byte ordering
48: * unsigned char kvno from ticket server's key version
49: * string realm server's realm
50: * unsigned char tl ticket length
51: * unsigned char idl request id length
52: * text ticket->dat ticket for server
53: * text req_id->dat request id
54: *
55: * The ticket information is retrieved from the ticket cache or
56: * fetched from Kerberos. The request id (called the "authenticator"
57: #ifdef NOENCRYPTION
58: * in the papers on Kerberos) contains the following:
59: #else
60: * in the papers on Kerberos) contains information encrypted in the session
61: * key for the client and ticket-granting service: {req_id}Kc,tgs
62: * Before encryption, it contains the following:
63: #endif
64: *
65: * req_id->dat
66: *
67: * string cr.pname {name, instance, and
68: * string cr.pinst realm of principal
69: * string myrealm making this request}
70: * 4 bytes checksum checksum argument given
71: * unsigned char tv_local.tf_usec time (milliseconds)
72: * 4 bytes tv_local.tv_sec time (seconds)
73: *
74: * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
75: * all rounded up to multiple of 8.
76: */
77:
78: krb_mk_req(authent,service,instance,realm,checksum)
79: register KTEXT authent; /* Place to build the authenticator */
80: char *service; /* Name of the service */
81: char *instance; /* Service instance */
82: char *realm; /* Authentication domain of service */
83: long checksum; /* Checksum of data (optional) */
84: {
85: static KTEXT_ST req_st; /* Temp storage for req id */
86: register KTEXT req_id = &req_st;
87: unsigned char *v = authent->dat; /* Prot version number */
88: unsigned char *t = (authent->dat+1); /* Message type */
89: unsigned char *kv = (authent->dat+2); /* Key version no */
90: unsigned char *tl = (authent->dat+4+strlen(realm)); /* Tkt len */
91: unsigned char *idl = (authent->dat+5+strlen(realm)); /* Reqid len */
92: CREDENTIALS cr; /* Credentials used by retr */
93: register KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
94: int retval; /* Returned by krb_get_cred */
95: static Key_schedule key_s;
96: char myrealm[REALM_SZ];
97:
98: /* The fixed parts of the authenticator */
99: *v = (unsigned char) KRB_PROT_VERSION;
100: *t = (unsigned char) AUTH_MSG_APPL_REQUEST;
101: *t |= HOST_BYTE_ORDER;
102:
103: /* Get the ticket and move it into the authenticator */
104: if (krb_ap_req_debug)
105: printf("Realm: %s\n",realm);
106: /*
107: * Determine realm of these tickets. We will send this to the
108: * KDC from which we are requesting tickets so it knows what to
109: * with our session key.
110: */
111: if ((retval = krb_get_tf_realm(TKT_FILE, myrealm)) != KSUCCESS)
112: return(retval);
113:
114: retval = krb_get_cred(service,instance,realm,&cr);
115:
116: if (retval == RET_NOTKT) {
117: if (retval = get_ad_tkt(service,instance,realm,lifetime))
118: return(retval);
119: if (retval = krb_get_cred(service,instance,realm,&cr))
120: return(retval);
121: }
122:
123: if (retval != KSUCCESS) return (retval);
124:
125: if (krb_ap_req_debug)
126: printf("%s %s %s %s %s\n", service, instance, realm,
127: cr.pname, cr.pinst);
128: *kv = (unsigned char) cr.kvno;
129: (void) strcpy((char *)(authent->dat+3),realm);
130: *tl = (unsigned char) ticket->length;
131: bcopy((char *)(ticket->dat),(char *)(authent->dat+6+strlen(realm)),
132: ticket->length);
133: authent->length = 6 + strlen(realm) + ticket->length;
134: if (krb_ap_req_debug)
135: printf("Ticket->length = %d\n",ticket->length);
136: if (krb_ap_req_debug)
137: printf("Issue date: %d\n",cr.issue_date);
138:
139: /* Build request id */
140: (void) strcpy((char *)(req_id->dat),cr.pname); /* Auth name */
141: req_id->length = strlen(cr.pname)+1;
142: /* Principal's instance */
143: (void) strcpy((char *)(req_id->dat+req_id->length),cr.pinst);
144: req_id->length += strlen(cr.pinst)+1;
145: /* Authentication domain */
146: (void) strcpy((char *)(req_id->dat+req_id->length),myrealm);
147: req_id->length += strlen(myrealm)+1;
148: /* Checksum */
149: bcopy((char *)&checksum,(char *)(req_id->dat+req_id->length),4);
150: req_id->length += 4;
151:
152: /* Fill in the times on the request id */
153: (void) gettimeofday(&tv_local,(struct timezone *) 0);
154: *(req_id->dat+(req_id->length)++) =
155: (unsigned char) tv_local.tv_usec;
156: /* Time (coarse) */
157: bcopy((char *)&(tv_local.tv_sec),
158: (char *)(req_id->dat+req_id->length), 4);
159: req_id->length += 4;
160:
161: /* Fill to a multiple of 8 bytes for DES */
162: req_id->length = ((req_id->length+7)/8)*8;
163:
164: #ifndef NOENCRYPTION
165: /* Encrypt the request ID using the session key */
166: key_sched(cr.session,key_s);
167: pcbc_encrypt((C_Block *)req_id->dat,(C_Block *)req_id->dat,
168: (long) req_id->length,key_s,cr.session,1);
169: /* clean up */
170: bzero((char *) key_s, sizeof(key_s));
171: #endif /* NOENCRYPTION */
172:
173: /* Copy it into the authenticator */
174: bcopy((char *)(req_id->dat),(char *)(authent->dat+authent->length),
175: req_id->length);
176: authent->length += req_id->length;
177: /* And set the id length */
178: *idl = (unsigned char) req_id->length;
179: /* clean up */
180: bzero((char *)req_id, sizeof(*req_id));
181:
182: if (krb_ap_req_debug)
183: printf("Authent->length = %d\n",authent->length);
184: if (krb_ap_req_debug)
185: printf("idl = %d, tl = %d\n",(int) *idl, (int) *tl);
186:
187: return(KSUCCESS);
188: }
189:
190: /*
191: * krb_set_lifetime sets the default lifetime for additional tickets
192: * obtained via krb_mk_req().
193: *
194: * It returns the previous value of the default lifetime.
195: */
196:
197: int
198: krb_set_lifetime(newval)
199: int newval;
200: {
201: int olife = lifetime;
202:
203: lifetime = newval;
204: return(olife);
205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.