Add ticketlife, renewlife.
[shishi.git] / lib / tgs.c
blob571a5b665b660c3c52e7c9f15ff2ff9dc51d6c77
1 /* tgs.c High level client TGS functions
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* TODO: make shishi_tgs_realmsname() take real sname pointer
23 array. */
25 #include "internal.h"
27 struct Shishi_tgs
29 Shishi *handle;
30 Shishi_asn1 tgsreq;
31 Shishi_tkt *tgtkt;
32 Shishi_ap *ap;
33 Shishi_asn1 tgsrep;
34 Shishi_asn1 krberror;
35 Shishi_tkt *tkt;
38 /**
39 * shishi_tgs:
40 * @handle: shishi handle as allocated by shishi_init().
41 * @tgs: holds pointer to newly allocate Shishi_tgs structure.
43 * Allocate a new TGS exchange variable.
45 * Return value: Returns SHISHI_OK iff successful.
46 **/
47 int
48 shishi_tgs (Shishi * handle, Shishi_tgs ** tgs)
50 Shishi_tgs *ltgs;
51 int res;
53 *tgs = malloc (sizeof (**tgs));
54 if (*tgs == NULL)
55 return SHISHI_MALLOC_ERROR;
56 ltgs = *tgs;
57 memset (ltgs, 0, sizeof (*ltgs));
59 ltgs->handle = handle;
61 ltgs->tgsreq = shishi_tgsreq (handle);
62 if (ltgs->tgsreq == NULL)
64 shishi_error_printf (handle, "Could not create TGS-REQ: %s\n",
65 shishi_strerror_details (handle));
66 return SHISHI_ASN1_ERROR;
69 ltgs->tgsrep = shishi_tgsrep (handle);
70 if (ltgs->tgsreq == NULL)
72 shishi_error_printf (handle, "Could not create TGS-REP: %s\n",
73 shishi_strerror_details (handle));
74 return SHISHI_ASN1_ERROR;
77 ltgs->krberror = shishi_krberror (handle);
78 if (ltgs->krberror == NULL)
80 shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n",
81 shishi_strerror_details (handle));
82 return SHISHI_ASN1_ERROR;
85 res = shishi_ap (handle, &ltgs->ap);
86 if (res != SHISHI_OK)
87 return res;
89 return SHISHI_OK;
92 /**
93 * shishi_tgs_tgtkt:
94 * @tgs: structure that holds information about TGS exchange
96 * Return value: Returns the ticket-granting-ticket used in the TGS
97 * exchange, or NULL if not yet set or an error occured.
98 **/
99 Shishi_tkt *
100 shishi_tgs_tgtkt (Shishi_tgs * tgs)
102 return tgs->tgtkt;
106 * shishi_tgs_tgtkt_set:
107 * @tgs: structure that holds information about TGS exchange
108 * @tgtkt: ticket granting ticket to store in TGS.
110 * Set the Ticket in the AP exchange.
112 void
113 shishi_tgs_tgtkt_set (Shishi_tgs * tgs, Shishi_tkt * tgtkt)
115 tgs->tgtkt = tgtkt;
119 * shishi_tgs_ap:
120 * @tgs: structure that holds information about TGS exchange
122 * Return value: Returns the AP exchange (part of TGS-REQ) from the
123 * TGS exchange, or NULL if not yet set or an error
124 * occured.
126 Shishi_ap *
127 shishi_tgs_ap (Shishi_tgs * tgs)
129 return tgs->ap;
133 * shishi_tgs_req:
134 * @tgs: structure that holds information about TGS exchange
136 * Return value: Returns the generated TGS-REQ from the TGS exchange,
137 * or NULL if not yet set or an error occured.
139 Shishi_asn1
140 shishi_tgs_req (Shishi_tgs * tgs)
142 return tgs->tgsreq;
146 * shishi_tgs_req_build:
147 * @tgs: structure that holds information about TGS exchange
149 * Checksum data in authenticator and add ticket and authenticator to
150 * TGS-REQ.
152 * Return value: Returns SHISHI_OK iff successful.
155 shishi_tgs_req_build (Shishi_tgs * tgs)
157 char rtime[BUFSIZ]; /* XXX dynamically allocate this */
158 int rtimelen;
159 int res;
160 int apoptions;
162 if (VERBOSE (tgs->handle))
163 printf ("Building TGS-REQ...\n");
165 res = shishi_kdcreq_build (tgs->handle, tgs->tgsreq);
166 if (res != SHISHI_OK)
167 return res;
169 res = shishi_apreq_options (tgs->handle, shishi_ap_req (tgs->ap),
170 &apoptions);
171 if (res != SHISHI_OK)
173 shishi_error_printf (tgs->handle,
174 "Could not get AP-REQ AP-Options: %s\n",
175 shishi_strerror (res));
176 return res;
179 res = shishi_ap_set_tktoptionsasn1usage
180 (tgs->ap, tgs->tgtkt, apoptions, tgs->tgsreq, "req-body",
181 SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR_CKSUM,
182 SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR);
183 if (res == SHISHI_OK)
184 res = shishi_ap_req_build (tgs->ap);
185 if (res != SHISHI_OK)
187 shishi_error_printf (tgs->handle, "Could not make AP-REQ: %s\n",
188 shishi_strerror (res));
189 return res;
193 if (VERBOSE (tgs->handle))
194 printf ("Got AP-REQ...\n");
196 if (VERBOSEASN1 (tgs->handle))
197 shishi_apreq_print (tgs->handle, stdout, shishi_ap_req (tgs->ap));
199 res = shishi_kdcreq_add_padata_tgs (tgs->handle, tgs->tgsreq,
200 shishi_ap_req (tgs->ap));
201 if (res != SHISHI_OK)
203 shishi_error_printf (tgs->handle, "Could not add AP-REQ to TGS: %s\n",
204 shishi_strerror (res));
205 return res;
208 return SHISHI_OK;
212 * shishi_tgs_rep:
213 * @tgs: structure that holds information about TGS exchange
215 * Return value: Returns the received TGS-REP from the TGS exchange,
216 * or NULL if not yet set or an error occured.
218 Shishi_asn1
219 shishi_tgs_rep (Shishi_tgs * tgs)
221 return tgs->tgsrep;
225 * shishi_tgs_rep_process:
226 * @tgs: structure that holds information about TGS exchange
228 * Process new TGS-REP and set ticket. The key to decrypt the TGS-REP
229 * is taken from the EncKDCRepPart of the TGS tgticket.
231 * Return value: Returns SHISHI_OK iff successful.
234 shishi_tgs_rep_process (Shishi_tgs * tgs)
236 Shishi_asn1 kdcreppart, ticket;
237 int res;
239 if (VERBOSE (tgs->handle))
240 printf ("Processing TGS-REQ and TGS-REP...\n");
242 res = shishi_tgs_process (tgs->handle, tgs->tgsreq, tgs->tgsrep,
243 shishi_tkt_enckdcreppart (tgs->tgtkt),
244 &kdcreppart);
245 if (res != SHISHI_OK)
247 shishi_error_printf (tgs->handle, "Could not process TGS: %s",
248 shishi_strerror (res));
249 return res;
252 if (VERBOSE (tgs->handle))
253 printf ("Got EncKDCRepPart...\n");
255 if (VERBOSEASN1 (tgs->handle))
256 shishi_enckdcreppart_print (tgs->handle, stdout, kdcreppart);
258 res = shishi_kdcrep_get_ticket (tgs->handle, tgs->tgsrep, &ticket);
259 if (res != SHISHI_OK)
261 shishi_error_printf (tgs->handle,
262 "Could not extract ticket from TGS-REP: %s",
263 shishi_strerror (res));
264 return res;
267 if (VERBOSE (tgs->handle))
268 printf ("Got Ticket...\n");
270 if (VERBOSEASN1 (tgs->handle))
271 shishi_ticket_print (tgs->handle, stdout, ticket);
273 tgs->tkt = shishi_tkt2 (tgs->handle, ticket, kdcreppart, tgs->tgsrep);
274 if (tgs->tkt == NULL)
276 shishi_error_printf (tgs->handle, "Could not create ticket");
277 return SHISHI_MALLOC_ERROR;
280 return SHISHI_OK;
284 * shishi_tgs_krberror:
285 * @tgs: structure that holds information about TGS exchange
287 * Return value: Returns the received TGS-REP from the TGS exchange,
288 * or NULL if not yet set or an error occured.
290 Shishi_asn1
291 shishi_tgs_krberror (Shishi_tgs * tgs)
293 return tgs->krberror;
297 * shishi_tgs_tkt:
298 * @tgs: structure that holds information about TGS exchange
300 * Return value: Returns the newly aquired ticket from the TGS
301 * exchange, or NULL if not yet set or an error occured.
303 Shishi_tkt *
304 shishi_tgs_tkt (Shishi_tgs * tgs)
306 return tgs->tkt;
310 * shishi_tgs_tkt_set:
311 * @tgs: structure that holds information about TGS exchange
312 * @tkt: ticket to store in TGS.
314 * Set the Ticket in the AP exchange.
316 void
317 shishi_tgs_tkt_set (Shishi_tgs * tgs, Shishi_tkt * tkt)
319 tgs->tkt = tkt;
323 * shishi_tgs_sendrecv:
324 * @tgs: structure that holds information about TGS exchange
326 * Send TGS-REQ and receive TGS-REP or KRB-ERROR. This is the
327 * subsequent authentication, usually used to acquire server tickets.
329 * Return value: Returns SHISHI_OK iff successful.
332 shishi_tgs_sendrecv (Shishi_tgs * tgs)
334 int res;
336 if (VERBOSE (tgs->handle))
337 printf ("Sending TGS-REQ...\n");
339 if (VERBOSEASN1 (tgs->handle))
340 shishi_kdcreq_print (tgs->handle, stdout, tgs->tgsreq);
342 res = shishi_kdcreq_sendrecv (tgs->handle, tgs->tgsreq, &tgs->tgsrep);
343 if (res == SHISHI_GOT_KRBERROR)
345 tgs->krberror = tgs->tgsrep;
346 tgs->tgsrep = NULL;
348 if (VERBOSE (tgs->handle))
349 printf ("Received KRB-ERROR...\n");
350 if (VERBOSEASN1 (tgs->handle))
351 shishi_krberror_print (tgs->handle, stdout, tgs->krberror);
353 if (res != SHISHI_OK)
354 return res;
357 if (VERBOSE (tgs->handle))
358 printf ("Received TGS-REP...\n");
360 if (VERBOSEASN1 (tgs->handle))
361 shishi_kdcrep_print (tgs->handle, stdout, tgs->tgsrep);
363 return SHISHI_OK;
367 * shishi_tgs_set_server:
368 * @tgs: structure that holds information about TGS exchange
369 * @server: indicates the server to acquire ticket for.
371 * Set the server in the TGS-REQ.
373 * Return value: Returns SHISHI_OK iff successful.
376 shishi_tgs_set_server (Shishi_tgs * tgs, const char *server)
378 int res;
380 res = shishi_kdcreq_set_server (tgs->handle, tgs->tgsreq, server);
381 if (res != SHISHI_OK)
383 shishi_error_printf (tgs->handle,
384 "Could not set server in KDC-REQ: %s\n",
385 shishi_strerror (res));
386 return res;
389 return SHISHI_OK;
393 * shishi_tgs_set_realm:
394 * @tgs: structure that holds information about TGS exchange
395 * @realm: indicates the realm to acquire ticket for.
397 * Set the server in the TGS-REQ.
399 * Return value: Returns SHISHI_OK iff successful.
402 shishi_tgs_set_realm (Shishi_tgs * tgs, const char *realm)
404 int res;
406 res = shishi_kdcreq_set_realm (tgs->handle, tgs->tgsreq, realm);
407 if (res != SHISHI_OK)
409 shishi_error_printf (tgs->handle,
410 "Could not set realm in KDC-REQ: %s\n",
411 shishi_strerror (res));
412 return res;
415 return SHISHI_OK;
419 * shishi_tgs_set_realmserver:
420 * @tgs: structure that holds information about TGS exchange
421 * @realm: indicates the realm to acquire ticket for.
422 * @server: indicates the server to acquire ticket for.
424 * Set the realm and server in the TGS-REQ.
426 * Return value: Returns SHISHI_OK iff successful.
429 shishi_tgs_set_realmserver (Shishi_tgs * tgs,
430 const char *realm, const char *server)
432 int res;
434 res = shishi_tgs_set_server (tgs, server);
435 if (res != SHISHI_OK)
436 return res;
438 res = shishi_tgs_set_realm (tgs, realm);
439 if (res != SHISHI_OK)
440 return res;
442 return SHISHI_OK;