*** empty log message ***
authorJohn Kohl <jtkohl@mit.edu>
Fri, 6 Apr 1990 13:27:24 +0000 (13:27 +0000)
committerJohn Kohl <jtkohl@mit.edu>
Fri, 6 Apr 1990 13:27:24 +0000 (13:27 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@465 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/send_tgs.c [new file with mode: 0644]

diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c
new file mode 100644 (file)
index 0000000..9e4bf95
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ * krb5_send_tgs()
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_send_tgs_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+
+#include <stdio.h>
+#include <krb5/libos-proto.h>
+#include <krb5/ext-proto.h>
+/*
+ Sends a request to the TGS and waits for a response.
+ options is used for the options in the KRB_TGS_REQ.
+ timestruct values are used for from, till, rtime " " "
+ etype is used for etype " " "
+ sumtype is used for the checksum in the AP_REQ in the KRB_TGS_REQ
+ sname is used for sname " " "
+ addrs, if non-NULL, is used for addresses " " "
+ authorization_dat, if non-NULL, is used for authorization_dat " " "
+ second_ticket, if required by options, is used for the 2nd ticket in the req.
+ usecred is used for the ticket & session key in the KRB_AP_REQ header " " "
+ (the KDC realm is extracted from usecred->server's realm)
+ The response is placed into *rep.
+ rep->response.data is set to point at allocated storage which should be
+ freed by the caller when finished.
+
+ returns system errors
+ */
+krb5_error_code
+krb5_send_tgs(DECLARG(krb5_flags, kdcoptions),
+             DECLARG(krb5_ticket_times *,timestruct),
+             DECLARG(krb5_enctype, etype),
+             DECLARG(krb5_cksumtype, sumtype),
+             DECLARG(krb5_principal, sname),
+             DECLARG(krb5_address **, addrs),
+             DECLARG(krb5_authdata **,authorization_data),
+             DECLARG(krb5_data *,second_ticket),
+             DECLARG(krb5_creds *,usecred),
+             DECLARG(krb5_response *,rep))
+OLDDECLARG(krb5_flags, kdcoptions)
+OLDDECLARG(krb5_ticket_times *,timestruct)
+OLDDECLARG(krb5_enctype, etype)
+OLDDECLARG(krb5_cksumtype, sumtype)
+OLDDECLARG(krb5_principal, sname)
+OLDDECLARG(krb5_address **, addrs)
+OLDDECLARG(krb5_authdata **,authorization_data)
+OLDDECLARG(krb5_data *,second_ticket)
+OLDDECLARG(krb5_creds *,usecred)
+OLDDECLARG(krb5_response *,rep)
+{
+    krb5_error_code retval;
+    krb5_tgs_req tgsreq;
+    krb5_real_tgs_req realreq;
+    krb5_tgs_req_enc_part encpart;
+    krb5_checksum ap_checksum;
+    krb5_data *scratch;
+    krb5_ticket *sec_ticket = 0;
+
+    bzero((char *)&realreq, sizeof(realreq));
+
+    realreq.kdc_options = kdcoptions;
+    realreq.from = timestruct->starttime;
+    realreq.till = timestruct->endtime;
+    realreq.rtime = timestruct->renew_till;
+    
+    if (retval = krb5_timeofday(&realreq.ctime))
+       return(retval);
+    realreq.etype = etype;
+    realreq.server = sname;
+    realreq.addresses = addrs;
+
+    encpart.authorization_data = authorization_data;
+    if (second_ticket) {
+       if (retval = krb5_decode_ticket(second_ticket, &sec_ticket))
+           return retval;
+       encpart.second_ticket = sec_ticket;
+    } else
+       encpart.second_ticket = 0;
+
+    realreq.enc_part2 = &encpart;
+
+    retval = encode_krb5_real_tgs_req(&realreq, &scratch);
+    if (sec_ticket)
+       krb5_free_ticket(sec_ticket);
+    if (retval)
+       return(retval);
+
+    /* xxx choose a checksum type */
+    if (retval = (*(krb5_cksumarray[sumtype]->
+                   sum_func))(scratch->data,
+                              0, /* XXX? */
+                              (krb5_pointer) usecred->keyblock.contents,
+                              scratch->length,
+                              usecred->keyblock.length,
+                              &ap_checksum)) {
+       krb5_free_data(scratch);
+       return retval;
+    }
+    tgsreq.tgs_request = *scratch;
+    xfree(scratch);
+
+#define cleanup() {(void) free((char *)tgsreq.tgs_request.data); \
+                  (void) free((char *)ap_checksum.contents);}
+    /*
+     * Now get an ap_req.
+     */
+    if (retval = krb5_mk_req_extended (0L /* no ap options */,
+                                      &ap_checksum,
+                                      0, /* don't need times */
+                                      0L, /* don't need kdc_options for this */
+                                      0, /* XXX no ccache */
+                                      usecred,
+                                      &tgsreq.header)) {
+       cleanup();
+       return retval;
+    }
+    /* now the TGS_REQ is assembled in tgsreq */
+    if (retval = encode_krb5_tgs_req(&tgsreq, &scratch)) {
+       cleanup();
+       return(retval);
+    }
+#undef cleanup
+#define cleanup() {(void) free(tgsreq.header.data); \
+                  (void) free(tgsreq.tgs_request.data);}
+
+    /* now send request & get response from KDC */
+    retval = krb5_sendto_kdc(scratch, krb5_princ_realm(sname),
+                            &rep->response);
+    krb5_free_data(scratch);
+    cleanup();
+    if (retval) {
+       return retval;
+    }
+#undef cleanup
+    /* here we use some knowledge of ASN.1 encodings */
+    /* first byte is the identifier octet.  KRB_KDC_REP is APPLICATION 1,
+       KRB_ERROR is application 2 */
+    /* allow either constructed or primitive encoding, so check for bit 6
+       set or reset */
+    if (rep->response.data[0] == 0x61 ||
+       rep->response.data[0] == 0x21) {
+       /* it's a KDC_REP--assume TGS_REP */
+       rep->message_type = KRB5_TGS_REP;
+    } else /* assume it's an error */
+       rep->message_type = KRB5_ERROR;
+    return 0;
+}