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
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.
48 shishi_tgs (Shishi
* handle
, Shishi_tgs
** tgs
)
53 *tgs
= malloc (sizeof (**tgs
));
55 return SHISHI_MALLOC_ERROR
;
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
, <gs
->ap
);
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.
100 shishi_tgs_tgtkt (Shishi_tgs
* tgs
)
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.
113 shishi_tgs_tgtkt_set (Shishi_tgs
* tgs
, Shishi_tkt
* tgtkt
)
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
127 shishi_tgs_ap (Shishi_tgs
* tgs
)
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.
140 shishi_tgs_req (Shishi_tgs
* tgs
)
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
152 * Return value: Returns SHISHI_OK iff successful.
155 shishi_tgs_req_build (Shishi_tgs
* tgs
)
157 char rtime
[BUFSIZ
]; /* XXX dynamically allocate this */
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
)
169 res
= shishi_apreq_options (tgs
->handle
, shishi_ap_req (tgs
->ap
),
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
));
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
));
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
));
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.
219 shishi_tgs_rep (Shishi_tgs
* tgs
)
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
;
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
),
245 if (res
!= SHISHI_OK
)
247 shishi_error_printf (tgs
->handle
, "Could not process TGS: %s",
248 shishi_strerror (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
));
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
;
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.
291 shishi_tgs_krberror (Shishi_tgs
* tgs
)
293 return tgs
->krberror
;
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.
304 shishi_tgs_tkt (Shishi_tgs
* tgs
)
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.
317 shishi_tgs_tkt_set (Shishi_tgs
* tgs
, Shishi_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
)
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
;
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
)
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
);
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
)
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
));
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
)
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
));
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
)
434 res
= shishi_tgs_set_server (tgs
, server
);
435 if (res
!= SHISHI_OK
)
438 res
= shishi_tgs_set_realm (tgs
, realm
);
439 if (res
!= SHISHI_OK
)