ckuath.c
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:270k
源码类别:

通讯/手机编程

开发平台:

Windows_Unix

  1. /*
  2.  * Function: Callback to decrypt a block of characters
  3.  *
  4.  * Parameters:
  5.  *  out - return as pointer to converted buffer.
  6.  *
  7.  *  in - the buffer to convert
  8.  *
  9.  * Returns: number of characters converted.
  10.  */
  11. int
  12. #ifdef CK_ANSIC
  13. auth_decrypt(struct kstream_data_block *out,
  14.      struct kstream_data_block *in)
  15. #else
  16. auth_decrypt(out,in)
  17.     struct kstream_data_block *out; struct kstream_data_block *in;
  18. #endif
  19. {
  20.     out->ptr = in->ptr;
  21.     out->length = in->length;
  22.     return(out->length);
  23. }
  24. void
  25. auth_finished(result) int result; {
  26.     extern char uidbuf[];
  27.     extern int sstelnet;
  28.     validUser = result;
  29.     switch (result) {
  30.     case AUTH_REJECT:           /* Rejected */
  31.         if (sstelnet)
  32.             uidbuf[0] = '';
  33.         authentication_version = AUTHTYPE_NULL;
  34.         break;
  35.     case AUTH_UNKNOWN:          /* We don't know who he is, but he's okay */
  36.         if (sstelnet)
  37.             strcpy(uidbuf,"(unknown)");
  38.         break;
  39.     case AUTH_OTHER:            /* We know him, but not his name */
  40.         if (sstelnet)
  41.             strcpy(uidbuf,"(other)");
  42.         break;
  43.     case AUTH_USER:             /* We know he name */
  44.     case AUTH_VALID:            /* We know him, and he needs no password */
  45.         if (sstelnet)
  46.             strcpy(uidbuf,szUserNameRequested);
  47.         break;
  48.     }
  49. }
  50. #ifdef KRB4
  51. #ifdef NT
  52. void
  53. ck_krb4_debug(int x)
  54. {
  55.     set_krb_debug(x);
  56.     set_krb_ap_req_debug(x);
  57. }
  58. #endif /* NT */
  59. int
  60. ck_krb4_autoget_TGT(char * realm)
  61. {
  62.     extern struct krb_op_data krb_op;
  63.     extern struct krb4_init_data krb4_init;
  64.     char passwd[PWD_SZ];
  65.     char prompt[256];
  66.     char * saverealm=NULL;
  67.     int  rc = -1;
  68.     extern char * k4prprompt;
  69.     extern char * k4pwprompt;
  70.     ini_kerb();         /* Place defaults in above structs */
  71.     passwd[0] = '';
  72.     if ( krb4_init.principal == NULL ||
  73.          krb4_init.principal[0] == '') {
  74.         readtext(k4prprompt && k4prprompt[0] ?
  75.  k4prprompt :
  76.  "Kerberos 4 Principal: ",
  77.  passwd,PWD_SZ-1);
  78.         if ( passwd[0] )
  79.             makestr(&krb4_init.principal,passwd);
  80.         else
  81.             return(0);
  82.     }
  83.     /* Save realm in init structure so it can be restored */
  84.     if ( realm ) {
  85.         saverealm = krb4_init.realm;
  86.         krb4_init.realm = realm;
  87.     }
  88.     if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
  89.         sprintf(prompt,k4pwprompt && k4pwprompt[0] ? k4pwprompt :
  90.                  "%s@%s's Kerberos 4 Password: ",
  91.                  krb4_init.principal,krb4_init.realm);
  92.         readpass(prompt,passwd,PWD_SZ-1);
  93.     } else {
  94.         ckstrncpy(passwd,pwbuf,sizeof(passwd));
  95. #ifdef OS2
  96.         if ( pwcrypt )
  97.             ck_encrypt((char *)passwd);
  98. #endif /* OS2 */
  99.     }
  100.     if ( passwd[0] ) {
  101.         makestr(&krb4_init.password,passwd);
  102.         rc = ck_krb4_initTGT(&krb_op, &krb4_init);
  103.         free(krb4_init.password);
  104.         krb4_init.password = NULL;
  105.     }
  106.     krb4_init.password = NULL;
  107.     memset(passwd,0,PWD_SZ);
  108.     /* restore realm to init structure if needed */
  109.     if ( saverealm )
  110.         krb4_init.realm = saverealm;
  111.     return(rc == 0);
  112. }
  113. char *
  114. ck_krb4_realmofhost(char *host)
  115. {
  116.     return (char *)krb_realmofhost(host);
  117. }
  118. /*
  119.  *
  120.  * K4_auth_send - gets authentication bits we need to send to KDC.
  121.  *
  122.  * Result is left in auth
  123.  *
  124.  * Returns: 0 on failure, 1 on success
  125.  */
  126. static int
  127. #ifdef CK_ANSIC
  128. k4_auth_send(void)
  129. #else
  130. k4_auth_send()
  131. #endif
  132. {
  133.     int r=0;                                    /* Return value */
  134.     char instance[INST_SZ+1]="";
  135.     char *realm=NULL;
  136.     char tgt[4*REALM_SZ+1];
  137.     memset(instance, 0, sizeof(instance));
  138.     debug(F110,"k4_auth_send","krb_get_phost",0);
  139.     if (realm = (char *)krb_get_phost(szHostName)) {
  140.         ckstrncpy(instance, realm, INST_SZ);
  141.     }
  142.     debug(F110,"k4_auth_send","krb_get_realmofhost",0);
  143.     realm = (char *)krb_realmofhost(szHostName);
  144.     if (!realm) {
  145.         strcpy(strTmp, "Can't find realm for host "");
  146.         strcat(strTmp, szHostName);
  147.         strcat(strTmp, """);
  148.         printf("?Kerberos 4 error: %srn",strTmp);
  149.         krb4_errno = r;
  150.         makestr(&krb4_errmsg,strTmp);
  151.         return(0);
  152.     }
  153.     sprintf(tgt,"krbtgt.%s@%s",realm,realm);
  154.     r = ck_krb4_tkt_isvalid(tgt);
  155.     if ( r <= 0 && krb4_autoget )
  156.         ck_krb4_autoget_TGT(realm);
  157.     debug(F110,"k4_auth_send","krb_mk_req",0);
  158.     r = krb_mk_req(&k4_auth, krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  159.                     instance, realm, 0);
  160.     if (r == 0) {
  161.         debug(F110,"k4_auth_send","krb_get_cred",0);
  162.         r = krb_get_cred(krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  163.                           instance, realm, (CREDENTIALS *)&cred);
  164.         if (r)
  165.             debug(F111,"k4_auth_send","krb_get_cred() failed",r);
  166.     }
  167.     else
  168.         debug(F111,"k4_auth_send","krb_mk_req() failed",r);
  169.     if (r) {
  170.         strcpy(strTmp, "Can't get "");
  171.         strcat(strTmp, krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME);
  172.         if (instance[0] != 0) {
  173.             strcat(strTmp, ".");
  174.             strcat(strTmp, instance);
  175.         }
  176.         strcat(strTmp, "@");
  177.         strcat(strTmp, realm);
  178.         strcat(strTmp, "" ticketrn  ");
  179.         strcat(strTmp, (char *)krb_get_err_text_entry(r));
  180.         debug(F111,"k4_auth_send",(char *)krb_get_err_text_entry(r),r);
  181.         printf("?Kerberos 4 error: %srn",strTmp);
  182.         krb4_errno = r;
  183.         makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  184.         return(0);
  185.     }
  186. #ifdef OS2
  187.     if ( !szUserName[0] || !stricmp(szUserName,cred.pname) ) {
  188.         ckstrncpy(szUserName, cred.pname, UIDBUFLEN);
  189.     }
  190. #endif /* OS2 */
  191.     krb4_errno = r;
  192.     makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  193.     debug(F110,"k4_auth_send",krb4_errmsg,0);
  194.     return(1);
  195. }
  196. /*
  197.  * Function: K4 parse authentication reply command
  198.  *
  199.  * Parameters:
  200.  *  parsedat - the sub-command data.
  201.  *
  202.  *  end_sub - index of the character in the 'parsedat' array which
  203.  * is the last byte in a sub-negotiation
  204.  *
  205.  * Returns: Kerberos error code.
  206.  */
  207. static int
  208. #ifdef CK_ANSIC
  209. k4_auth_reply(unsigned char *parsedat, int end_sub)
  210. #else
  211. k4_auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  212. #endif
  213. {
  214. #ifdef CK_ENCRYPTION
  215.     Session_Key skey;
  216. #ifdef MIT_CURRENT
  217.     krb5_data kdata;
  218.     krb5_enc_data encdata;
  219.     krb5_error_code code;
  220. #endif /* MIT_CURRENT */
  221. #endif
  222.     time_t t;
  223.     int x;
  224.     int i;
  225.     if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
  226.         auth_finished(AUTH_REJECT);
  227.         return AUTH_FAILURE;
  228.     }
  229.     if (parsedat[4] == KRB_REJECT) {
  230.         strTmp[0] = 0;
  231.         for (i = 5; i <= end_sub; i++) {
  232.             if (parsedat[i] == IAC)
  233.                 break;
  234.             strTmp[i-5] = parsedat[i];
  235.             strTmp[i-4] = 0;
  236.         }
  237.         if (!strTmp[0])
  238.             strcpy(strTmp, "Authentication rejected by remote machine!");
  239.         printf("Kerberos V4 authentication failed!rn%srn",strTmp);
  240.         krb4_errno = 0;
  241.         makestr(&krb4_errmsg,strTmp);
  242.         auth_finished(AUTH_REJECT);
  243.         return AUTH_FAILURE;
  244.     }
  245.     if (parsedat[4] == KRB_ACCEPT) {
  246.         int net_len;
  247.         if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) {
  248.             sprintf(strTmp,"Kerberos V4 accepts you as %s",szUserName);
  249.             printf("%srn",strTmp);
  250.             accept_complete = 1;
  251.             krb4_errno = 0;
  252.             makestr(&krb4_errmsg,strTmp);
  253.             auth_finished(AUTH_USER);
  254.             return AUTH_SUCCESS;
  255.         }
  256.         if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) {
  257.             printf("Kerberos V4 authentication failed!rn");
  258.             sprintf(strTmp,
  259.         "Kerberos V4 accepted you, but didn't provide mutual authentication");
  260.             printf("%srn",strTmp);
  261.             krb4_errno = 0;
  262.             makestr(&krb4_errmsg,strTmp);
  263.             auth_finished(AUTH_REJECT);
  264.             return AUTH_FAILURE;
  265.         }
  266. #ifndef REMOVE_FOR_EXPORT
  267. #ifdef CK_ENCRYPTION
  268.         SendK4AuthSB(KRB4_CHALLENGE,k4_session_key,sizeof(k4_session_key));
  269.         /* We have sent the decrypted session key to the host as a challenge */
  270. /* now encrypt it to restore it to its original valid DES key value */
  271. #ifdef MIT_CURRENT
  272.         kdata.data = k4_session_key;
  273.         kdata.length = 8;
  274.         encdata.ciphertext.data = k4_session_key;
  275.         encdata.ciphertext.length = 8;
  276.         encdata.enctype = ENCTYPE_UNKNOWN;
  277.         if (code = krb5_c_encrypt(k5_context, &k4_krbkey,
  278.                                    0, 0, &kdata, &encdata)) {
  279.             com_err("k4_auth_reply", code,
  280.                      "while encrypting session_key");
  281.             auth_finished(AUTH_REJECT);
  282.             return AUTH_FAILURE;
  283.         }
  284. #else /* MIT_CURRENT */
  285. #ifdef NT
  286.         des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 1);
  287. #else /* NT */
  288.         des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 1);
  289. #endif /* NT */
  290.         hexdump(
  291.     "k4_auth_reply des_ecb_encrypt(k4_session_key,k4_session_key,1)",
  292.              k4_session_key,
  293.      8
  294. );
  295. #endif /* MIT_CURRENT */
  296.         /* And then use it to configure the encryption state machine. */
  297.         skey.type = SK_DES;
  298.         skey.length = 8;
  299.         skey.data = k4_session_key;
  300.         encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  301. #endif /* ENCRYPTION */
  302. #endif /* REMOVE_FOR_EXPORT */
  303.         accept_complete = 1;
  304.         sprintf(strTmp,"Kerberos V4 accepts you as %s",szUserName);
  305.         printf("%srn",strTmp);
  306.         krb4_errno = 0;
  307.         makestr(&krb4_errmsg,strTmp);
  308.         auth_finished(AUTH_USER);
  309.         return AUTH_SUCCESS;
  310.     }
  311.     if (parsedat[4] == KRB4_RESPONSE) {
  312.         if (end_sub < 12) {
  313.             auth_finished(AUTH_REJECT);
  314.             return AUTH_FAILURE;
  315.         }
  316.         hexdump("KRB4_RESPONSE &parsedat[5]",&parsedat[5],8);
  317. #ifdef CK_ENCRYPTION
  318.         hexdump("KRB4_RESPONSE k4_challenge",k4_challenge,8);
  319.         /* The datablock returned from the host should match the value */
  320.         /* we stored in k4_challenge.                                  */
  321.         if (memcmp(&parsedat[5], k4_challenge, sizeof(k4_challenge)) != 0) {
  322.             printf("Kerberos V4 authentication failed!rn%srn",
  323.             "Remote machine is being impersonated!");
  324.             krb4_errno = 0;
  325.             makestr(&krb4_errmsg,"Remote machine is being impersonated!");
  326.             auth_finished(AUTH_REJECT);
  327.             return AUTH_FAILURE;
  328.         }
  329. #else /* ENCRYPTION */
  330.         makestr(&krb4_errmsg,"Kermit built without support for encryption.");
  331.         return AUTH_FAILURE;
  332. #endif /* ENCRYPTION */
  333.         mutual_complete = 1;
  334.         sprintf(strTmp,"Remote machine has been mutually authenticated");
  335.         printf("%srn",strTmp);
  336.         krb4_errno = 0;
  337.         makestr(&krb4_errmsg,strTmp);
  338.         auth_finished(AUTH_USER);
  339.         return AUTH_SUCCESS;
  340.     }
  341.     auth_finished(AUTH_REJECT);
  342.     return AUTH_FAILURE;
  343. }
  344. /*
  345.  * Function: K4 parse authentication IS command
  346.  *
  347.  * Parameters:
  348.  *  parsedat - the sub-command data.
  349.  *
  350.  *  end_sub - index of the character in the 'parsedat' array which
  351.  *            is the last byte in a sub-negotiation
  352.  *
  353.  * Returns: Kerberos error code.
  354.  */
  355. static int
  356. #ifdef CK_ANSIC
  357. k4_auth_is(unsigned char *parsedat, int end_sub)
  358. #else
  359. k4_auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  360. #endif
  361. {
  362. #ifdef CK_ENCRYPTION
  363.     Session_Key skey;
  364. #ifdef MIT_CURRENT
  365.     Block datablock, tmpkey;
  366.     krb5_data kdata;
  367.     krb5_enc_data encdata;
  368.     krb5_error_code code;
  369. #else /* MIT_CURRENT */
  370.     Block datablock;
  371. #endif /* MIT_CURRENT */
  372. #endif /* ENCRYPTION */
  373.     char realm[REALM_SZ+1];
  374.     char instance[INST_SZ];
  375.     int r = 0;
  376.     char * data = &parsedat[5];
  377.     int    cnt = end_sub - 5;
  378.     extern char myipaddr[];
  379.     struct hostent *host;
  380.     struct in_addr inaddr;
  381.     int i;
  382.     if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
  383.         debug(F110,"k4_auth_is","Not kerberos v4",0);
  384.         auth_finished(AUTH_REJECT);
  385.         return AUTH_FAILURE;
  386.     }
  387.     switch (parsedat[4]) {
  388.     case KRB_AUTH:
  389.         debug(F110,"k4_auth_is","KRB_AUTH",0);
  390.         if (krb_get_lrealm(realm, 1) != KSUCCESS) {
  391.             SendK4AuthSB(KRB_REJECT, (void *)"No local V4 Realm.", -1);
  392.             printf("rn? Kerberos 4 - No Local Realmrn");
  393.             debug(F110,"k4_auth_is","No local realm",0);
  394.             krb4_errno = 0;
  395.             makestr(&krb4_errmsg,"No local realm");
  396.             auth_finished(AUTH_REJECT);
  397.             return AUTH_FAILURE;
  398.         }
  399.         debug(F110,"k4_auth_is",realm,0);
  400.         k4_auth.length = cnt;
  401.         memcpy((void *)k4_auth.dat, (void *)data, k4_auth.length);
  402. #ifdef COMMENT
  403.         debug(F101,"kerberos4_cksum","",
  404.                kerberos4_cksum(k4_auth.dat, k4_auth.length));
  405. #endif /* COMMENT */
  406.         hexdump("k4_auth.dat",k4_auth.dat, k4_auth.length);
  407.         /* Get Instance */
  408.         inaddr.s_addr = inet_addr(myipaddr);
  409.         host = gethostbyaddr((unsigned char *)&inaddr,4,PF_INET);
  410.         if ( host ) {
  411.             ckstrncpy(instance,host->h_name,INST_SZ);
  412.             for ( i=0;i<INST_SZ;i++ ) {
  413.                 if ( instance[i] == '.' )
  414.                     instance[i] = '';
  415.                 else
  416.                     instance[i] = tolower(instance[i]);
  417.             }
  418.         } else {
  419.             instance[0] = '*';
  420.             instance[1] = 0;
  421.         }
  422.         if (r = krb_rd_req(&k4_auth,
  423.                             krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  424.                             instance, 0, &k4_adat, k4_keyfile)) {
  425.             hexdump("k4_adat", &k4_adat, sizeof(AUTH_DAT));
  426.             krb_kntoln(&k4_adat, k4_name);
  427.             sprintf(strTmp,"Kerberos failed him as %s", k4_name);
  428.             printf("%srn",strTmp);
  429.             krb4_errno = r;
  430.             makestr(&krb4_errmsg,strTmp);
  431.             SendK4AuthSB(KRB_REJECT, (void *)krb_get_err_text_entry(r), -1);
  432.             auth_finished(AUTH_REJECT);
  433.             return AUTH_FAILURE;
  434.         }
  435. #ifdef CK_ENCRYPTION
  436.         memcpy((void *)k4_session_key, (void *)k4_adat.session, sizeof(Block));
  437.         hexdump("k4_auth_is k4_session_key",k4_session_key,sizeof(Block));
  438. #endif /* ENCRYPTION */
  439.         krb_kntoln(&k4_adat, k4_name);
  440.         ckstrncpy(szUserNameAuthenticated,k4_name,128);
  441.         if (szUserNameRequested && !kuserok(&k4_adat, k4_name)) {
  442.             SendK4AuthSB(KRB_ACCEPT, (void *)0, 0);
  443.     if ( !strcmp(k4_name,szUserNameRequested) )
  444. auth_finished(AUTH_VALID);
  445.     else
  446. auth_finished(AUTH_USER);
  447.             accept_complete = 1;
  448.         }
  449.         else {
  450.             SendK4AuthSB(KRB_REJECT,
  451.                   (void *)"user is not authorized", -1);
  452.             auth_finished(AUTH_REJECT);
  453.             krb4_errno = r;
  454.             makestr(&krb4_errmsg,"user is not authorized");
  455.             return(AUTH_FAILURE);
  456.         }
  457.         break;
  458.     case KRB4_CHALLENGE:
  459.         debug(F110,"k4_auth_is","KRB_CHALLENGE",0);
  460. #ifndef CK_ENCRYPTION
  461.         SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
  462. #else /* ENCRYPTION */
  463.         if (!VALIDKEY(k4_session_key)) {
  464.             /*
  465.             * We don't have a valid session key, so just
  466.             * send back a response with an empty session
  467.             * key.
  468.             */
  469.             SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
  470.             mutual_complete = 1;
  471.             break;
  472.         }
  473.         /*
  474.         * Initialize the random number generator since it's
  475.         * used later on by the encryption routine.
  476.         */
  477. #ifdef MIT_CURRENT
  478.         kdata.data = k4_session_key;
  479.         kdata.length = 8;
  480.         if (code = krb5_c_random_seed(k5_context, &kdata)) {
  481.             com_err("k4_auth_is", code,
  482.                      "while seeding random number generator");
  483.             auth_finished(AUTH_REJECT);
  484.             return AUTH_FAILURE;
  485.         }
  486.         memcpy((void *)datablock, (void *)data, sizeof(Block));
  487.         /*
  488.         * Take the received encrypted challenge, and encrypt
  489.         * it again to get a unique session_key for the
  490.         * ENCRYPT option.
  491.         */
  492.         k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
  493.         k4_krbkey.length = 8;
  494.         k4_krbkey.contents = k4_session_key;
  495.         kdata.data = datablock;
  496.         kdata.length = 8;
  497.         encdata.ciphertext.data = tmpkey;
  498.         encdata.ciphertext.length = 8;
  499.         encdata.enctype = ENCTYPE_UNKNOWN;
  500.         if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
  501.                                    &kdata, &encdata)) {
  502.             com_err("k4_auth_is", code, "while encrypting random key");
  503.             auth_finished(AUTH_REJECT);
  504.             return AUTH_FAILURE;
  505.         }
  506.         skey.type = SK_DES;
  507.         skey.length = 8;
  508.         skey.data = tmpkey;
  509.         encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  510.         /*
  511.         * Now decrypt the received encrypted challenge,
  512.         * increment by one, re-encrypt it and send it back.
  513.         */
  514.         encdata.ciphertext.data = datablock;
  515.         encdata.ciphertext.length = 8;
  516.         encdata.enctype = ENCTYPE_UNKNOWN;
  517.         kdata.data = k4_challenge;
  518.         kdata.length = 8;
  519.         if (code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  520.                                    &encdata, &kdata)) {
  521.             com_err("k4_auth_is", code, "while decrypting challenge");
  522.             auth_finished(AUTH_REJECT);
  523.             return AUTH_FAILURE;
  524.         }
  525. #else /* MIT_CURRENT */
  526.         des_set_random_generator_seed(k4_session_key);
  527.         r = des_key_sched(k4_session_key, k4_sched);
  528.         if ( r == -1 ) {
  529.             printf("?Invalid DES key specified in credentialsrn");
  530.             debug(F110,"auth_is CHALLENGE",
  531.                    "invalid DES Key specified in credentials",0);
  532.         } else if ( r == -2 ) {
  533.             printf("?Weak DES key specified in credentialsrn");
  534.             debug(F110,"auth_is CHALLENGE",
  535.                    "weak DES Key specified in credentials",0);
  536.         } else if ( r != 0 ) {
  537.             printf("?DES Key Schedule not set by credentialsrn");
  538.             debug(F110,"auth_is CHALLENGE",
  539.                    "DES Key Schedule not set by credentials",0);
  540.         }
  541.         hexdump("auth_is schedule",k4_sched,8*16);
  542.         memcpy((void *)datablock, (void *)data, sizeof(Block));
  543.         hexdump("auth_is challege",datablock,sizeof(Block));
  544.         /*
  545.         * Take the received encrypted challenge, and encrypt
  546.         * it again to get a unique k4_session_key for the
  547.         * ENCRYPT option.
  548.         */
  549. #ifdef NT
  550.         des_ecb_encrypt(datablock, k4_session_key, k4_sched, 1);
  551. #else /* NT */
  552.         des_ecb_encrypt(&datablock, &k4_session_key, k4_sched, 1);
  553. #endif /* NT */
  554.         hexdump("auth_is des_ecb_encrypt(datablock,k4_session_key,1)",
  555.                  k4_session_key,8);
  556.         skey.type = SK_DES;
  557.         skey.length = 8;
  558.         skey.data = k4_session_key;
  559.         encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  560.         /*
  561.         * Now decrypt the received encrypted challenge,
  562.         * increment by one, re-encrypt it and send it back.
  563.         */
  564. #ifdef NT
  565.         des_ecb_encrypt(datablock, k4_challenge, k4_sched, 0);
  566. #else /* NT */
  567.         des_ecb_encrypt(&datablock, &k4_challenge, k4_sched, 0);
  568. #endif /* NT */
  569.         hexdump("auth_is des_ecb_encrypt(datablock,k4_challenge,0)",
  570.                  k4_session_key,8);
  571. #endif /* MIT_CURRENT */
  572.         for (r = 7; r >= 0; r--) {
  573.             register int t;
  574.             t = (unsigned int)k4_challenge[r] + 1;
  575.             k4_challenge[r] = t; /* ignore overflow */
  576.             if (t < 256) /* if no overflow, all done */
  577.                 break;
  578.         }
  579.         hexdump("auth_is k4_challenge+1",k4_challenge,8);
  580. #ifdef MIT_CURRENT
  581.         kdata.data = k4_challenge;
  582.         kdata.length = 8;
  583.         encdata.ciphertext.data = k4_challenge;
  584.         encdata.ciphertext.length = 8;
  585.         encdata.enctype = ENCTYPE_UNKNOWN;
  586.         if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
  587.                                    &kdata, &encdata)) {
  588.             com_err("k4_auth_is", code, "while decrypting challenge");
  589.             auth_finished(AUTH_REJECT);
  590.             return AUTH_FAILURE;
  591.         }
  592. #else /* MIT_CURRENT */
  593. #ifdef NT
  594.         des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
  595. #else /* NT */
  596.         des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
  597. #endif /* NT */
  598.         hexdump("auth_is des_ecb_encrypt(k4_challenge_key,k4_challenge,1)",
  599.                  k4_challenge,8);
  600. #endif /* MIT_CURRENT */
  601.         SendK4AuthSB(KRB4_RESPONSE,(void *)k4_challenge,sizeof(k4_challenge));
  602. #endif /* ENCRYPTION */
  603.         mutual_complete = 1;
  604.         break;
  605.     default:
  606.         if (1)
  607.             printf("Unknown Kerberos option %drn", data[-1]);
  608.         SendK4AuthSB(KRB_REJECT, 0, 0);
  609.         return(AUTH_FAILURE);
  610.     }
  611.     krb4_errno = r;
  612.     makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  613.     return(AUTH_SUCCESS);
  614. }
  615. #endif /* KRB4 */
  616. #ifdef KRB5
  617. int
  618. ck_krb5_autoget_TGT(char * realm)
  619. {
  620.     extern struct krb_op_data krb_op;
  621.     extern struct krb5_init_data krb5_init;
  622.     char passwd[PWD_SZ];
  623.     char prompt[64];
  624.     char * saverealm=NULL;
  625.     int  rc = -1;
  626.     extern char * k5prprompt;
  627.     extern char * k5pwprompt;
  628.     ini_kerb();         /* Place defaults in above structs */
  629.     passwd[0] = '';
  630.     if ( krb5_init.principal == NULL ||
  631.          krb5_init.principal[0] == '') {
  632.         readtext(k5prprompt && k5prprompt[0] ? k5prprompt :
  633.                   "Kerberos 5 Principal: ",passwd,PWD_SZ-1);
  634.         if ( passwd[0] )
  635.             makestr(&krb5_init.principal,passwd);
  636.         else
  637.             return(0);
  638.     }
  639.     /* Save realm in init structure so it can be restored */
  640.     if ( realm ) {
  641.         saverealm = krb5_init.realm;
  642.         krb5_init.realm = realm;
  643.     }
  644.     if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
  645.         sprintf(prompt,k5pwprompt && k5pwprompt[0] ? k5pwprompt :
  646.                  "%s@%s's Kerberos 5 Password: ",
  647.                  krb5_init.principal,krb5_init.realm);
  648.         readpass(prompt,passwd,PWD_SZ-1);
  649.     } else {
  650.         ckstrncpy(passwd,pwbuf,sizeof(passwd));
  651. #ifdef OS2
  652.         if ( pwcrypt )
  653.             ck_encrypt((char *)passwd);
  654. #endif /* OS2 */
  655.     }
  656.     if ( passwd[0] ) {
  657.         makestr(&krb5_init.password,passwd);
  658.         rc = ck_krb5_initTGT(&krb_op, &krb5_init);
  659.         free(krb5_init.password);
  660.         krb5_init.password = NULL;
  661.         if ( krb5_d_getk4 && krb4_autoget ) {
  662.             extern struct krb4_init_data krb4_init;
  663.             char * savek4realm=NULL;
  664.             makestr(&krb4_init.principal,krb5_init.principal);
  665.             makestr(&krb4_init.password,passwd);
  666.             if ( realm ) {
  667.                 savek4realm = krb4_init.realm;
  668.                 krb4_init.realm = realm;
  669.             }
  670.             rc = ck_krb4_initTGT(&krb_op, &krb4_init);
  671.             if ( savek4realm )
  672.                 krb4_init.realm = savek4realm;
  673.             free(krb4_init.password);
  674.             krb4_init.password = NULL;
  675.         }
  676.         memset(passwd,0,PWD_SZ);
  677.     }
  678.     /* restore realm to init structure if needed */
  679.     if ( saverealm )
  680.         krb5_init.realm = saverealm;
  681.     return(rc == 0);
  682. }
  683. static krb5_error_code
  684. #ifdef CK_ANSIC
  685. k5_get_ccache( krb5_context k5_context, krb5_ccache * p_ccache,
  686.                char * cc_name )
  687. #else  /* CK_ANSIC */
  688. k5_get_ccache(k5_context, p_ccache, cc_name)
  689.     krb5_context k5_context;
  690.     krb5_ccache * p_ccache;
  691.     char * cc_name;
  692. #endif /* CK_ANSIC */
  693. {
  694.     krb5_error_code r=0;
  695.     char cc_tmp[CKMAXPATH+1];
  696.     const char * def_name = NULL;
  697.     if ( cc_name ) {
  698.         if ( strncmp("FILE:",cc_name,5) &&
  699.              strncmp("MEMORY:",cc_name,7) &&
  700.              strncmp("API:",cc_name,4) &&
  701.              strncmp("STDIO:",cc_name,6))
  702.             sprintf(cc_tmp,"FILE:%s",cc_name);
  703.         else {
  704.             ckstrncpy(cc_tmp,cc_name,CKMAXPATH);
  705.         }
  706.         r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
  707.         if (r != 0) {
  708.             com_err("k5_get_ccache resolving ccache",r,
  709.                      cc_tmp);
  710.         }
  711.     } else if ( krb5_d_cc ) {
  712.         if ( strncmp("FILE:",krb5_d_cc,5) &&
  713.              strncmp("MEMORY:",krb5_d_cc,7) &&
  714.              strncmp("API:",krb5_d_cc,4) &&
  715.              strncmp("STDIO:",krb5_d_cc,6))
  716.             sprintf(cc_tmp,"FILE:%s",krb5_d_cc);
  717.         else {
  718.             ckstrncpy(cc_tmp,krb5_d_cc,CKMAXPATH);
  719.         }
  720.         r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
  721.         if (r != 0) {
  722.             com_err("k5_get_ccache resolving ccache",r,
  723.                      krb5_d_cc);
  724.         }
  725.     } else {
  726.         if ((r = krb5_cc_default(k5_context, p_ccache))) {
  727.             com_err("k5_get_ccache",r,"while getting default ccache");
  728.         }
  729.     }
  730.     krb5_errno = r;
  731.     makestr(&krb5_errmsg,error_message(krb5_errno));
  732.     return(r);
  733. }
  734. char *
  735. ck_krb5_realmofhost(char *host)
  736. {
  737.     char ** realmlist=NULL;
  738.     krb5_context private_context=NULL;
  739.     static char * realm = NULL;
  740.     if ( !host )
  741.         return NULL;
  742.     if ( realm ) {
  743.         free(realm);
  744.         realm = NULL;
  745.     }
  746.     /* create private_context */
  747.     krb5_init_context(&private_context);
  748.     krb5_get_host_realm(private_context,host,&realmlist);
  749.     if (realmlist && realmlist[0]) {
  750.         makestr(&realm,realmlist[0]);
  751.         krb5_free_host_realm(private_context,realmlist);
  752.         realmlist = NULL;
  753.     }
  754.     if ( private_context ) {
  755.         krb5_free_context(private_context);
  756.         private_context = NULL;
  757.     }
  758.     return(realm);
  759. }
  760. /*
  761.  *
  762.  * K5_auth_send - gets authentication bits we need to send to KDC.
  763.  *
  764.  * Code lifted from telnet sample code in the appl directory.
  765.  *
  766.  * Result is left in k5_auth
  767.  *
  768.  * Returns: 0 on failure, 1 on success
  769.  *
  770.  */
  771. static int
  772. #ifdef CK_ANSIC
  773. k5_auth_send(int how, int encrypt, int forward)
  774. #else
  775. k5_auth_send(how,encrypt) int how; int encrypt; int forward;
  776. #endif
  777. {
  778.     krb5_error_code r=0;
  779.     krb5_ccache ccache=NULL;
  780.     krb5_creds creds;
  781.     krb5_creds * new_creds=NULL;
  782.     krb5_flags ap_opts;
  783.     char type_check[2];
  784.     krb5_data check_data;
  785.     int len=0;
  786. #ifdef CK_ENCRYPTION
  787.     krb5_keyblock *newkey = 0;
  788. #endif
  789.     char * realm = NULL;
  790.     char tgt[256];
  791.     realm = ck_krb5_realmofhost(szHostName);
  792.     if (!realm) {
  793.         strcpy(strTmp, "Can't find realm for host "");
  794.         strcat(strTmp, szHostName);
  795.         strcat(strTmp, """);
  796.         printf("?Kerberos 5 error: %srn",strTmp);
  797.         krb5_errno = 5;
  798.         makestr(&krb5_errmsg,strTmp);
  799.         return(0);
  800.     }
  801.     sprintf(tgt,"krbtgt/%s@%s",realm,realm);
  802.     debug(F110,"k5_auth_send TGT",tgt,0);
  803.     if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
  804.   (ck_krb5_is_tgt_valid() > 0)) &&
  805.         krb5_autoget )
  806.         ck_krb5_autoget_TGT(realm);
  807.     r = k5_get_ccache(k5_context,&ccache,NULL);
  808.     if ( r ) {
  809.         com_err(NULL, r, "while authorizing (0).");
  810.         krb5_errno = r;
  811.         makestr(&krb5_errmsg,error_message(krb5_errno));
  812.         return(0);
  813.     }
  814.     memset((char *)&creds, 0, sizeof(creds));
  815.     if (r = krb5_sname_to_principal(k5_context, szHostName,
  816.                                 krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  817.                                 KRB5_NT_SRV_HST, &creds.server)) {
  818.         com_err(NULL, r, "while authorizing (1).");
  819.         krb5_errno = r;
  820.         makestr(&krb5_errmsg,error_message(krb5_errno));
  821.         return(0);
  822.     }
  823.     if (r = krb5_cc_get_principal(k5_context, ccache, &creds.client)) {
  824.         com_err(NULL, r, "while authorizing (2).");
  825.         krb5_free_cred_contents(k5_context, &creds);
  826.         krb5_errno = r;
  827.         makestr(&krb5_errmsg,error_message(krb5_errno));
  828.         return(0);
  829.     }
  830.     if (szUserName[0] == '') {                /* Get user name now */
  831.         len  = krb5_princ_component(k5_context, creds.client, 0)->length;
  832.         memcpy(szUserName,
  833.                 krb5_princ_component(k5_context, creds.client, 0)->data,
  834.                 len);
  835.         szUserName[len] = '';
  836.     } else {
  837.         char * name = NULL;
  838.         len  = krb5_princ_component(k5_context, creds.client, 0)->length;
  839.         if ( len == strlen(szUserName) ) {
  840.             name = krb5_princ_component(k5_context, creds.client, 0)->data;
  841. #ifdef OS2
  842.             if ( !strnicmp(szUserName,name,len) ) {
  843.                 memcpy(szUserName,name,len);
  844.                 szUserName[len] = '';
  845.             }
  846. #endif /* OS2 */
  847.         }
  848.     }
  849.     creds.keyblock.enctype=ENCTYPE_DES_CBC_CRC;
  850.     if (r = krb5_get_credentials(k5_context, 0,
  851.                                   ccache, &creds, &new_creds)) {
  852.         com_err(NULL, r, "while authorizing (3).");
  853.         krb5_free_cred_contents(k5_context, &creds);
  854.         krb5_errno = r;
  855.         makestr(&krb5_errmsg,error_message(krb5_errno));
  856.         return(0);
  857.     }
  858.     if (auth_context) {
  859.         krb5_auth_con_free(k5_context, auth_context);
  860.         auth_context = 0;
  861.     }
  862.     if ((r = krb5_auth_con_init(k5_context, &auth_context))) {
  863.         com_err(NULL, r, "while initializing auth context");
  864.         krb5_errno = r;
  865.         makestr(&krb5_errmsg,error_message(krb5_errno));
  866.         return(0);
  867.     }
  868.     krb5_auth_con_setflags(k5_context, auth_context,
  869.                             KRB5_AUTH_CONTEXT_RET_TIME);
  870.     type_check[0] = AUTHTYPE_KERBEROS_V5;
  871.     type_check[1] = AUTH_CLIENT_TO_SERVER |
  872.         (how ? AUTH_HOW_MUTUAL : AUTH_HOW_ONE_WAY) |
  873.         (encrypt ? AUTH_ENCRYPT_USING_TELOPT : AUTH_ENCRYPT_OFF) |
  874.         (forward ? INI_CRED_FWD_ON : INI_CRED_FWD_OFF);
  875.     check_data.magic = KV5M_DATA;
  876.     check_data.length = 2;
  877.     check_data.data = (char *)&type_check;
  878.     ap_opts = 0;
  879.     if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
  880.         ap_opts = AP_OPTS_MUTUAL_REQUIRED;
  881. #ifdef CK_ENCRYPTION
  882.     ap_opts |= AP_OPTS_USE_SUBKEY;
  883. #endif
  884.     r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts,
  885.                               &check_data, new_creds, &k5_auth);
  886. #ifdef CK_ENCRYPTION
  887.     krb5_auth_con_getlocalsubkey(k5_context, auth_context, &newkey);
  888.     if (k5_session_key) {
  889.         krb5_free_keyblock(k5_context, k5_session_key);
  890.         k5_session_key = 0;
  891.     }
  892.     if (newkey) {
  893.         /*
  894.         * keep the key in our private storage, but don't use it
  895.         * yet---see kerberos5_reply() below
  896.         */
  897.         if ((newkey->enctype != ENCTYPE_DES_CBC_CRC) &&
  898.              (newkey-> enctype != ENCTYPE_DES_CBC_MD5))
  899.         {
  900.             if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
  901.                  (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5))
  902.                 /* use the session key in credentials instead */
  903.                 krb5_copy_keyblock(k5_context,
  904.                                     &new_creds->keyblock, &k5_session_key);
  905.             else
  906.                 ;  /* What goes here? XXX */
  907.         } else {
  908.             krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  909.         }
  910.         krb5_free_keyblock(k5_context, newkey);
  911.     }
  912. #endif  /* ENCRYPTION */
  913.     krb5_free_cred_contents(k5_context, &creds);
  914.     krb5_free_creds(k5_context, new_creds);
  915.     krb5_cc_close(k5_context,ccache);
  916.     if (r) {
  917.         com_err(NULL, r, "while authorizing (4).");
  918.         krb5_errno = r;
  919.         makestr(&krb5_errmsg,error_message(krb5_errno));
  920.         return(0);
  921.     }
  922.     krb5_errno = r;
  923.     makestr(&krb5_errmsg,error_message(krb5_errno));
  924.     return(1);
  925. }
  926. /*
  927.  *
  928.  * K5_auth_reply -- checks the reply for mutual authentication.
  929.  *
  930.  * Code lifted from telnet sample code in the appl directory.
  931.  *
  932.  */
  933. static int
  934. #ifdef CK_ANSIC
  935. k5_auth_reply(int how, unsigned char *data, int cnt)
  936. #else
  937. k5_auth_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  938. #endif
  939. {
  940. #ifdef CK_ENCRYPTION
  941.     Session_Key skey;
  942. #endif
  943.     data += 4;                                  /* Point to status byte */
  944.     switch (*data++) {
  945.     case KRB_REJECT:
  946.         cnt -=5;
  947.         if (cnt > 0) {
  948.             char *s;
  949.             sprintf(strTmp,"Kerberos V5 refuses authentication becausern");
  950.             s = strTmp + strlen(strTmp);
  951.             memcpy(s, data, cnt);
  952.             s[cnt] = 0;
  953.         } else
  954.             sprintf(strTmp, "Kerberos V5 refuses authentication");
  955.         krb5_errno = 0;
  956.         makestr(&krb5_errmsg,strTmp);
  957.         printf("Kerberos authentication failed!rn%srn",strTmp);
  958.         auth_finished(AUTH_REJECT);
  959.         return AUTH_FAILURE;
  960.     case KRB_ACCEPT:
  961.         if (!mutual_complete) {
  962.             if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) {
  963.                 sprintf(strTmp,
  964.                           "Kerberos V5 accepted you, but didn't provide"
  965.                           " mutual authentication");
  966.                 printf("Kerberos authentication failed!rn%srn",strTmp);
  967.                 krb5_errno = 0;
  968.                 makestr(&krb5_errmsg,strTmp);
  969.                 auth_finished(AUTH_REJECT);
  970.                 return AUTH_FAILURE;
  971.             }
  972. #ifdef CK_ENCRYPTION
  973.             if (k5_session_key) {
  974.                 skey.type = SK_DES;
  975.                 skey.length = 8;
  976.                 skey.data = k5_session_key->contents;
  977.                 encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  978.             }
  979. #endif
  980.         }
  981.         cnt -= 5;
  982.         if ( cnt > 0 ) {
  983.             char *s;
  984.             sprintf(strTmp,"Kerberos V5 accepts you as ");
  985.             s = strTmp + strlen(strTmp);
  986.             memcpy(s,data,cnt);
  987.             s[cnt] = 0;
  988.         }
  989.         accept_complete = 1;
  990.         printf("%srn",strTmp);
  991. #ifdef FORWARD
  992.         if (forward_flag && (auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
  993.             kerberos5_forward();
  994. #endif
  995.         krb5_errno = 0;
  996.         makestr(&krb5_errmsg,strTmp);
  997.         auth_finished(AUTH_USER);
  998.         return AUTH_SUCCESS;
  999.     case KRB5_RESPONSE:
  1000.         if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  1001.             /* the rest of the reply should contain a krb_ap_rep */
  1002.             krb5_ap_rep_enc_part *reply;
  1003.             krb5_data inbuf;
  1004.             krb5_error_code r;
  1005.             inbuf.length = cnt;
  1006.             inbuf.data = (char *)data;
  1007.             if (r = krb5_rd_rep(k5_context, auth_context, &inbuf, &reply)) {
  1008.                 com_err(NULL, r, "while authorizing. (5)");
  1009.                 krb5_errno = r;
  1010.                 makestr(&krb5_errmsg,error_message(krb5_errno));
  1011.                 auth_finished(AUTH_REJECT);
  1012.                 return AUTH_FAILURE;
  1013.             }
  1014.             krb5_free_ap_rep_enc_part(k5_context, reply);
  1015. #ifdef CK_ENCRYPTION
  1016.             if (encrypt_flag && k5_session_key) {
  1017.                 skey.type = SK_DES;
  1018.                 skey.length = 8;
  1019.                 skey.data = k5_session_key->contents;
  1020.                 encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  1021.             }
  1022. #endif /* ENCRYPTION */
  1023.             mutual_complete = 1;
  1024.         }
  1025.         sprintf(strTmp,"Remote machine has been mutually authenticated");
  1026.         krb5_errno = 0;
  1027.         makestr(&krb5_errmsg,strTmp);
  1028.         printf("%srn",strTmp);
  1029.         auth_finished(AUTH_USER);
  1030.         return AUTH_SUCCESS;
  1031. #ifdef FORWARD
  1032.     case KRB5_FORWARD_ACCEPT:
  1033.         forwarded_tickets = 1;
  1034.         sprintf(strTmp,"Remote machine has accepted forwarded credentials");
  1035.         krb5_errno = 0;
  1036.         makestr(&krb5_errmsg,strTmp);
  1037.         printf("%srn",strTmp);
  1038.         return AUTH_SUCCESS;
  1039.     case KRB5_FORWARD_REJECT:
  1040.         forwarded_tickets = 0;
  1041.         if (cnt > 0) {
  1042.             char *s;
  1043.             sprintf(strTmp,
  1044.                       "Kerberos V5 refuses forwarded credentials because ");
  1045.             s = strTmp + strlen(strTmp);
  1046.             memcpy(s, data, cnt);
  1047.             s[cnt] = 0;
  1048.         } else
  1049.             sprintf(strTmp, "Kerberos V5 refuses forwarded credentials");
  1050.         printf("%srn",strTmp);
  1051.         krb5_errno = 0;
  1052.         makestr(&krb5_errmsg,strTmp);
  1053.         return AUTH_SUCCESS;
  1054. #endif /* FORWARD */
  1055.     default:
  1056.         krb5_errno = 0;
  1057.         makestr(&krb5_errmsg,"Unknown reply type");
  1058.         auth_finished(AUTH_REJECT);
  1059.         return AUTH_FAILURE;                        /* Unknown reply type */
  1060.     }
  1061. }
  1062. #ifdef FORWARD
  1063. /* Decode, decrypt and store the forwarded creds in the local ccache. */
  1064. /* Needed for KRB5_FORWARD                                            */
  1065. static krb5_error_code
  1066. rd_and_store_for_creds(context, auth_context, inbuf)
  1067.     krb5_context context;
  1068.     krb5_auth_context auth_context;
  1069.     krb5_data *inbuf;
  1070. {
  1071.     krb5_creds ** creds;
  1072.     krb5_error_code retval;
  1073.     krb5_ccache ccache=NULL;
  1074.     if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)))
  1075.         return(retval);
  1076.     retval = k5_get_ccache(context,&ccache,NULL);
  1077.     if ( retval )
  1078.         goto cleanup;
  1079.     if ((retval = krb5_cc_initialize(context, ccache, creds[0]->client)))
  1080.         goto cleanup;
  1081.     if ((retval = krb5_cc_store_cred(context, ccache, creds[0])))
  1082.         goto cleanup;
  1083.     if ((retval = krb5_cc_close(context, ccache)))
  1084.         goto cleanup;
  1085. cleanup:
  1086.     krb5_free_tgt_creds(context, creds);
  1087.     krb5_errno = retval;
  1088.     makestr(&krb5_errmsg,error_message(krb5_errno));
  1089.     return retval;
  1090. }
  1091. #endif /* FORWARD */
  1092. /*
  1093.  *
  1094.  * K5_auth_is.
  1095.  *
  1096.  */
  1097. static int
  1098. #ifdef CK_ANSIC
  1099. k5_auth_is(int how, unsigned char *data, int cnt)
  1100. #else
  1101. k5_auth_is(how,data,cnt) int how; unsigned char *data; int cnt;
  1102. #endif
  1103. {
  1104.     int r = 0;
  1105.     krb5_principal server;
  1106.     krb5_keyblock *newkey = NULL;
  1107.     krb5_keytab keytabid = 0;
  1108.     krb5_data outbuf;
  1109. #ifdef CK_ENCRYPTION
  1110.     Session_Key skey;
  1111. #endif
  1112.     char errbuf[128]="";
  1113.     char *name;
  1114.     char *getenv();
  1115.     krb5_data inbuf;
  1116.     krb5_authenticator *authenticator;
  1117.     char princ[256]="";
  1118.     int len;
  1119.     data += 4;                                  /* Point to status byte */
  1120.     cnt -= 4;
  1121.     hexdump("k5_auth_is data",data,cnt);
  1122.     if (cnt-- < 1) {
  1123.         auth_finished(AUTH_REJECT);
  1124.         return AUTH_FAILURE;
  1125.     }
  1126.     switch (*data++) {
  1127.     case KRB_AUTH:
  1128.         k5_auth.data = (char *)data;
  1129.         k5_auth.length = cnt;
  1130.         debug(F110,"k5_auth_is","KRB_AUTH",0);
  1131.         debug(F111,"k5_auth_is","auth_context",auth_context);
  1132.         if (!r && !auth_context) {
  1133.             r = krb5_auth_con_init(k5_context, &auth_context);
  1134.             debug(F111,"k5_auth_is","krb5_auth_con_init",r);
  1135.         }
  1136.         if (!r) {
  1137.             krb5_rcache rcache = NULL;
  1138.             r = krb5_auth_con_getrcache(k5_context, auth_context,
  1139.                                          &rcache);
  1140.             debug(F111,"k5_auth_is","krb5_auth_con_getrcache",r);
  1141.             if (!r && !rcache) {
  1142.                 r = krb5_sname_to_principal(k5_context, 0,
  1143. #ifdef COMMENT
  1144.                                              0, /* changed in KRB5-CURRENT */
  1145. #else /* COMMENT */
  1146.                                              krb5_d_srv ? krb5_d_srv :
  1147.                                              KRB5_SERVICE_NAME,
  1148. #endif /* COMMENT */
  1149.                                              KRB5_NT_SRV_HST, &server);
  1150.                 debug(F111,"k5_auth_is","krb5_sname_to_principal",r);
  1151.                 if (!r) {
  1152.                     r = krb5_get_server_rcache(k5_context,
  1153.                         krb5_princ_component(k5_context, server, 0),
  1154.                                                 &rcache);
  1155.                     debug(F111,"k5_auth_is","krb5_get_server_rcache",r);
  1156.                     krb5_free_principal(k5_context, server);
  1157.                 }
  1158.             }
  1159.             if (!r) {
  1160.                 r = krb5_auth_con_setrcache(k5_context,
  1161.                                              auth_context, rcache);
  1162.                 debug(F111,"k5_auth_is","krb5_auth_con_setrcache",r);
  1163.             }
  1164.         }
  1165.         if (!r && telnet_srvtab) {
  1166.             r = krb5_kt_resolve(k5_context,
  1167.                                  telnet_srvtab, &keytabid);
  1168.             debug(F111,"k5_auth_is","krb5_kt_resolve",r);
  1169.         }
  1170.         if (!r) {
  1171.             r = krb5_rd_req(k5_context, &auth_context, &k5_auth,
  1172.                              NULL, keytabid, NULL, &k5_ticket);
  1173.             debug(F111,"k5_auth_is","krb5_rd_req",r);
  1174.         }
  1175.         if (r) {
  1176.             (void) strcpy(errbuf, "krb5_rd_req failed: ");
  1177.             (void) strcat(errbuf, error_message(r));
  1178.             goto errout;
  1179.         }
  1180.         len = krb5_princ_component(k5_context,k5_ticket->server,0)->length;
  1181.         if (len < 256)
  1182.         {
  1183.             memcpy(princ,krb5_princ_component(k5_context,
  1184.                                            k5_ticket->server,0)->data,len);
  1185.             princ[len] = '';
  1186.         }
  1187.         if ( strcmp((krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME), princ) )
  1188.         {
  1189.             debug(F110,"k5_auth_is incorrect service name",princ,0);
  1190.             (void) sprintf( errbuf, "incorrect service name: %s != %s",
  1191.                             (krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME),
  1192.                             princ);
  1193.             goto errout;
  1194.         }
  1195.         r = krb5_auth_con_getauthenticator(k5_context,
  1196.                                             auth_context,
  1197.                                             &authenticator);
  1198.         debug(F111,"k5_auth_is","krb5_auth_con_getauthenticator",r);
  1199.         if (r) {
  1200.             (void) strcpy(errbuf,
  1201.                            "krb5_auth_con_getauthenticator failed: ");
  1202.             (void) strcat(errbuf, error_message(r));
  1203.             goto errout;
  1204.         }
  1205.         if (authenticator->checksum) {
  1206.             char type_check[2];
  1207.             krb5_checksum *cksum = authenticator->checksum;
  1208.             krb5_keyblock *key;
  1209.             type_check[0] = AUTHTYPE_KERBEROS_V5;
  1210.             type_check[1] = how;        /* not broken into parts */
  1211.             r = krb5_auth_con_getkey(k5_context, auth_context,
  1212.                                       &key);
  1213.             debug(F111,"k5_auth_is","krb5_auth_con_getkey",r);
  1214.             if (r) {
  1215.                 (void) strcpy(errbuf, "krb5_auth_con_getkey failed: ");
  1216.                 (void) strcat(errbuf, error_message(r));
  1217.                 goto errout;
  1218.             }
  1219.             r = krb5_verify_checksum(k5_context,
  1220.                                       cksum->checksum_type, cksum,
  1221.                                       &type_check, 2, key->contents,
  1222.                                       key->length);
  1223.             debug(F111,"k5_auth_is","krb5_verify_checksum",r);
  1224.             if (r) {
  1225.                 (void) strcpy(errbuf,
  1226.                                "checksum verification failed: ");
  1227.                 (void) strcat(errbuf, error_message(r));
  1228.                 goto errout;
  1229.             }
  1230.             krb5_free_keyblock(k5_context, key);
  1231.         } else {
  1232.             if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT) {
  1233.                 (void) strcpy(errbuf,
  1234.                                "authenticator is missing required checksum");
  1235.                 goto errout;
  1236.             }
  1237.         }
  1238.         krb5_free_authenticator(k5_context, authenticator);
  1239.         if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  1240.             /* do ap_rep stuff here */
  1241.             if ((r = krb5_mk_rep(k5_context, auth_context,
  1242.                                   &outbuf))) {
  1243.                 debug(F111,"k5_auth_is","krb5_mk_rep",r);
  1244.                 (void) strcpy(errbuf, "Make reply failed: ");
  1245.                 (void) strcat(errbuf, error_message(r));
  1246.                 goto errout;
  1247.             }
  1248.             debug(F111,"k5_auth_is","krb5_mk_rep",r);
  1249.             SendK5AuthSB(KRB5_RESPONSE, outbuf.data, outbuf.length);
  1250.             mutual_complete = 1;
  1251.         }
  1252.         if (krb5_unparse_name(k5_context,
  1253.                                k5_ticket->enc_part2 ->client,
  1254.                                &name))
  1255.             name = 0;
  1256.         SendK5AuthSB(KRB_ACCEPT, name, name ? -1 : 0);
  1257.         accept_complete = 1;
  1258.         sprintf(strTmp,"Kerberos5 identifies him as ``%s''",
  1259.                 name ? name : "");
  1260.         printf("%srn",strTmp);
  1261.         ckstrncpy(szUserNameAuthenticated,name,128);
  1262. if (szUserNameRequested[0] &&
  1263.     krb5_kuserok(k5_context, k5_ticket->enc_part2->client,
  1264.  szUserNameRequested))
  1265.     auth_finished(AUTH_VALID);
  1266. else
  1267.     auth_finished(AUTH_USER);
  1268.         if (name)
  1269.             free(name);
  1270.         krb5_auth_con_getremotesubkey(k5_context, auth_context,
  1271.                                        &newkey);
  1272.         if (k5_session_key) {
  1273.             krb5_free_keyblock(k5_context, k5_session_key);
  1274.             k5_session_key = 0;
  1275.         }
  1276.         if (newkey) {
  1277.             krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  1278.             krb5_free_keyblock(k5_context, newkey);
  1279.         } else {
  1280.             krb5_copy_keyblock(k5_context,
  1281.                                  k5_ticket->enc_part2->session,
  1282.                                 &k5_session_key);
  1283.         }
  1284. #ifdef CK_ENCRYPTION
  1285.         skey.type = k5_session_key->length == 8 ? SK_DES : SK_GENERIC;
  1286.         skey.length = k5_session_key->length;
  1287.         skey.data = k5_session_key->contents;
  1288.         encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  1289. #endif
  1290.         debug(F100,"k5_auth_is AUTH_SUCCESS","",0);
  1291.         krb5_errno = r;
  1292.         if ( krb5_errno )
  1293.             makestr(&krb5_errmsg,error_message(krb5_errno));
  1294.         else
  1295.             makestr(&krb5_errmsg,strTmp);
  1296.         return AUTH_SUCCESS;
  1297. #ifdef FORWARD
  1298.     case KRB5_FORWARD:
  1299. if ( !forward_flag ) {
  1300.             SendK5AuthSB(KRB5_FORWARD_REJECT,
  1301.   "forwarded credentials are being refused.",
  1302.   -1);
  1303.     return(AUTH_SUCCESS);
  1304. }
  1305.         inbuf.length = cnt;
  1306.         inbuf.data = (char *)data;
  1307.         if ((r = krb5_auth_con_genaddrs(k5_context,auth_context,g_kstream->fd,
  1308.       KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) ||
  1309.     (r = rd_and_store_for_creds(k5_context, auth_context,
  1310.       &inbuf, k5_ticket, szUserNameRequested))) {
  1311.             (void) strcpy(errbuf, "Read forwarded creds failed: ");
  1312.             (void) strcat(errbuf, error_message(r));
  1313.             SendK5AuthSB(KRB5_FORWARD_REJECT, errbuf, -1);
  1314.             printf("Could not read forwarded credentialsrn");
  1315.             krb5_errno = r;
  1316.             makestr(&krb5_errmsg,error_message(krb5_errno));
  1317.         }
  1318.         else {
  1319.             SendK5AuthSB(KRB5_FORWARD_ACCEPT, 0, 0);
  1320.             sprintf(strTmp,"Forwarded credentials obtained");
  1321.             printf("%srn",strTmp);
  1322.             krb5_errno = r;
  1323.             makestr(&krb5_errmsg,strTmp);
  1324.         }
  1325. /* A failure to accept forwarded credentials is not an */
  1326. /* authentication failure.                             */
  1327. return AUTH_SUCCESS;
  1328. #endif /* FORWARD */
  1329.     default:
  1330.         printf("Unknown Kerberos option %drn", data[-1]);
  1331.         SendK5AuthSB(KRB_REJECT, 0, 0);
  1332.         break;
  1333.     }
  1334.     auth_finished(AUTH_REJECT);
  1335.     return AUTH_FAILURE;
  1336.   errout:
  1337.     SendK5AuthSB(KRB_REJECT, errbuf, -1);
  1338.     krb5_errno = r;
  1339.     makestr(&krb5_errmsg,errbuf);
  1340.     printf("%srn", errbuf);
  1341.     if (auth_context) {
  1342.         krb5_auth_con_free(k5_context, auth_context);
  1343.         auth_context = 0;
  1344.     }
  1345.     auth_finished(AUTH_REJECT);
  1346.     return AUTH_FAILURE;
  1347. }
  1348. #ifdef FORWARD
  1349. VOID
  1350. #ifdef CK_ANSIC
  1351. kerberos5_forward(void)
  1352. #else
  1353. kerberos5_forward()
  1354. #endif
  1355. {
  1356.     krb5_error_code r;
  1357.     krb5_ccache ccache=NULL;
  1358.     krb5_principal client = 0;
  1359.     krb5_principal server = 0;
  1360.     krb5_data forw_creds;
  1361.     forw_creds.data = 0;
  1362.     r = k5_get_ccache(k5_context,&ccache,NULL);
  1363.     if ( r ) {
  1364.         com_err(NULL, r, "Kerberos V5: could not get default ccache");
  1365.         krb5_errno = r;
  1366.         makestr(&krb5_errmsg,error_message(krb5_errno));
  1367.         return;
  1368.     }
  1369.     if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) {
  1370.         com_err(NULL, r, "Kerberos V5: could not get default principal");
  1371.         goto cleanup;
  1372.     }
  1373.     if ((r = krb5_sname_to_principal(k5_context, szHostName,
  1374.                                krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  1375.      KRB5_NT_SRV_HST, &server))) {
  1376.         com_err(NULL, r, "Kerberos V5: could not make server principal");
  1377.         goto cleanup;
  1378.     }
  1379.     if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, g_kstream->fd,
  1380.     KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) {
  1381.         com_err(NULL, r, "Kerberos V5: could not gen local full address");
  1382.         goto cleanup;
  1383.     }
  1384.     if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server,
  1385.         ccache, forwardable_flag, &forw_creds)) {
  1386.         com_err(NULL, r, "Kerberos V5: error getting forwardable credentials");
  1387.         goto cleanup;
  1388.     }
  1389.     /* Send forwarded credentials */
  1390.     if (!SendK5AuthSB(KRB5_FORWARD, forw_creds.data, forw_creds.length)) {
  1391.         printf("Kerberos V5 forwarding error!rn%srn",
  1392.                     "Not enough room for authentication data");
  1393.     }
  1394. cleanup:
  1395.     if (client)
  1396.         krb5_free_principal(k5_context, client);
  1397.     if (server)
  1398.         krb5_free_principal(k5_context, server);
  1399. #if 0 /* XXX */
  1400.     if (forw_creds.data)
  1401.         free(forw_creds.data);
  1402. #endif
  1403.     krb5_cc_close(k5_context, ccache);
  1404.     krb5_errno = r;
  1405.     makestr(&krb5_errmsg,error_message(krb5_errno));
  1406. }
  1407. #endif /* FORWARD */
  1408. #else /* KRB5 */
  1409. int
  1410. ck_krb5_autoget_TGT(char * dummy)
  1411. {
  1412.     return(0);
  1413. }
  1414. #ifdef CK_KERBEROS
  1415. int
  1416. #ifdef CK_ANSIC
  1417. ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init )
  1418. #else
  1419. ck_krb5_initTGT(op,init)
  1420.     krb_op_data * op; struct krb5_init_data * init;
  1421. #endif /* CK_ANSIC*/
  1422. {
  1423.     return(-1);
  1424. }
  1425. int
  1426. #ifdef CK_ANSIC
  1427. ck_krb5_destroy(struct krb_op_data * op)
  1428. #else
  1429. ck_krb5_destroy(op) struct krb_op_data * op;
  1430. #endif
  1431. {
  1432.     return(-1);
  1433. }
  1434. int
  1435. #ifdef CK_ANSIC
  1436. ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
  1437. #else
  1438. ck_krb5_list_creds(op,lc)
  1439.     struct krb_op_data * op; struct krb5_list_cred_data * lc;
  1440. #endif
  1441. {
  1442.     return(-1);
  1443. }
  1444. #else /* CK_KERBEROS */
  1445. int
  1446. #ifdef CK_ANSIC
  1447. ck_krb5_initTGT(void * op, void * init )
  1448. #else
  1449. ck_krb5_initTGT(op,init)
  1450.     void * op; void * init;
  1451. #endif /* CK_ANSIC*/
  1452. {
  1453.     return(-1);
  1454. }
  1455. int
  1456. #ifdef CK_ANSIC
  1457. ck_krb5_destroy(void * op)
  1458. #else
  1459. ck_krb5_destroy(op) void * op;
  1460. #endif
  1461. {
  1462.     return(-1);
  1463. }
  1464. int
  1465. #ifdef CK_ANSIC
  1466. ck_krb5_list_creds(void * op, void * lc)
  1467. #else
  1468. ck_krb5_list_creds(op,lc)
  1469.     void * op; void * lc;
  1470. #endif
  1471. {
  1472.     return(-1);
  1473. }
  1474. #endif /* CK_KERBEROS */
  1475. #endif /* KRB5 */
  1476. #ifdef CK_SRP
  1477. /*
  1478.  * Copyright (c) 1997 Stanford University
  1479.  *
  1480.  * The use of this software for revenue-generating purposes may require a
  1481.  * license from the owners of the underlying intellectual property.
  1482.  * Specifically, the SRP-3 protocol may not be used for revenue-generating
  1483.  * purposes without a license.
  1484.  *
  1485.  * Within that constraint, permission to use, copy, modify, and distribute
  1486.  * this software and its documentation for any purpose is hereby granted
  1487.  * without fee, provided that the above copyright notices and this permission
  1488.  * notice appear in all copies of the software and related documentation.
  1489.  *
  1490.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  1491.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  1492.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  1493.  *
  1494.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  1495.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  1496.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
  1497.  * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
  1498.  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1499.  */
  1500. static void
  1501. srp_encode_length(data, num)
  1502.     unsigned char * data;
  1503.     int num;
  1504. {
  1505.     *data = (num >> 8) & 0xff;
  1506.     *++data = num & 0xff;
  1507. }
  1508. static int
  1509. srp_decode_length(data)
  1510.     unsigned char * data;
  1511. {
  1512.     return (((int) *data & 0xff) << 8) | (*(data + 1) & 0xff);
  1513. }
  1514. static int
  1515. #ifdef CK_ANSIC
  1516. srp_reply(int how, unsigned char *data, int cnt)
  1517. #else
  1518. srp_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  1519. #endif
  1520. {
  1521.     struct t_num n;
  1522.     struct t_num g;
  1523.     struct t_num s;
  1524.     struct t_num B;
  1525.     struct t_num * A;
  1526.     char hexbuf[MAXHEXPARAMLEN];
  1527.     char type_check[2];
  1528.     int pflag;
  1529. #ifdef CK_ENCRYPTION
  1530.     Session_Key skey;
  1531. #endif /* ENCRYPTION */
  1532.     char * str=NULL;
  1533.     data += 4;                          /* Point to status byte */
  1534.     cnt  -= 4;
  1535.     if(cnt-- < 1) {
  1536.         auth_finished(AUTH_REJECT);
  1537.         return AUTH_FAILURE;
  1538.     }
  1539.     switch(*data++) {
  1540.     case SRP_REJECT:
  1541.         if (cnt > 0) {
  1542.             sprintf(strTmp,
  1543.                      "SRP refuses authentication for '%s' (%.*s)rn",
  1544.                      szUserName, cnt, data);
  1545.             str = strTmp + strlen(strTmp);
  1546.             memcpy(str,data,cnt);
  1547.             str[cnt] = 0;
  1548.         } else
  1549.             sprintf(strTmp,"SRP refuses authentication for '%s'rn",
  1550.                      szUserName);
  1551.         printf("SRP authentication failed!rn%srn",strTmp);
  1552.         auth_finished(AUTH_REJECT);
  1553.         return AUTH_FAILURE;
  1554.     case SRP_ACCEPT:
  1555.         if(tc == NULL || cnt < RESPONSE_LEN || !srp_waitresp) {
  1556.             printf("SRP Protocol errorrn");
  1557.             auth_finished(AUTH_REJECT);
  1558.             return AUTH_FAILURE;
  1559.         }
  1560.         srp_waitresp = 0;
  1561.         if(t_clientverify(tc, data) == 0) {
  1562.             printf("SRP accepts you as %srn",szUserName);
  1563. #ifdef CK_ENCRYPTION
  1564.             skey.type = SK_GENERIC;
  1565.             skey.length = SESSION_KEY_LEN;
  1566.             skey.data = tc->session_key;
  1567.             encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  1568. #endif /* ENCRYPTION */
  1569.             accept_complete = 1;
  1570.             auth_finished(AUTH_VALID);
  1571.             return AUTH_SUCCESS;
  1572.         }
  1573.         else {
  1574.             printf("SRP server authentication failed!rn");
  1575.             auth_finished(AUTH_REJECT);
  1576.             return AUTH_FAILURE;
  1577.         }
  1578.         break;
  1579.     case SRP_PARAMS:
  1580.         if(!szUserName) {
  1581.             printf("No username availablern");
  1582.             auth_finished(AUTH_REJECT);
  1583.             return AUTH_FAILURE;
  1584.         }
  1585.         n.len = srp_decode_length(data);
  1586.         data += 2;
  1587.         cnt -= 2;
  1588.         if(n.len > cnt) {
  1589.             printf("n too longrn");
  1590.             auth_finished(AUTH_REJECT);
  1591.             return AUTH_FAILURE;
  1592.         }
  1593.         n.data = data;
  1594.         data += n.len;
  1595.         cnt -= n.len;
  1596.         g.len = srp_decode_length(data);
  1597.         data += 2;
  1598.         cnt -= 2;
  1599.         if(g.len > cnt) {
  1600.             printf("g too longrn");
  1601.             auth_finished(AUTH_REJECT);
  1602.             return AUTH_FAILURE;
  1603.         }
  1604.         g.data = data;
  1605.         data += g.len;
  1606.         cnt -= g.len;
  1607.         s.len = srp_decode_length(data);
  1608.         data += 2;
  1609.         cnt -= 2;
  1610.         if(s.len > cnt) {
  1611.             printf("salt too longrn");
  1612.             auth_finished(AUTH_REJECT);
  1613.             return AUTH_FAILURE;
  1614.         }
  1615.         s.data = data;
  1616.         data += s.len;
  1617.         cnt -= s.len;
  1618.         tc = t_clientopen(szUserName, &n, &g, &s);
  1619.         A = t_clientgenexp(tc);
  1620.         SendSRPAuthSB(SRP_EXP, A->data, A->len);
  1621.         if ( pwbuf[0] && pwflg ) {
  1622.             printf("SRP using %d-bit modulus for '%s'rn",
  1623.    8 * n.len,
  1624.    szUserName
  1625.    );
  1626.             ckstrncpy(srp_passwd,pwbuf,sizeof(srp_passwd));
  1627. #ifdef OS2
  1628.             if ( pwcrypt )
  1629.                 ck_encrypt((char *)srp_passwd);
  1630. #endif /* OS2 */
  1631.         } else {
  1632.             extern char * srppwprompt;
  1633.             char prompt[128];
  1634.             sprintf(prompt,"SRP using %d-bit modulusrn%s's password: ",
  1635.                      8 * n.len,szUserName);
  1636.             readpass(srppwprompt && srppwprompt[0] ? srppwprompt :
  1637.                       prompt,srp_passwd,sizeof(srp_passwd)-1);
  1638.         }
  1639.         t_clientpasswd(tc, srp_passwd);
  1640.         memset(srp_passwd, 0, sizeof(srp_passwd));
  1641.         return AUTH_SUCCESS;
  1642.     case SRP_CHALLENGE:
  1643.         if(tc == NULL) {
  1644.             printf("Protocol errorrn");
  1645.             auth_finished(AUTH_REJECT);
  1646.             return AUTH_FAILURE;
  1647.         }
  1648. #ifndef PRE_SRP_1_4_5
  1649.         if ( (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT ) {
  1650.             type_check[0] = AUTHTYPE_SRP;
  1651.             type_check[1] = how;
  1652.             t_clientaddexdata(tc,type_check,2);
  1653.         }
  1654. #endif /* PRE_SRP_1_4_5 */
  1655.         B.data = data;
  1656.         B.len = cnt;
  1657.         t_clientgetkey(tc, &B);
  1658.         SendSRPAuthSB(SRP_RESPONSE, t_clientresponse(tc), RESPONSE_LEN);
  1659.         srp_waitresp = 1;
  1660.         return AUTH_SUCCESS;
  1661.     default:
  1662.         auth_finished(AUTH_REJECT);
  1663.         return AUTH_FAILURE;
  1664.     }
  1665.     return AUTH_FAILURE;
  1666. }
  1667. static int
  1668. #ifdef CK_ANSIC
  1669. srp_is(int how, unsigned char *data, int cnt)
  1670. #else
  1671. srp_is(how,data,cnt) int how; unsigned char *data; int cnt;
  1672. #endif
  1673. {
  1674.     char pbuf[2 * MAXPARAMLEN + 5];
  1675.     char * ptr;
  1676.     struct t_num A;
  1677.     char hexbuf[MAXHEXPARAMLEN];
  1678.     struct passwd * pass;
  1679. #ifdef CK_ENCRYPTION
  1680.     Session_Key skey;
  1681. #endif
  1682.     struct t_pw * tpw = NULL;
  1683.     struct t_conf * tconf = NULL;
  1684.     char type_check[2];
  1685.     if ((cnt -= 4) < 1) {
  1686.         auth_finished(AUTH_REJECT);
  1687.         return AUTH_FAILURE;
  1688.     }
  1689.     data += 4;
  1690.     cnt  -= 1;
  1691.     switch(*data++) {
  1692.     case SRP_AUTH:
  1693.         /* Send parameters back to client */
  1694.         if(ts != NULL) {
  1695.             t_serverclose(ts);
  1696.             ts = NULL;
  1697.         }
  1698.         if(!szUserNameRequested[0]) {
  1699.             if (1)
  1700.                 printf("No username availablern");
  1701.             SendSRPAuthSB(SRP_REJECT, (void *) "No username supplied", -1);
  1702.             auth_finished(AUTH_REJECT);
  1703.             return(AUTH_FAILURE);
  1704.         }
  1705. #ifdef IKSD
  1706. #ifdef CK_LOGIN
  1707.         if (inserver && ckxanon &&
  1708.              !strcmp(szUserNameRequested,"anonymous")) {
  1709.             SendSRPAuthSB(SRP_REJECT, (void *)
  1710.             "anonymous login cannot be performed with Secure Remote Password",
  1711.             -1);
  1712.             auth_finished(AUTH_REJECT);
  1713.             return(AUTH_FAILURE);
  1714.         }
  1715. #endif /* CK_LOGIN */
  1716. #endif /* IKSD */
  1717. #ifdef PRE_SRP_1_4_4
  1718.         if(tpw == NULL) {
  1719.             if((tpw = t_openpw(NULL)) == NULL) {
  1720.                 if (1)
  1721.                     printf("Unable to open password filern");
  1722.                 SendSRPAuthSB(SRP_REJECT, (void *) "No password file", -1);
  1723.                 return(AUTH_FAILURE);
  1724.             }
  1725.         }
  1726.         if(tconf == NULL) {
  1727.             if((tconf = t_openconf(NULL)) == NULL) {
  1728.                 if (1)
  1729.   printf("Unable to open configuration filern");
  1730.                 SendSRPAuthSB(SRP_REJECT, (void *)"No configuration file", -1);
  1731.                 return(AUTH_FAILURE);
  1732.             }
  1733.         }
  1734.         ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
  1735.         t_closepw(tpw);
  1736.         tpw = NULL;
  1737.         t_closeconf(tconf);
  1738.         tconf = NULL;
  1739. #else /* PRE_SRP_1_4_4 */
  1740.         /* On Windows and OS/2 there is no well defined place for the */
  1741.         /* ETC directory.  So we look for either an SRP_ETC or ETC    */
  1742.         /* environment variable in that order.  If we find one we     */
  1743.         /* attempt to open the files manually.                        */
  1744.         /* We will reuse the pbuf[] for the file names. */
  1745.         ptr = getenv("SRP_ETC");
  1746.         if ( !ptr )
  1747.             ptr = getenv("ETC");
  1748.         if ( ptr ) {
  1749.             int len = strlen(ptr);
  1750.             int i;
  1751.             strcpy(pbuf,ptr);
  1752.             for ( i=0;i<len;i++ ) {
  1753.                 if ( pbuf[i] == '\' )
  1754.                     pbuf[i] = '/';
  1755.             }
  1756.             if ( pbuf[len-1] != '/' )
  1757.                 strcat(pbuf,"/tpasswd");
  1758.             else
  1759.                 strcat(pbuf,"tpasswd");
  1760.             tpw = t_openpwbyname(pbuf);
  1761.             strcat(pbuf,".conf");
  1762.             tconf = t_openconfbyname(pbuf);
  1763.         }
  1764.         if ( tpw && tconf )
  1765.             ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
  1766.         else
  1767.             ts = t_serveropen(szUserNameRequested);
  1768.         if ( tpw ) {
  1769.             t_closepw(tpw);
  1770.             tpw = NULL;
  1771.         }
  1772.         if ( tconf ) {
  1773.             t_closeconf(tconf);
  1774.             tconf = NULL;
  1775.         }
  1776. #endif /* PRE_SRP_1_4_4 */
  1777.         if(ts == NULL) {
  1778.             if (1)
  1779.                 printf("User %s not foundrn", szUserNameRequested);
  1780.             SendSRPAuthSB(SRP_REJECT, (void *) "Password not set", -1);
  1781.             return(AUTH_FAILURE);
  1782.         }
  1783.         ptr = pbuf;
  1784.         srp_encode_length(ptr, ts->n.len);
  1785.         ptr += 2;
  1786.         memcpy(ptr, ts->n.data, ts->n.len);
  1787.         ptr += ts->n.len;
  1788.         srp_encode_length(ptr, ts->g.len);
  1789.         ptr += 2;
  1790.         memcpy(ptr, ts->g.data, ts->g.len);
  1791.         ptr += ts->g.len;
  1792.         srp_encode_length(ptr, ts->s.len);
  1793.         ptr += 2;
  1794.         memcpy(ptr, ts->s.data, ts->s.len);
  1795.         ptr += ts->s.len;
  1796.         SendSRPAuthSB(SRP_PARAMS, pbuf, ptr - pbuf);
  1797.         B = t_servergenexp(ts);
  1798.         ckstrncpy(szUserNameAuthenticated,szUserNameRequested,128);
  1799.         return AUTH_SUCCESS;
  1800.     case SRP_EXP:
  1801.         /* Client is sending A to us, compute challenge & expected response. */
  1802.         if (ts == NULL || B == NULL) {
  1803.             if (1)
  1804.       printf("Protocol error: SRP_EXP unexpectedrn");
  1805.             SendSRPAuthSB(SRP_REJECT,
  1806.   (void *) "Protocol error: unexpected EXP",
  1807.   -1
  1808.   );
  1809.             return(AUTH_FAILURE);
  1810.         }
  1811.         /* Wait until now to send B, since it contains the key to "u" */
  1812.         SendSRPAuthSB(SRP_CHALLENGE, B->data, B->len);
  1813.         B = NULL;
  1814. #ifndef PRE_SRP_1_4_5
  1815.         if ( (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT ) {
  1816.             type_check[0] = AUTHTYPE_SRP;
  1817.             type_check[1] = how;
  1818.             t_serveraddexdata(ts,type_check,2);
  1819.         }
  1820. #endif /* PRE_SRP_1_4_5 */
  1821.         A.data = data;
  1822.         A.len = cnt;
  1823.         ptr = t_servergetkey(ts, &A);
  1824.         if(ptr == NULL) {
  1825.             if (1)
  1826.       printf("Security alert: Trivial session key attemptedrn");
  1827.             SendSRPAuthSB(SRP_REJECT,
  1828.   (void *) "Trivial session key detected",
  1829.   -1
  1830.   );
  1831.             return(AUTH_FAILURE);
  1832.         }
  1833.         srp_waitresp = 1;
  1834.         return AUTH_SUCCESS;
  1835.     case SRP_RESPONSE:
  1836.         /* Got the response; see if it's correct */
  1837.         if(ts == NULL || !srp_waitresp) {
  1838.             if (1)
  1839.       printf("Protocol error: SRP_RESPONSE unexpectedrn");
  1840.             SendSRPAuthSB(SRP_REJECT,
  1841.   (void *) "Protocol error: unexpected RESPONSE",
  1842.   -1
  1843.   );
  1844.             return(AUTH_FAILURE);
  1845.         }
  1846. srp_waitresp = 0; /* we got a response */
  1847.         if (cnt < RESPONSE_LEN) {
  1848.             if (1)
  1849.       printf("Protocol error: malformed responsern");
  1850.             SendSRPAuthSB(SRP_REJECT,
  1851.   (void *) "Protocol error: malformed response",
  1852.   -1
  1853.   );
  1854.             return(AUTH_FAILURE);
  1855.         }
  1856.         if (t_serververify(ts, data) == 0) {
  1857.             SendSRPAuthSB(SRP_ACCEPT, t_serverresponse(ts), RESPONSE_LEN);
  1858.             accept_complete = 1;
  1859. #ifdef CK_ENCRYPTION
  1860.             hexdump("SRP_RESPONSE ts",ts,sizeof(ts));
  1861.             hexdump("SRP_RESPONSE session_key",
  1862.     ts->session_key,
  1863.     SESSION_KEY_LEN
  1864.     );
  1865.             skey.type = SK_GENERIC;
  1866.             skey.length = SESSION_KEY_LEN;
  1867.             skey.data = ts->session_key;
  1868.             encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  1869. #endif
  1870.             auth_finished(AUTH_VALID);
  1871.         }
  1872.         else {
  1873.             SendSRPAuthSB(SRP_REJECT, (void *) "Login incorrect", -1);
  1874.             auth_finished(AUTH_REJECT);
  1875.             return(AUTH_FAILURE);
  1876.         }
  1877.         return AUTH_SUCCESS;
  1878.     default:
  1879.         if (1)
  1880.             printf("Unknown SRP option %drn", data[-1]);
  1881.         SendSRPAuthSB(SRP_REJECT, (void *) "Unknown option received", -1);
  1882.         return(AUTH_FAILURE);
  1883.     }
  1884. }
  1885. #endif /* SRP */
  1886. #ifdef KRB5
  1887. #ifdef KINIT
  1888. /*
  1889.  * clients/kinit/kinit.c
  1890.  *
  1891.  * Copyright 1990 by the Massachusetts Institute of Technology.
  1892.  * All Rights Reserved.
  1893.  *
  1894.  * Export of this software from the United States of America may
  1895.  *   require a specific license from the United States Government.
  1896.  *   It is the responsibility of any person or organization contemplating
  1897.  *   export to obtain such a license before exporting.
  1898.  *
  1899.  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  1900.  * distribute this software and its documentation for any purpose and
  1901.  * without fee is hereby granted, provided that the above copyright
  1902.  * notice appear in all copies and that both that copyright notice and
  1903.  * this permission notice appear in supporting documentation, and that
  1904.  * the name of M.I.T. not be used in advertising or publicity pertaining
  1905.  * to distribution of the software without specific, written prior
  1906.  * permission.  M.I.T. makes no representations about the suitability of
  1907.  * this software for any purpose.  It is provided "as is" without express
  1908.  * or implied warranty.
  1909.  *
  1910.  *
  1911.  * Initialize a credentials cache.
  1912.  */
  1913. #define KRB5_DEFAULT_OPTIONS 0
  1914. #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
  1915. static krb5_data tgtname = {
  1916.     0,
  1917.     KRB5_TGS_NAME_SIZE,
  1918.     KRB5_TGS_NAME
  1919. };
  1920. /* Internal prototypes */
  1921. static krb5_error_code krb5_validate_tgt
  1922.         KRB5_PROTOTYPE((krb5_context, krb5_ccache,
  1923.                         krb5_principal, krb5_data *));
  1924. static krb5_error_code krb5_renew_tgt
  1925.         KRB5_PROTOTYPE((krb5_context, krb5_ccache,
  1926.                         krb5_principal, krb5_data *));
  1927. static krb5_error_code krb5_tgt_gen
  1928.         KRB5_PROTOTYPE((krb5_context, krb5_ccache,
  1929.                         krb5_principal, krb5_data *, int opt));
  1930. /*
  1931.  * Try no preauthentication first; then try the encrypted timestamp
  1932.  */
  1933. static krb5_preauthtype * preauth = NULL;
  1934. static krb5_preauthtype preauth_list[2] = { 0, -1 };
  1935. #define NO_KEYTAB
  1936. int
  1937. #ifdef CK_ANSIC
  1938. ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init )
  1939. #else
  1940. ck_krb5_initTGT(op,init)
  1941.     krb_op_data * op; struct krb5_init_data * init;
  1942. #endif /* CK_ANSIC*/
  1943. {
  1944.     krb5_context kcontext;
  1945.     krb5_ccache ccache = NULL;
  1946.     krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */
  1947.     krb5_timestamp starttime = 0;
  1948.     krb5_deltat rlife = 0;
  1949.     int options = KRB5_DEFAULT_OPTIONS;
  1950.     int option;
  1951.     int errflg = 0;
  1952.     krb5_error_code code;
  1953.     krb5_principal me=NULL;
  1954.     krb5_principal server=NULL;
  1955.     krb5_creds my_creds;
  1956.     krb5_timestamp now;
  1957.     krb5_address **addrs = (krb5_address **)0;
  1958.     int addr_count=0;
  1959.     int i,j;
  1960. #ifndef NO_KEYTAB
  1961.     int use_keytab = 0; /* -k option */
  1962.     krb5_keytab keytab = NULL;
  1963. #endif /* NO_KEYTAB */
  1964.     struct passwd *pw = 0;
  1965.     int pwsize;
  1966.     char *client_name=NULL, realm[256]="", numstr[40]="";
  1967.     if ( !ck_krb5_is_installed() )
  1968.         return(-1);
  1969. #ifdef COMMENT
  1970.     printf("Kerberos V initializationrn");
  1971. #endif /* COMMENT */
  1972.     code = krb5_init_context(&kcontext);
  1973.     if (code) {
  1974.         com_err("krb5_kinit",code,"while init_context");
  1975.         krb5_errno = code;
  1976.         makestr(&krb5_errmsg,error_message(krb5_errno));
  1977.         return(-1);
  1978.     }
  1979.     if ((code = krb5_timeofday(kcontext, &now))) {
  1980.         com_err("krb5_kinit",code,"while getting time of day");
  1981.         goto exit_k5_init;
  1982.     }
  1983.     if ( init->renewable ) {
  1984.         options |= KDC_OPT_RENEWABLE;
  1985.         sprintf(numstr,"%dm",init->renewable);
  1986.         code = krb5_string_to_deltat(numstr, &rlife);
  1987.         if (code != 0 || rlife == 0) {
  1988.             printf("Bad renewable time value %srn", numstr);
  1989.             errflg++;
  1990.         }
  1991.     }
  1992.     if ( init->renew ) {
  1993.         /* renew the ticket */
  1994.         options |= KDC_OPT_RENEW;
  1995.     }
  1996.     if ( init->validate ) {
  1997.         /* validate the ticket */
  1998.         options |= KDC_OPT_VALIDATE;
  1999.     }
  2000.     if ( init->proxiable ) {
  2001.         options |= KDC_OPT_PROXIABLE;
  2002.     }
  2003.     if ( init->forwardable ) {
  2004.         options |= KDC_OPT_FORWARDABLE;
  2005.     }
  2006. #ifndef NO_KEYTAB
  2007.     if (  ) {
  2008.         use_keytab = 1;
  2009.     }
  2010.     if (  ) {
  2011.         if (keytab == NULL && keytab_name != NULL) {
  2012.             code = krb5_kt_resolve(kcontext, keytab_name, &keytab);
  2013.             if (code != 0) {
  2014.                 debug(F111,"krb5_init resolving keytab",
  2015.                          keytab_name,code);
  2016.                 errflg++;
  2017.             }
  2018.         }
  2019.     }
  2020. #endif
  2021.     if ( init->lifetime ) {
  2022.         sprintf(numstr,"%dm",init->lifetime);
  2023.         code = krb5_string_to_deltat(numstr, &lifetime);
  2024.         if (code != 0 || lifetime == 0) {
  2025.             printf("Bad lifetime value %srn", numstr);
  2026.             errflg++;
  2027.         }
  2028.     }
  2029.     if ( init->postdate ) {
  2030.         /* Convert cmdate() to a time_t value */
  2031.         struct tm * time_tm;
  2032.         struct tm * cmdate2tm(char *,int);
  2033.         time_tm = cmdate2tm(init->postdate,0);
  2034.         if ( time_tm )
  2035.             starttime = (krb5_timestamp) mktime(time_tm);
  2036.         if (code != 0 || starttime == 0 || starttime == -1) {
  2037.             krb5_deltat ktmp;
  2038.             code = krb5_string_to_deltat(init->postdate, &ktmp);
  2039.             if (code == 0 && ktmp != 0) {
  2040. starttime = now + ktmp;
  2041. options |= KDC_OPT_POSTDATED;
  2042.             } else {
  2043. printf("Bad postdate start time value %srn",
  2044.                         init->postdate);
  2045. errflg++;
  2046.             }
  2047.         } else {
  2048.             options |= KDC_OPT_POSTDATED;
  2049.         }
  2050.     }
  2051.     code = k5_get_ccache(kcontext,&ccache,op->cache);
  2052.     if (code != 0) {
  2053.         com_err("krb5_kinit",code,"while getting default ccache");
  2054.         goto exit_k5_init;
  2055.     }
  2056.     if (init->principal == NULL) {       /* No principal name specified */
  2057. #ifndef NO_KEYTAB
  2058.         if (use_keytab) {
  2059.             /* Use the default host/service name */
  2060.             code = krb5_sname_to_principal(kcontext, NULL, NULL,
  2061.                                             KRB5_NT_SRV_HST, &me);
  2062.             if (code) {
  2063.                 com_err("krb5_kinit",
  2064. code,
  2065. "when creating default server principal name");
  2066.                 goto exit_k5_init;
  2067.             }
  2068.         } else
  2069. #endif
  2070.         {
  2071.             /* Get default principal from cache if one exists */
  2072.             code = krb5_cc_get_principal(kcontext, ccache, &me);
  2073.             if (code) {
  2074. #ifdef HAVE_PWD_H
  2075.                 /* Else search passwd file for client */
  2076.                 pw = getpwuid((int) getuid());
  2077.                 if (pw) {
  2078.                     if ((code = krb5_parse_name(kcontext,pw->pw_name,
  2079.                                                  &me))) {
  2080.                         krb5_errno = code;
  2081.                         com_err("krb5_kinit",code,"when parsing name",
  2082.                                   pw->pw_name);
  2083.                         goto exit_k5_init;
  2084.                     }
  2085.                 } else {
  2086.                     printf(
  2087.                         "Unable to identify user from password filern");
  2088.                     goto exit_k5_init;
  2089.                 }
  2090. #else /* HAVE_PWD_H */
  2091.                 printf("Unable to identify userrn");
  2092.                 goto exit_k5_init;
  2093. #endif /* HAVE_PWD_H */
  2094.             }
  2095.         }
  2096.     } /* Use specified name */
  2097.     else {
  2098.         char princ_realm[256];
  2099.         if ( (strlen(init->principal) +
  2100.       (init->instance ? strlen(init->instance)+1 : 0) +
  2101.       strlen(init->realm ? init->realm : krb5_d_realm)
  2102.       + 2) > 255 )
  2103.              goto exit_k5_init;
  2104.         strcpy(princ_realm,init->principal);
  2105.         if (init->instance) {
  2106.             strcat(princ_realm,"/");
  2107.             strcat(princ_realm,init->instance);
  2108.         }
  2109.         strcat(princ_realm,"@");
  2110.         if ( init->realm )
  2111.             strcat(princ_realm,init->realm);
  2112.         else
  2113.             strcat(princ_realm,krb5_d_realm);
  2114.         if ((code = krb5_parse_name (kcontext, princ_realm, &me))) {
  2115.             com_err("krb5_kinit",code,"when parsing name",
  2116.                      princ_realm);
  2117.             goto exit_k5_init;
  2118.         }
  2119.     }
  2120.     if ( init->realm == NULL ) {
  2121.         /* Save the realm */
  2122.         memcpy(realm,krb5_princ_realm(kcontext, me)->data,
  2123.                 krb5_princ_realm(kcontext, me)->length);
  2124.         realm[krb5_princ_realm(kcontext, me)->length]='';
  2125.     } else {
  2126.         strcpy(realm,init->realm);
  2127.     }
  2128.     if ((code = krb5_unparse_name(kcontext, me, &client_name))) {
  2129. com_err("krb5_kinit",code,"when unparsing name");
  2130.         goto exit_k5_init;
  2131.     }
  2132.     memset((char *)&my_creds, 0, sizeof(my_creds));
  2133.     my_creds.client = me;
  2134.     if (init->service == NULL) {
  2135.         if ((code =
  2136.      krb5_build_principal_ext(kcontext,
  2137.       &server,
  2138.       strlen(realm),realm,
  2139.       tgtname.length, tgtname.data,
  2140.       strlen(realm),realm,
  2141.       0))) {
  2142.             com_err("krb5_kinit",code,"while building server name");
  2143.             goto exit_k5_init;
  2144.         }
  2145.     } else {
  2146.         if (code = krb5_parse_name(kcontext, init->service, &server)) {
  2147.             com_err("krb5_kinit",code,"while parsing service name",
  2148.     init->service);
  2149.             goto exit_k5_init;
  2150.         }
  2151.     }
  2152.     my_creds.server = server;
  2153.     if (options & KDC_OPT_POSTDATED) {
  2154.         my_creds.times.starttime = starttime;
  2155.         my_creds.times.endtime = starttime + lifetime;
  2156.     } else {
  2157.         my_creds.times.starttime = 0; /* start timer when request
  2158.    gets to KDC */
  2159.         my_creds.times.endtime = now + lifetime;
  2160.     }
  2161.     if (options & KDC_OPT_RENEWABLE) {
  2162. my_creds.times.renew_till = now + rlife;
  2163.     } else
  2164. my_creds.times.renew_till = 0;
  2165.     if (options & KDC_OPT_VALIDATE) {
  2166.         /* don't use get_in_tkt, just use mk_req... */
  2167.         krb5_data outbuf;
  2168.         code = krb5_validate_tgt(kcontext, ccache, server, &outbuf);
  2169. if (code) {
  2170.             com_err("krb5_kinit",code,"validating tgt");
  2171.             goto exit_k5_init;
  2172. }
  2173. /* should be done... */
  2174.         goto exit_k5_init;
  2175.     }
  2176.     if (options & KDC_OPT_RENEW) {
  2177.         /* don't use get_in_tkt, just use mk_req... */
  2178.         krb5_data outbuf;
  2179.         code = krb5_renew_tgt(kcontext, ccache, server, &outbuf);
  2180. if (code) {
  2181.             com_err("krb5_kinit",code,"while renewing tgt");
  2182.             goto exit_k5_init;
  2183. }
  2184. /* should be done... */
  2185.         goto exit_k5_init;
  2186.     }
  2187.     if ( init->addrs ) {
  2188.         /* construct an array of krb5_address structs to pass to get_in_tkt */
  2189.         /* include both the local ip addresses as well as any other that    */
  2190.         /* are specified.                                                   */
  2191.         unsigned long ipaddr;
  2192.         for ( addr_count=0;addr_count<KRB5_NUM_OF_ADDRS;addr_count++ )
  2193.             if ( init->addrs[addr_count] == NULL )
  2194.                 break;
  2195.         if (addr_count > 0) {
  2196.             krb5_address ** local_addrs=NULL;
  2197.             krb5_os_localaddr(kcontext, &local_addrs);
  2198.             i = 0;
  2199.             while ( local_addrs[i] )
  2200.                 i++;
  2201.             addr_count += i;
  2202.             addrs = (krb5_address **)
  2203.       malloc((addr_count+1) * sizeof(krb5_address));
  2204.             if ( !addrs ) {
  2205.                 krb5_free_addresses(kcontext, local_addrs);
  2206.                 goto exit_k5_init;
  2207.             }
  2208.             memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
  2209.             i = 0;
  2210.             while ( local_addrs[i] ) {
  2211.                 addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
  2212.                 if (addrs[i] == NULL) {
  2213.                     krb5_free_addresses(kcontext, local_addrs);
  2214.                     goto exit_k5_init;
  2215.                 }
  2216.                 addrs[i]->magic = local_addrs[i]->magic;
  2217.                 addrs[i]->addrtype = local_addrs[i]->addrtype;
  2218.                 addrs[i]->length = local_addrs[i]->length;
  2219.                 addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
  2220.                 if (!addrs[i]->contents) {
  2221.                     krb5_free_addresses(kcontext, local_addrs);
  2222.                     goto exit_k5_init;
  2223.                 }
  2224.                 memcpy(addrs[i]->contents,local_addrs[i]->contents,
  2225.                         local_addrs[i]->length);
  2226.                 i++;
  2227.             }
  2228.             krb5_free_addresses(kcontext, local_addrs);
  2229.             for ( j=0;i<addr_count;i++,j++ ) {
  2230.                 addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
  2231.                 if (addrs[i] == NULL)
  2232.                     goto exit_k5_init;
  2233.                 addrs[i]->magic = KV5M_ADDRESS;
  2234.                 addrs[i]->addrtype = AF_INET;
  2235.                 addrs[i]->length = 4;
  2236.                 addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
  2237.                 if (!addrs[i]->contents)
  2238.                     goto exit_k5_init;
  2239.                 ipaddr = inet_addr(init->addrs[j]);
  2240.                 memcpy(addrs[i]->contents,&ipaddr,4);
  2241.             }
  2242.         }
  2243.      }
  2244. #ifndef NO_KEYTAB
  2245.     if (!use_keytab)
  2246. #endif
  2247.     {
  2248.         pwsize = strlen(init->password);
  2249.         if (pwsize == 0) {
  2250.             printf("A password must be specified for %s.rn",client_name);
  2251.             memset(init->password, 0, pwsize);
  2252.             goto exit_k5_init;
  2253.         }
  2254.  code = krb5_get_in_tkt_with_password(kcontext, options, addrs,
  2255.       NULL, preauth, init->password,
  2256.                                                0, &my_creds, 0);
  2257.  memset(init->password, 0, pwsize);
  2258. #ifndef NO_KEYTAB
  2259.     } else {
  2260.         code = krb5_get_in_tkt_with_keytab(kcontext, options, addrs,
  2261.     NULL, preauth, keytab, 0,
  2262.     &my_creds, 0);
  2263. #endif
  2264.     }
  2265.     if (code) {
  2266. switch (code) {
  2267.         case KRB5KRB_AP_ERR_BAD_INTEGRITY:
  2268.     printf("Password incorrectrn");
  2269.             goto exit_k5_init;
  2270.         case KRB5KRB_AP_ERR_V4_REPLY:
  2271.             if (init->getk4) {
  2272.                 printf("Kerberos 5 Tickets not support by server.  ");
  2273.                 printf("A version 4 Ticket will be requested.rn");
  2274.             }
  2275.             goto exit_k5_init;
  2276.         default:
  2277.             goto exit_k5_init;
  2278.         }
  2279.     }
  2280.     code = krb5_cc_initialize (kcontext, ccache, me);
  2281.     if (code != 0) {
  2282. com_err("krb5_kinit",code,"when initializing cache",
  2283.  op->cache);
  2284.         goto exit_k5_init;
  2285.     }
  2286.     code = krb5_cc_store_cred(kcontext, ccache, &my_creds);
  2287.     if (code) {
  2288. com_err("krb5_kinit",code,"while storing credentials");
  2289.         goto exit_k5_init;
  2290.     }
  2291. exit_k5_init:
  2292.     /* Free krb5_address structures if we created them */
  2293.     if ( addrs ) {
  2294.         for ( i=0;i<addr_count;i++ ) {
  2295.             if ( addrs[i] ) {
  2296.                 if ( addrs[i]->contents )
  2297.                     free(addrs[i]->contents);
  2298.                 free(addrs[i]);
  2299.             }
  2300.         }
  2301.     }
  2302.     /* my_creds is pointing at server */
  2303.     krb5_free_principal(kcontext, server);
  2304.     krb5_cc_close(kcontext,ccache);
  2305.     krb5_free_context(kcontext);
  2306.     krb5_errno = code;
  2307.     makestr(&krb5_errmsg,error_message(krb5_errno));
  2308.     if ( init->getk4 && code == KRB5KRB_AP_ERR_V4_REPLY )
  2309.         return(0);
  2310.     printf("Result from realm %s: %srn",realm,
  2311.             code?error_message(code):"OK");
  2312.     return(code?-1:0);
  2313. }
  2314. #define VALIDATE 0
  2315. #define RENEW 1
  2316. /* stripped down version of krb5_mk_req */
  2317. static krb5_error_code
  2318. #ifdef CK_ANSIC
  2319. krb5_validate_tgt( krb5_context context,
  2320.                    krb5_ccache ccache,
  2321.                    krb5_principal     server, /* tgtname */
  2322.                    krb5_data *outbuf )
  2323. #else
  2324. krb5_validate_tgt(context, ccache, server, outbuf)
  2325.      krb5_context context;
  2326.      krb5_ccache ccache;
  2327.      krb5_principal     server; /* tgtname */
  2328.      krb5_data *outbuf;
  2329. #endif
  2330. {
  2331.     return krb5_tgt_gen(context, ccache, server, outbuf, VALIDATE);
  2332. }
  2333. /* stripped down version of krb5_mk_req */
  2334. static krb5_error_code
  2335. #ifdef CK_ANSIC
  2336. krb5_renew_tgt(krb5_context context,
  2337.                 krb5_ccache ccache,
  2338.                 krb5_principal   server, /* tgtname */
  2339.                 krb5_data *outbuf)
  2340. #else
  2341. krb5_renew_tgt(context, ccache, server, outbuf)
  2342.      krb5_context context;
  2343.      krb5_ccache ccache;
  2344.      krb5_principal   server; /* tgtname */
  2345.      krb5_data *outbuf;
  2346. #endif
  2347. {
  2348.     return krb5_tgt_gen(context, ccache, server, outbuf, RENEW);
  2349. }
  2350. /* stripped down version of krb5_mk_req */
  2351. static krb5_error_code
  2352. #ifdef CK_ANSIC
  2353. krb5_tgt_gen(krb5_context context,
  2354.               krb5_ccache ccache,
  2355.               krb5_principal   server, /* tgtname */
  2356.               krb5_data *outbuf,
  2357.               int opt)
  2358. #else
  2359. krb5_tgt_gen(context, ccache, server, outbuf, opt)
  2360.      krb5_context context;
  2361.      krb5_ccache ccache;
  2362.      krb5_principal   server; /* tgtname */
  2363.      krb5_data *outbuf;
  2364.      int opt;
  2365. #endif
  2366. {
  2367.     krb5_error_code    retval;
  2368.     krb5_creds  * credsp;
  2369.     krb5_creds    creds;
  2370.     /* obtain ticket & session key */
  2371.     memset((char *)&creds, 0, sizeof(creds));
  2372.     if ((retval = krb5_copy_principal(context, server, &creds.server)))
  2373. goto cleanup;
  2374.     if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)))
  2375. goto cleanup_creds;
  2376.     if (opt == VALIDATE) {
  2377. if ((retval = krb5_get_credentials_validate(context, 0,
  2378.     ccache, &creds, &credsp)))
  2379.   goto cleanup_creds;
  2380.     } else {
  2381. if ((retval = krb5_get_credentials_renew(context, 0,
  2382.  ccache, &creds, &credsp)))
  2383.   goto cleanup_creds;
  2384.     }
  2385.     /* we don't actually need to do the mk_req, just get the creds. */
  2386. cleanup_creds:
  2387.     krb5_free_cred_contents(context, &creds);
  2388. cleanup:
  2389.     return retval;
  2390. }
  2391. #endif /* KINIT */
  2392. #ifdef KDESTROY
  2393. int
  2394. #ifdef CK_ANSIC
  2395. ck_krb5_destroy(struct krb_op_data * op)
  2396. #else
  2397. ck_krb5_destroy(op) struct krb_op_data * op;
  2398. #endif
  2399. {
  2400.     krb5_context kcontext;
  2401.     krb5_error_code retval;
  2402.     int c;
  2403.     krb5_ccache ccache = NULL;
  2404.     char *cache_name = NULL;
  2405.     int code;
  2406.     int errflg=0;
  2407.     int quiet = 0;
  2408.     if ( !ck_krb5_is_installed() )
  2409.         return(-1);
  2410.     code = krb5_init_context(&kcontext);
  2411.     if (code) {
  2412.         debug(F101,"ck_krb5_destroy while initializing krb5","",code);
  2413.         krb5_errno = code;
  2414.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2415.         return(-1);
  2416.     }
  2417.     code = k5_get_ccache(kcontext,&ccache,op->cache);
  2418.     if (code != 0) {
  2419.         debug(F101,"ck_krb5_destroy while getting ccache",
  2420.                "",code);
  2421.         krb5_free_context(kcontext);
  2422.         krb5_errno = code;
  2423.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2424.         return(-1);
  2425.     }
  2426.     code = krb5_cc_destroy (kcontext, ccache);
  2427.     if (code != 0) {
  2428. debug(F101,"ck_krb5_destroy while destroying cache","",code);
  2429.         if ( code == KRB5_FCC_NOFILE )
  2430.             printf("No ticket cache to destroy.rn");
  2431.         else
  2432.             printf("Ticket cache NOT destroyed!rn");
  2433.         krb5_cc_close(kcontext,ccache);
  2434.         krb5_free_context(kcontext);
  2435.         krb5_errno = code;
  2436.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2437. return(-1);
  2438.     }
  2439.     printf("Tickets destroyed.rn");
  2440.     /* Do not call krb5_cc_close() because cache has been destroyed */
  2441.     krb5_free_context(kcontext);
  2442.     krb5_errno = code;
  2443.     makestr(&krb5_errmsg,error_message(krb5_errno));
  2444.     return (0);
  2445. }
  2446. #endif /* KDESTROY */
  2447. #ifdef KLIST
  2448. static int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
  2449. static int show_etype = 0, show_addr = 0;
  2450. static char *defname;
  2451. static char *progname;
  2452. static krb5_int32 now;
  2453. static int timestamp_width;
  2454. static char * etype_string KRB5_PROTOTYPE((krb5_enctype ));
  2455. static void show_credential KRB5_PROTOTYPE((krb5_context,
  2456.                                              krb5_creds *));
  2457. static int do_ccache KRB5_PROTOTYPE((krb5_context,char *));
  2458. static int do_keytab KRB5_PROTOTYPE((krb5_context,char *));
  2459. static void printtime KRB5_PROTOTYPE((time_t));
  2460. static void fillit KRB5_PROTOTYPE((int, int));
  2461. #define DEFAULT 0
  2462. #define CCACHE 1
  2463. #define KEYTAB 2
  2464. int
  2465. #ifdef CK_ANSIC
  2466. ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
  2467. #else
  2468. ck_krb5_list_creds(op,lc)
  2469.     struct krb_op_data * op; struct krb5_list_cred_data * lc;
  2470. #endif
  2471. {
  2472.     krb5_context kcontext;
  2473.     krb5_error_code retval;
  2474.     int code;
  2475.     char *name = op->cache;
  2476.     int mode;
  2477.     if ( !ck_krb5_is_installed() )
  2478.         return(-1);
  2479.     code = krb5_init_context(&kcontext);
  2480.     if (code) {
  2481.         debug(F101,"ck_krb5_list_creds while initializing krb5","",code);
  2482.         krb5_errno = code;
  2483.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2484.         return(-1);
  2485.     }
  2486.     name = op->cache;
  2487.     mode = DEFAULT;
  2488.     show_flags = 0;
  2489.     show_time = 0;
  2490.     status_only = 0;
  2491.     show_keys = 0;
  2492.     show_etype = 0;
  2493.     show_addr = 0;
  2494.     show_flags = lc->flags;
  2495.     show_etype = lc->encryption;
  2496.     show_addr  = lc->addr;
  2497.     show_time = 1;
  2498.     show_keys = 1;
  2499.     mode = CCACHE;
  2500.     if ((code = krb5_timeofday(kcontext, &now))) {
  2501.         if (!status_only)
  2502.             debug(F101,"ck_krb5_list_creds while getting time of day.",
  2503.                    "",code);
  2504.         krb5_free_context(kcontext);
  2505.         krb5_errno = code;
  2506.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2507.         return(-1);
  2508.     }
  2509.     else {
  2510. char tmp[BUFSIZ];
  2511. if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
  2512.     !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), (char *) NULL))
  2513.     timestamp_width = (int) strlen(tmp);
  2514. else
  2515.     timestamp_width = 15;
  2516.     }
  2517.     if (mode == DEFAULT || mode == CCACHE)
  2518.  retval = do_ccache(kcontext,name);
  2519.     else
  2520.  retval = do_keytab(kcontext,name);
  2521.     krb5_free_context(kcontext);
  2522.     return(retval);
  2523. }
  2524. static int
  2525. #ifdef CK_ANSIC
  2526. do_keytab(krb5_context kcontext, char * name)
  2527. #else
  2528. do_keytab(kcontext,name) krb5_context kcontext; char * name;
  2529. #endif
  2530. {
  2531.     krb5_keytab kt;
  2532.     krb5_keytab_entry entry;
  2533.     krb5_kt_cursor cursor;
  2534.     char buf[BUFSIZ]; /* hopefully large enough for any type */
  2535.     char *pname;
  2536.     int code = 0;
  2537.     if (name == NULL) {
  2538.         if ((code = krb5_kt_default(kcontext, &kt))) {
  2539.             debug(F101,"ck_krb5_list_creds while getting default keytab",
  2540.                    "",code);
  2541.             krb5_errno = code;
  2542.             makestr(&krb5_errmsg,error_message(krb5_errno));
  2543.             return(-1);
  2544.         }
  2545.     } else {
  2546.         if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
  2547.             debug(F111,"ck_krb5_list_creds while resolving keytab",
  2548.                      name,code);
  2549.             krb5_errno = code;
  2550.             makestr(&krb5_errmsg,error_message(krb5_errno));
  2551.             return(-1);
  2552.         }
  2553.     }
  2554.     if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
  2555.         debug(F101,"ck_krb5_list_creds while getting keytab name",
  2556.                "",code);
  2557.         krb5_errno = code;
  2558.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2559.         return(-1);
  2560.     }
  2561.      printf("Keytab name: %srn", buf);
  2562.      if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
  2563.          debug(F101,"ck_krb5_list_creds while starting keytab scan",
  2564.                 "",code);
  2565.          krb5_errno = code;
  2566.          makestr(&krb5_errmsg,error_message(krb5_errno));
  2567.          return(-1);
  2568.      }
  2569.      if (show_time) {
  2570.   printf("KVNO Timestamp");
  2571.           fillit(timestamp_width - sizeof("Timestamp") + 2, (int) ' ');
  2572.   printf("Principalrn");
  2573.   printf("---- ");
  2574.   fillit(timestamp_width, (int) '-');
  2575.   printf(" ");
  2576.   fillit(78 - timestamp_width - sizeof("KVNO"), (int) '-');
  2577.   printf("rn");
  2578.      } else {
  2579.   printf("KVNO Principalrn");
  2580.   printf(
  2581. "---- --------------------------------------------------------------------
  2582. ------rn");
  2583.      }
  2584.     while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
  2585.         if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
  2586.             debug(F101,"ck_krb5_list_creds while unparsing principal name",
  2587.                    "",code);
  2588.             krb5_errno = code;
  2589.             makestr(&krb5_errmsg,error_message(krb5_errno));
  2590.             return(-1);
  2591.         }
  2592.         printf("%4d ", entry.vno);
  2593.         if (show_time) {
  2594.             printtime(entry.timestamp);
  2595.             printf(" ");
  2596.         }
  2597.         printf("%s", pname);
  2598.         if (show_etype)
  2599.             printf(" (%s) " , etype_string(entry.key.enctype));
  2600.         if (show_keys) {
  2601.             printf(" (0x");
  2602.             {
  2603.                 int i;
  2604.                 for (i = 0; i < entry.key.length; i++)
  2605.                     printf("%02x", entry.key.contents[i]);
  2606.             }
  2607.             printf(")");
  2608.         }
  2609.         printf("rn");
  2610.         krb5_free_unparsed_name(kcontext,pname);
  2611.     }
  2612.     if (code && code != KRB5_KT_END) {
  2613.         debug(F101,"ck_krb5_list_creds while scanning keytab",
  2614.                "",code);
  2615.         krb5_errno = code;
  2616.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2617.         return(-1);
  2618.     }
  2619.     if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
  2620.         debug(F101,"ck_krb5_list_creds while ending keytab scan",
  2621.                "",code);
  2622.         krb5_errno = code;
  2623.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2624.         return(-1);
  2625.     }
  2626.     krb5_errno = code;
  2627.     makestr(&krb5_errmsg,error_message(krb5_errno));
  2628.     return(0);
  2629. }
  2630. static int
  2631. #ifdef CK_ANSIC
  2632. do_ccache(krb5_context kcontext, char * cc_name)
  2633. #else
  2634. do_ccache(kcontext,name) krb5_context kcontext; char * cc_name;
  2635. #endif
  2636. {
  2637.     krb5_ccache cache = NULL;
  2638.     krb5_cc_cursor cur;
  2639.     krb5_creds creds;
  2640.     krb5_principal princ=NULL;
  2641.     krb5_flags flags=0;
  2642.     krb5_error_code code = 0;
  2643.     int exit_status = 0;
  2644.     if (status_only)
  2645. /* exit_status is set back to 0 if a valid tgt is found */
  2646. exit_status = 1;
  2647.     code = k5_get_ccache(kcontext,&cache,cc_name);
  2648.     if (code != 0) {
  2649.         debug(F111,"do_ccache while getting ccache",
  2650.                error_message(code),code);
  2651.         krb5_errno = code;
  2652.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2653.         return(-1);
  2654.     }
  2655.     flags = 0; /* turns off OPENCLOSE mode */
  2656.     if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  2657. if (code == ENOENT) {
  2658.             debug(F111,"ck_krb5_list_creds (ticket cache)",
  2659.                    krb5_cc_get_name(kcontext, cache),code);
  2660. } else {
  2661.             debug(F111,
  2662.  "ck_krb5_list_creds while setting cache flags (ticket cache)",
  2663.                   krb5_cc_get_name(kcontext, cache),code);
  2664. }
  2665.         printf("No ticket File.rn");
  2666.         krb5_errno = code;
  2667.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2668.         krb5_cc_close(kcontext,cache);
  2669. return(-1);
  2670.     }
  2671.     if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  2672.         debug(F101,"ck_krb5_list_creds while retrieving principal name",
  2673.                "",code);
  2674.         krb5_errno = code;
  2675.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2676.         krb5_cc_close(kcontext,cache);
  2677. return(-1);
  2678.     }
  2679.     if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  2680.         debug(F101,"ck_krb5_list_creds while unparsing principal name",
  2681.                "",code);
  2682.         krb5_errno = code;
  2683.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2684.         krb5_cc_close(kcontext,cache);
  2685. return(-1);
  2686.     }
  2687.     if (!status_only) {
  2688. printf("Ticket cache:      %s:%srnDefault principal: %srnrn",
  2689.                 krb5_cc_get_type(kcontext, cache),
  2690.                 krb5_cc_get_name(kcontext, cache), defname);
  2691. printf("Valid starting");
  2692. fillit(timestamp_width - sizeof("Valid starting") + 3,
  2693.        (int) ' ');
  2694. printf("Expires");
  2695. fillit(timestamp_width - sizeof("Expires") + 3,
  2696.        (int) ' ');
  2697. printf("Service principalrn");
  2698.     }
  2699.     if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  2700.         debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
  2701.                "",code);
  2702.         krb5_errno = code;
  2703.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2704.         krb5_cc_close(kcontext,cache);
  2705. return(-1);
  2706.     }
  2707.     while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  2708. if (status_only) {
  2709.     if (exit_status && creds.server->length == 2 &&
  2710. strcmp(creds.server->realm.data, princ->realm.data) == 0 &&
  2711. strcmp((char *)creds.server->data[0].data, "krbtgt") == 0 &&
  2712. strcmp((char *)creds.server->data[1].data,
  2713.        princ->realm.data) == 0 &&
  2714. creds.times.endtime > now)
  2715. exit_status = 0;
  2716. } else {
  2717.     show_credential(kcontext, &creds);
  2718. }
  2719. krb5_free_cred_contents(kcontext, &creds);
  2720.     }
  2721.     printf("rn");
  2722.     if (code == KRB5_CC_END || code == KRB5_CC_NOTFOUND) {
  2723. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  2724.             debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
  2725.                    "",code);
  2726.             krb5_errno = code;
  2727.             makestr(&krb5_errmsg,error_message(krb5_errno));
  2728.             krb5_cc_close(kcontext,cache);
  2729.     return(-1);
  2730. }
  2731. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  2732. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  2733.             debug(F101,"ck_krb5_list_creds while closing ccache",
  2734.                    "",code);
  2735.             krb5_errno = code;
  2736.             makestr(&krb5_errmsg,error_message(krb5_errno));
  2737.             krb5_cc_close(kcontext,cache);
  2738.     return(-1);
  2739. }
  2740.         krb5_errno = code;
  2741.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2742.         krb5_cc_close(kcontext,cache);
  2743. return(exit_status);
  2744.     } else {
  2745.         debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
  2746.         krb5_errno = code;
  2747.         makestr(&krb5_errmsg,error_message(krb5_errno));
  2748.         krb5_cc_close(kcontext,cache);
  2749. return(-1);
  2750.     }
  2751.     krb5_errno = code;
  2752.     makestr(&krb5_errmsg,error_message(krb5_errno));
  2753.     krb5_cc_close(kcontext,cache);
  2754.     return(0);
  2755. }
  2756. static char *
  2757. #ifdef CK_ANSIC
  2758. etype_string(krb5_enctype enctype)
  2759. #else
  2760. etype_string(enctype) krb5_enctype enctype;
  2761. #endif
  2762. {
  2763.     static char buf[12];
  2764.     switch (enctype) {
  2765.     case ENCTYPE_NULL:
  2766.         return "NULL";
  2767.     case ENCTYPE_DES_CBC_CRC:
  2768. return "DES-CBC-CRC";
  2769.     case ENCTYPE_DES_CBC_MD4:
  2770. return "DES-CBC-MD4";
  2771.     case ENCTYPE_DES_CBC_MD5:
  2772. return "DES-CBC-MD5";
  2773.     case ENCTYPE_DES3_CBC_SHA:
  2774. return "DES3-CBC-SHA";
  2775.     case ENCTYPE_DES_CBC_RAW:
  2776.         return "DES-CBC-RAW";
  2777.     case ENCTYPE_DES3_CBC_RAW:
  2778.         return "DES3-CBC-RAW";
  2779.     case ENCTYPE_DES3_HMAC_SHA1:
  2780.         return "DES3-HMAC-SHA1";
  2781.     case ENCTYPE_DES_HMAC_SHA1:
  2782.         return "DES-HMAC-SHA1";
  2783.     case ENCTYPE_UNKNOWN:
  2784.         return "UNKNOWN";
  2785.     case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
  2786.         return "LOCAL-DES3-HMAC-SHA1";
  2787.     default:
  2788. sprintf(buf, "etype %d", enctype);
  2789. return buf;
  2790. break;
  2791.     }
  2792. }
  2793. static char *
  2794. #ifdef CK_ANSIC
  2795. flags_string(register krb5_creds *cred)
  2796. #else
  2797. flags_string(cred) register krb5_creds *cred;
  2798. #endif
  2799. {
  2800.     static char buf[32];
  2801.     int i = 0;
  2802.     if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
  2803.         buf[i++] = 'F';
  2804.     if (cred->ticket_flags & TKT_FLG_FORWARDED)
  2805.         buf[i++] = 'f';
  2806.     if (cred->ticket_flags & TKT_FLG_PROXIABLE)
  2807.         buf[i++] = 'P';
  2808.     if (cred->ticket_flags & TKT_FLG_PROXY)
  2809.         buf[i++] = 'p';
  2810.     if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
  2811.         buf[i++] = 'D';
  2812.     if (cred->ticket_flags & TKT_FLG_POSTDATED)
  2813.         buf[i++] = 'd';
  2814.     if (cred->ticket_flags & TKT_FLG_INVALID)
  2815.         buf[i++] = 'i';
  2816.     if (cred->ticket_flags & TKT_FLG_RENEWABLE)
  2817.         buf[i++] = 'R';
  2818.     if (cred->ticket_flags & TKT_FLG_INITIAL)
  2819.         buf[i++] = 'I';
  2820.     if (cred->ticket_flags & TKT_FLG_HW_AUTH)
  2821.         buf[i++] = 'H';
  2822.     if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
  2823.         buf[i++] = 'A';
  2824.     buf[i] = '';
  2825.     return(buf);
  2826. }
  2827. static char   *