X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fkssl.c;h=21172f31d5aedd7d05c5d45a3d47582a19e62d70;hb=23a22b4cf72b0c2aadcd65001d4a28941d570547;hp=b8192cdfc719d937d6baaa3035326be86cb67818;hpb=fe8bf9560dbe5998e8857869508d2fe4b4f5dbf6;p=oweals%2Fopenssl.git diff --git a/ssl/kssl.c b/ssl/kssl.c index b8192cdfc7..21172f31d5 100644 --- a/ssl/kssl.c +++ b/ssl/kssl.c @@ -56,21 +56,19 @@ */ -/* ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl -** -** 19990701 VRS Started. -** 200011?? Jeffrey Altman, Richard Levitte -** Generalized for Heimdal, Newer MIT, & Win32. -** Integrated into main OpenSSL 0.9.7 snapshots. -** 20010413 Simon Wilkinson, VRS -** Real RFC2712 KerberosWrapper replaces AP_REQ. -*/ +/*- + * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl + * + * 19990701 VRS Started. + * 200011?? Jeffrey Altman, Richard Levitte + * Generalized for Heimdal, Newer MIT, & Win32. + * Integrated into main OpenSSL 0.9.7 snapshots. + * 20010413 Simon Wilkinson, VRS + * Real RFC2712 KerberosWrapper replaces AP_REQ. + */ #include -#define _XOPEN_SOURCE 500 /* glibc2 needs this to declare strptime() */ -#include -#undef _XOPEN_SOURCE /* To avoid clashes with anything else... */ #include #define KRB5_PRIVATE 1 @@ -79,6 +77,7 @@ #include #include #include +#include "kssl_lcl.h" #ifndef OPENSSL_NO_KRB5 @@ -134,7 +133,7 @@ #define krb5_principal_compare kssl_krb5_principal_compare #define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part #define krb5_timeofday kssl_krb5_timeofday -#define krb5_rc_default kssl_krb5_rc_default +#define krb5_rc_default kssl_krb5_rc_default #ifdef krb5_rc_initialize #undef krb5_rc_initialize @@ -295,7 +294,7 @@ load_krb5_dll(void) HANDLE hKRB5_32; krb5_loaded++; - hKRB5_32 = LoadLibrary("KRB5_32"); + hKRB5_32 = LoadLibrary(TEXT("KRB5_32")); if (!hKRB5_32) return; @@ -782,6 +781,25 @@ kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, } #endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ + +/* memory allocation functions for non-temporary storage + * (e.g. stuff that gets saved into the kssl context) */ +static void* kssl_calloc(size_t nmemb, size_t size) +{ + void* p; + + p=OPENSSL_malloc(nmemb*size); + if (p){ + memset(p, 0, nmemb*size); + } + return p; +} + +#define kssl_malloc(size) OPENSSL_malloc((size)) +#define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size) +#define kssl_free(ptr) OPENSSL_free((ptr)) + + char *kstring(char *string) { @@ -791,10 +809,10 @@ char } /* Given KRB5 enctype (basically DES or 3DES), -** return closest match openssl EVP_ encryption algorithm. -** Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes. -** Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK. -*/ + * return closest match openssl EVP_ encryption algorithm. + * Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes. + * Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK. + */ const EVP_CIPHER * kssl_map_enc(krb5_enctype enctype) { @@ -819,11 +837,11 @@ kssl_map_enc(krb5_enctype enctype) /* Return true:1 if p "looks like" the start of the real authenticator -** described in kssl_skip_confound() below. The ASN.1 pattern is -** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and -** xx and yy are possibly multi-byte length fields. -*/ -int kssl_test_confound(unsigned char *p) + * described in kssl_skip_confound() below. The ASN.1 pattern is + * "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and + * xx and yy are possibly multi-byte length fields. + */ +static int kssl_test_confound(unsigned char *p) { int len = 2; int xx = 0, yy = 0; @@ -849,16 +867,16 @@ int kssl_test_confound(unsigned char *p) } /* Allocate, fill, and return cksumlens array of checksum lengths. -** This array holds just the unique elements from the krb5_cksumarray[]. -** array[n] == 0 signals end of data. -** -** The krb5_cksumarray[] was an internal variable that has since been -** replaced by a more general method for storing the data. It should -** not be used. Instead we use real API calls and make a guess for -** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 -** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. -*/ -size_t *populate_cksumlens(void) + * This array holds just the unique elements from the krb5_cksumarray[]. + * array[n] == 0 signals end of data. + * + * The krb5_cksumarray[] was an internal variable that has since been + * replaced by a more general method for storing the data. It should + * not be used. Instead we use real API calls and make a guess for + * what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 + * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. + */ +static size_t *populate_cksumlens(void) { int i, j, n; static size_t *cklens = NULL; @@ -889,13 +907,14 @@ size_t *populate_cksumlens(void) return cklens; } -/* Return pointer to start of real authenticator within authenticator, or -** return NULL on error. -** Decrypted authenticator looks like this: -** [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] -** This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the -** krb5_auth_con_getcksumtype() function advertised in its krb5.h. -*/ +/*- + * Return pointer to start of real authenticator within authenticator, or + * return NULL on error. + * Decrypted authenticator looks like this: + * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] + * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the + * krb5_auth_con_getcksumtype() function advertised in its krb5.h. + */ unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) { int i, conlen; @@ -917,15 +936,15 @@ unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) /* Set kssl_err error info when reason text is a simple string -** kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; } -*/ + * kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; } + */ void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) { if (kssl_err == NULL) return; kssl_err->reason = reason; - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, text); + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); return; } @@ -937,15 +956,15 @@ print_krb5_data(char *label, krb5_data *kdata) { int i; - printf("%s[%d] ", label, kdata->length); + fprintf(stderr,"%s[%d] ", label, kdata->length); for (i=0; i < (int)kdata->length; i++) { if (0 && isprint((int) kdata->data[i])) - printf( "%c ", kdata->data[i]); + fprintf(stderr, "%c ", kdata->data[i]); else - printf( "%02x ", (unsigned char) kdata->data[i]); + fprintf(stderr, "%02x ", (unsigned char) kdata->data[i]); } - printf("\n"); + fprintf(stderr,"\n"); } @@ -956,20 +975,20 @@ print_krb5_authdata(char *label, krb5_authdata **adata) { if (adata == NULL) { - printf("%s, authdata==0\n", label); + fprintf(stderr,"%s, authdata==0\n", label); return; } - printf("%s [%p]\n", label, (void *)adata); + fprintf(stderr,"%s [%p]\n", label, (void *)adata); #if 0 { int i; - printf("%s[at%d:%d] ", label, adata->ad_type, adata->length); + fprintf(stderr,"%s[at%d:%d] ", label, adata->ad_type, adata->length); for (i=0; i < adata->length; i++) { - printf((isprint(adata->contents[i]))? "%c ": "%02x", + fprintf(stderr,(isprint(adata->contents[i]))? "%c ": "%02x", adata->contents[i]); } - printf("\n"); + fprintf(stderr,"\n"); } #endif } @@ -984,62 +1003,62 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk) if (keyblk == NULL) { - printf("%s, keyblk==0\n", label); + fprintf(stderr,"%s, keyblk==0\n", label); return; } #ifdef KRB5_HEIMDAL - printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, + fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->keytype, keyblk->keyvalue->length); for (i=0; i < (int)keyblk->keyvalue->length; i++) { - printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); + fprintf(stderr,"%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); } - printf("\n"); + fprintf(stderr,"\n"); #else - printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); + fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); for (i=0; i < (int)keyblk->length; i++) { - printf("%02x",keyblk->contents[i]); + fprintf(stderr,"%02x",keyblk->contents[i]); } - printf("\n"); + fprintf(stderr,"\n"); #endif } /* Display contents of krb5_principal_data struct, for debugging -** (krb5_principal is typedef'd == krb5_principal_data *) -*/ -void + * (krb5_principal is typedef'd == krb5_principal_data *) + */ +static void print_krb5_princ(char *label, krb5_principal_data *princ) { int i, ui, uj; - printf("%s principal Realm: ", label); + fprintf(stderr,"%s principal Realm: ", label); if (princ == NULL) return; for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.data[ui]); - printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); + fprintf(stderr," (nametype %d) has %d strings:\n", princ->type,princ->length); for (i=0; i < (int)princ->length; i++) { - printf("\t%d [%d]: ", i, princ->data[i].length); + fprintf(stderr,"\t%d [%d]: ", i, princ->data[i].length); for (uj=0; uj < (int)princ->data[i].length; uj++) { putchar(princ->data[i].data[uj]); } - printf("\n"); + fprintf(stderr,"\n"); } return; } -/* Given krb5 service (typically "kssl") and hostname in kssl_ctx, -** Return encrypted Kerberos ticket for service @ hostname. -** If authenp is non-NULL, also return encrypted authenticator, -** whose data should be freed by caller. -** (Originally was: Create Kerberos AP_REQ message for SSL Client.) -** -** 19990628 VRS Started; Returns Kerberos AP_REQ message. -** 20010409 VRS Modified for RFC2712; Returns enc tkt. -** 20010606 VRS May also return optional authenticator. -*/ +/*- Given krb5 service (typically "kssl") and hostname in kssl_ctx, + * Return encrypted Kerberos ticket for service @ hostname. + * If authenp is non-NULL, also return encrypted authenticator, + * whose data should be freed by caller. + * (Originally was: Create Kerberos AP_REQ message for SSL Client.) + * + * 19990628 VRS Started; Returns Kerberos AP_REQ message. + * 20010409 VRS Modified for RFC2712; Returns enc tkt. + * 20010606 VRS May also return optional authenticator. + */ krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, /* OUT */ krb5_data **enc_ticketp, @@ -1124,8 +1143,8 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, krb5rc = KRB5KRB_ERR_GENERIC; /* caller should free data of krb5_app_req */ /* 20010406 VRS deleted for real KerberosWrapper - ** 20010605 VRS reinstated to offer Authenticator to KerberosWrapper - */ + * 20010605 VRS reinstated to offer Authenticator to KerberosWrapper + */ krb5_app_req.length = 0; if (authenp) { @@ -1197,18 +1216,19 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, } -/* Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. -** Return Kerberos error code and kssl_err struct on error. -** Allocates krb5_ticket and krb5_principal; caller should free these. -** -** 20010410 VRS Implemented krb5_decode_ticket() as -** old_krb5_decode_ticket(). Missing from MIT1.0.6. -** 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. -** Re-used some of the old krb5_decode_ticket() -** code here. This tkt should alloc/free just -** like the real thing. -*/ -krb5_error_code +/*- + * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. + * Return Kerberos error code and kssl_err struct on error. + * Allocates krb5_ticket and krb5_principal; caller should free these. + * + * 20010410 VRS Implemented krb5_decode_ticket() as + * old_krb5_decode_ticket(). Missing from MIT1.0.6. + * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. + * Re-used some of the old krb5_decode_ticket() + * code here. This tkt should alloc/free just + * like the real thing. + */ +static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, /* IN */ KRB5_TKTBODY *asn1ticket, /* OUT */ krb5_ticket **krb5ticket, @@ -1281,13 +1301,14 @@ kssl_TKT2tkt( /* IN */ krb5_context krb5context, } -/* Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), -** and krb5 AP_REQ message & message length, -** Return Kerberos session key and client principle -** to SSL Server in KSSL_CTX *kssl_ctx. -** -** 19990702 VRS Started. -*/ +/*- + * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), + * and krb5 AP_REQ message & message length, + * Return Kerberos session key and client principle + * to SSL Server in KSSL_CTX *kssl_ctx. + * + * 19990702 VRS Started. + */ krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, /* IN */ krb5_data *indata, @@ -1315,7 +1336,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, } #ifdef KSSL_DEBUG - printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); + fprintf(stderr,"in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); #endif /* KSSL_DEBUG */ if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) @@ -1402,19 +1423,20 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, } } - /* Actual Kerberos5 krb5_recvauth() has initial conversation here - ** o check KRB5_SENDAUTH_BADAUTHVERS - ** unless KRB5_RECVAUTH_SKIP_VERSION - ** o check KRB5_SENDAUTH_BADAPPLVERS - ** o send "0" msg if all OK - */ + /*- Actual Kerberos5 krb5_recvauth() has initial conversation here + * o check KRB5_SENDAUTH_BADAUTHVERS + * unless KRB5_RECVAUTH_SKIP_VERSION + * o check KRB5_SENDAUTH_BADAPPLVERS + * o send "0" msg if all OK + */ - /* 20010411 was using AP_REQ instead of true KerberosWrapper - ** - ** if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, - ** &krb5in_data, krb5server, krb5keytab, - ** &ap_option, &krb5ticket)) != 0) { Error } - */ + /*- + * 20010411 was using AP_REQ instead of true KerberosWrapper + * + * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, + * &krb5in_data, krb5server, krb5keytab, + * &ap_option, &krb5ticket)) != 0) { Error } + */ p = (unsigned char *)indata->data; if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p, @@ -1464,18 +1486,18 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, #ifdef KSSL_DEBUG { int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs; - printf("Decrypted ticket fields:\n"); - printf("\tflags: %X, transit-type: %X", + fprintf(stderr,"Decrypted ticket fields:\n"); + fprintf(stderr,"\tflags: %X, transit-type: %X", krb5ticket->enc_part2->flags, krb5ticket->enc_part2->transited.tr_type); print_krb5_data("\ttransit-data: ", &(krb5ticket->enc_part2->transited.tr_contents)); - printf("\tcaddrs: %p, authdata: %p\n", + fprintf(stderr,"\tcaddrs: %p, authdata: %p\n", krb5ticket->enc_part2->caddrs, krb5ticket->enc_part2->authorization_data); if (paddr) { - printf("\tcaddrs:\n"); + fprintf(stderr,"\tcaddrs:\n"); for (i=0; paddr[i] != NULL; i++) { krb5_data d; @@ -1484,7 +1506,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, print_krb5_data("\t\tIP: ", &d); } } - printf("\tstart/auth/end times: %d / %d / %d\n", + fprintf(stderr,"\tstart/auth/end times: %d / %d / %d\n", krb5ticket->enc_part2->times.starttime, krb5ticket->enc_part2->times.authtime, krb5ticket->enc_part2->times.endtime); @@ -1546,13 +1568,13 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, KSSL_CTX * kssl_ctx_new(void) { - return ((KSSL_CTX *) calloc(1, sizeof(KSSL_CTX))); + return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX))); } /* Frees a kssl_ctx struct and any allocated memory it holds. -** Returns NULL. -*/ + * Returns NULL. + */ KSSL_CTX * kssl_ctx_free(KSSL_CTX *kssl_ctx) { @@ -1560,21 +1582,21 @@ kssl_ctx_free(KSSL_CTX *kssl_ctx) if (kssl_ctx->key) OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - if (kssl_ctx->key) free(kssl_ctx->key); - if (kssl_ctx->client_princ) free(kssl_ctx->client_princ); - if (kssl_ctx->service_host) free(kssl_ctx->service_host); - if (kssl_ctx->service_name) free(kssl_ctx->service_name); - if (kssl_ctx->keytab_file) free(kssl_ctx->keytab_file); + if (kssl_ctx->key) kssl_free(kssl_ctx->key); + if (kssl_ctx->client_princ) kssl_free(kssl_ctx->client_princ); + if (kssl_ctx->service_host) kssl_free(kssl_ctx->service_host); + if (kssl_ctx->service_name) kssl_free(kssl_ctx->service_name); + if (kssl_ctx->keytab_file) kssl_free(kssl_ctx->keytab_file); - free(kssl_ctx); + kssl_free(kssl_ctx); return (KSSL_CTX *) NULL; } /* Given an array of (krb5_data *) entity (and optional realm), -** set the plain (char *) client_princ or service_host member -** of the kssl_ctx struct. -*/ + * set the plain (char *) client_princ or service_host member + * of the kssl_ctx struct. + */ krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, krb5_data *realm, krb5_data *entity, int nentities) @@ -1591,7 +1613,7 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, case KSSL_SERVER: princ = &kssl_ctx->service_host; break; default: return KSSL_CTX_ERR; break; } - if (*princ) free(*princ); + if (*princ) kssl_free(*princ); /* Add up all the entity->lengths */ length = 0; @@ -1604,7 +1626,7 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, /* Space for the ('@'+realm+NULL | NULL) */ length += ((realm)? realm->length + 2: 1); - if ((*princ = calloc(1, length)) == NULL) + if ((*princ = kssl_calloc(1, length)) == NULL) return KSSL_CTX_ERR; else { @@ -1627,11 +1649,11 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, } -/* Set one of the plain (char *) string members of the kssl_ctx struct. -** Default values should be: -** which == KSSL_SERVICE => "khost" (KRB5SVC) -** which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) -*/ +/*- Set one of the plain (char *) string members of the kssl_ctx struct. + * Default values should be: + * which == KSSL_SERVICE => "khost" (KRB5SVC) + * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) + */ krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) { @@ -1647,7 +1669,7 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) case KSSL_KEYTAB: string = &kssl_ctx->keytab_file; break; default: return KSSL_CTX_ERR; break; } - if (*string) free(*string); + if (*string) kssl_free(*string); if (!text) { @@ -1655,7 +1677,7 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) return KSSL_CTX_OK; } - if ((*string = calloc(1, strlen(text) + 1)) == NULL) + if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) return KSSL_CTX_ERR; else strcpy(*string, text); @@ -1665,8 +1687,8 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) /* Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx -** struct. Clear kssl_ctx->key if Kerberos session key is NULL. -*/ + * struct. Clear kssl_ctx->key if Kerberos session key is NULL. + */ krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) { @@ -1679,7 +1701,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) if (kssl_ctx->key) { OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - free(kssl_ctx->key); + kssl_free(kssl_ctx->key); } if (session) @@ -1705,7 +1727,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) } if ((kssl_ctx->key = - (krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL) + (krb5_octet FAR *) kssl_calloc(1, kssl_ctx->length)) == NULL) { kssl_ctx->length = 0; return KSSL_CTX_ERR; @@ -1786,6 +1808,9 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx) kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC, KRB5_NT_SRV_HST, &princ); + if (krb5rc) + goto exit; + krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, 0 /* IGNORE_VNO */, @@ -1877,13 +1902,13 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) /* Given pointers to KerberosTime and struct tm structs, convert the -** KerberosTime string to struct tm. Note that KerberosTime is a -** ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional -** seconds as defined in RFC 1510. -** Return pointer to the (partially) filled in struct tm on success, -** return NULL on failure. -*/ -struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) + * KerberosTime string to struct tm. Note that KerberosTime is a + * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional + * seconds as defined in RFC 1510. + * Return pointer to the (partially) filled in struct tm on success, + * return NULL on failure. + */ +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) { char c, *p; @@ -1905,11 +1930,11 @@ struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) /* Helper function for kssl_validate_times(). -** We need context->clockskew, but krb5_context is an opaque struct. -** So we try to sneek the clockskew out through the replay cache. -** If that fails just return a likely default (300 seconds). -*/ -krb5_deltat get_rc_clockskew(krb5_context context) + * We need context->clockskew, but krb5_context is an opaque struct. + * So we try to sneek the clockskew out through the replay cache. + * If that fails just return a likely default (300 seconds). + */ +static krb5_deltat get_rc_clockskew(krb5_context context) { krb5_rcache rc; krb5_deltat clockskew; @@ -1925,15 +1950,15 @@ krb5_deltat get_rc_clockskew(krb5_context context) /* kssl_validate_times() combines (and more importantly exposes) -** the MIT KRB5 internal function krb5_validate_times() and the -** in_clock_skew() macro. The authenticator client time is checked -** to be within clockskew secs of the current time and the current -** time is checked to be within the ticket start and expire times. -** Either check may be omitted by supplying a NULL value. -** Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. -** See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c -** 20010420 VRS -*/ + * the MIT KRB5 internal function krb5_validate_times() and the + * in_clock_skew() macro. The authenticator client time is checked + * to be within clockskew secs of the current time and the current + * time is checked to be within the ticket start and expire times. + * Either check may be omitted by supplying a NULL value. + * Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. + * See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c + * 20010420 VRS + */ krb5_error_code kssl_validate_times( krb5_timestamp atime, krb5_ticket_times *ttimes) { @@ -1956,7 +1981,7 @@ krb5_error_code kssl_validate_times( krb5_timestamp atime, if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED; #ifdef KSSL_DEBUG - printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", + fprintf(stderr,"kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", start, atime, now, skew, ttimes->endtime); #endif /* KSSL_DEBUG */ @@ -1965,12 +1990,12 @@ krb5_error_code kssl_validate_times( krb5_timestamp atime, /* Decode and decrypt given DER-encoded authenticator, then pass -** authenticator ctime back in *atimep (or 0 if time unavailable). -** Returns krb5_error_code and kssl_err on error. A NULL -** authenticator (authentp->length == 0) is not considered an error. -** Note that kssl_check_authent() makes use of the KRB5 session key; -** you must call kssl_sget_tkt() to get the key before calling this routine. -*/ + * authenticator ctime back in *atimep (or 0 if time unavailable). + * Returns krb5_error_code and kssl_err on error. A NULL + * authenticator (authentp->length == 0) is not considered an error. + * Note that kssl_check_authent() makes use of the KRB5 session key; + * you must call kssl_sget_tkt() to get the key before calling this routine. + */ krb5_error_code kssl_check_authent( /* IN */ KSSL_CTX *kssl_ctx, /* IN */ krb5_data *authentp, @@ -2007,10 +2032,10 @@ krb5_error_code kssl_check_authent( #ifdef KSSL_DEBUG { unsigned int ui; - printf("kssl_check_authent: authenticator[%d]:\n",authentp->length); + fprintf(stderr,"kssl_check_authent: authenticator[%d]:\n",authentp->length); p = authentp->data; - for (ui=0; ui < authentp->length; ui++) printf("%02x ",p[ui]); - printf("\n"); + for (ui=0; ui < authentp->length; ui++) fprintf(stderr,"%02x ",p[ui]); + fprintf(stderr,"\n"); } #endif /* KSSL_DEBUG */ @@ -2049,9 +2074,9 @@ krb5_error_code kssl_check_authent( if (enc == NULL) { /* Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. - ** This enctype indicates the authenticator was encrypted - ** using key-usage derived keys which openssl cannot decrypt. - */ + * This enctype indicates the authenticator was encrypted + * using key-usage derived keys which openssl cannot decrypt. + */ goto err; } @@ -2073,9 +2098,12 @@ krb5_error_code kssl_check_authent( EVP_CIPHER_CTX_cleanup(&ciph_ctx); #ifdef KSSL_DEBUG - printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); - for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); - printf("\n"); + { + int padl; + fprintf(stderr,"kssl_check_authent: decrypted authenticator[%d] =\n", outl); + for (padl=0; padl < outl; padl++) fprintf(stderr,"%02x ",unenc_authent[padl]); + fprintf(stderr,"\n"); + } #endif /* KSSL_DEBUG */ if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) @@ -2105,14 +2133,14 @@ krb5_error_code kssl_check_authent( tm_g = gmtime(&now); tg = mktime(tm_g); tz_offset = tg - tl; - *atimep = tr - tz_offset; + *atimep = (krb5_timestamp)(tr - tz_offset); } #ifdef KSSL_DEBUG - printf("kssl_check_authent: returns %d for client time ", *atimep); - if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) - printf("%.*s\n", auth->ctime->length, auth->ctime->data); - else printf("NULL\n"); + fprintf(stderr,"kssl_check_authent: returns %d for client time ", *atimep); + if (auth->ctime && auth->ctime->length && auth->ctime->data) + fprintf(stderr,"%.*s\n", auth->ctime->length, auth->ctime->data); + else fprintf(stderr,"NULL\n"); #endif /* KSSL_DEBUG */ err: @@ -2125,10 +2153,10 @@ krb5_error_code kssl_check_authent( /* Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), -** because I dont't know how to stub varargs. -** Returns krb5_error_code == ENOMEM on alloc error, otherwise -** passes back newly constructed principal, which should be freed by caller. -*/ + * because I don't know how to stub varargs. + * Returns krb5_error_code == ENOMEM on alloc error, otherwise + * passes back newly constructed principal, which should be freed by caller. + */ krb5_error_code kssl_build_principal_2( /* UPDATE */ krb5_context context, /* OUT */ krb5_principal *princ, @@ -2171,11 +2199,27 @@ krb5_error_code kssl_build_principal_2( return ENOMEM; } +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) + { + s->kssl_ctx = kctx; + } + +KSSL_CTX * SSL_get0_kssl_ctx(SSL *s) + { + return s->kssl_ctx; + } + +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) + { + if (kctx) + return kctx->client_princ; + return NULL; + } #else /* !OPENSSL_NO_KRB5 */ #if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) -static int dummy=(int)&dummy; +static void *dummy=&dummy; #endif #endif /* !OPENSSL_NO_KRB5 */