home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / kerberosIV / krb / mk_req.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-25  |  6.9 KB  |  206 lines

  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. }
  206.