X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fkssl.c;h=0033e9bf62e3857f27ea9dbda7047eb2a50a5f82;hb=ab1415d2f5b56a17efbd6b2add7a0ff2dbb903c5;hp=a80f5b2f74dad0019f31da33d79da7885911e1a0;hpb=c4d00669a058eb8a26b496746c25beaef6cdad1b;p=openssl.git diff --git a/ssl/kssl.c b/ssl/kssl.c index a80f5b2f74..0033e9bf62 100644 --- a/ssl/kssl.c +++ b/ssl/kssl.c @@ -68,18 +68,22 @@ #include -#define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */ -#include -#undef _XOPEN_SOURCE /* To avoid clashes with anything else... */ #include +#define KRB5_PRIVATE 1 + #include #include #include #include +#include "kssl_lcl.h" #ifndef OPENSSL_NO_KRB5 +#ifndef ENOMEM +#define ENOMEM KRB5KRB_ERR_GENERIC +#endif + /* * When OpenSSL is built on Windows, we do not want to require that * the Kerberos DLLs be available in order for the OpenSSL DLLs to @@ -128,7 +132,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 @@ -289,7 +293,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; @@ -776,6 +780,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) { @@ -817,7 +840,7 @@ kssl_map_enc(krb5_enctype enctype) ** "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) +static int kssl_test_confound(unsigned char *p) { int len = 2; int xx = 0, yy = 0; @@ -852,7 +875,7 @@ int kssl_test_confound(unsigned char *p) ** 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) +static size_t *populate_cksumlens(void) { int i, j, n; static size_t *cklens = NULL; @@ -919,7 +942,7 @@ 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; } @@ -932,7 +955,7 @@ print_krb5_data(char *label, krb5_data *kdata) int i; printf("%s[%d] ", label, kdata->length); - for (i=0; i < kdata->length; i++) + for (i=0; i < (int)kdata->length; i++) { if (0 && isprint((int) kdata->data[i])) printf( "%c ", kdata->data[i]); @@ -953,7 +976,7 @@ print_krb5_authdata(char *label, krb5_authdata **adata) printf("%s, authdata==0\n", label); return; } - printf("%s [%p]\n", label, adata); + printf("%s [%p]\n", label, (void *)adata); #if 0 { int i; @@ -984,14 +1007,14 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk) #ifdef KRB5_HEIMDAL printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, keyblk->keyvalue->length); - for (i=0; i < keyblk->keyvalue->length; i++) + for (i=0; i < (int)keyblk->keyvalue->length; i++) { printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); } printf("\n"); #else printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); - for (i=0; i < keyblk->length; i++) + for (i=0; i < (int)keyblk->length; i++) { printf("%02x",keyblk->contents[i]); } @@ -1003,19 +1026,19 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk) /* Display contents of krb5_principal_data struct, for debugging ** (krb5_principal is typedef'd == krb5_principal_data *) */ -void +static void print_krb5_princ(char *label, krb5_principal_data *princ) { int i, ui, uj; printf("%s principal Realm: ", label); if (princ == NULL) return; - for (ui=0; ui < princ->realm.length; ui++) putchar(princ->realm.data[ui]); + 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); - for (i=0; i < princ->length; i++) + for (i=0; i < (int)princ->length; i++) { printf("\t%d [%d]: ", i, princ->data[i].length); - for (uj=0; uj < princ->data[i].length; uj++) { + for (uj=0; uj < (int)princ->data[i].length; uj++) { putchar(princ->data[i].data[uj]); } printf("\n"); @@ -1124,7 +1147,7 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, if (authenp) { krb5_data krb5in_data; - unsigned char *p; + const unsigned char *p; long arlen; KRB5_APREQBODY *ap_req; @@ -1202,7 +1225,7 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, ** code here. This tkt should alloc/free just ** like the real thing. */ -krb5_error_code +static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, /* IN */ KRB5_TKTBODY *asn1ticket, /* OUT */ krb5_ticket **krb5ticket, @@ -1293,7 +1316,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, static krb5_auth_context krb5auth_context = NULL; krb5_ticket *krb5ticket = NULL; KRB5_TKTBODY *asn1ticket = NULL; - unsigned char *p; + const unsigned char *p; krb5_keytab krb5keytab = NULL; krb5_keytab_entry kt_entry; krb5_principal krb5server; @@ -1496,8 +1519,9 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, "bad ticket from krb5_rd_req.\n"); } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, - &krb5ticket->enc_part2->client->realm, - krb5ticket->enc_part2->client->data)) + &krb5ticket->enc_part2->client->realm, + krb5ticket->enc_part2->client->data, + krb5ticket->enc_part2->client->length)) { kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, "kssl_ctx_setprinc() fails.\n"); @@ -1539,7 +1563,7 @@ 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))); } @@ -1553,27 +1577,28 @@ 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 a (krb5_data *) entity (and optional realm), +/* 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. */ krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, - krb5_data *realm, krb5_data *entity) + krb5_data *realm, krb5_data *entity, int nentities) { char **princ; int length; + int i; if (kssl_ctx == NULL || entity == NULL) return KSSL_CTX_ERR; @@ -1583,20 +1608,35 @@ 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; + for (i=0; i < nentities; i++) + { + length += entity[i].length; + } + /* Add in space for the '/' character(s) (if any) */ + length += nentities-1; + /* Space for the ('@'+realm+NULL | NULL) */ + length += ((realm)? realm->length + 2: 1); - length = entity->length + ((realm)? realm->length + 2: 1); - if ((*princ = calloc(1, length)) == NULL) + if ((*princ = kssl_calloc(1, length)) == NULL) return KSSL_CTX_ERR; else - { - strncpy(*princ, entity->data, entity->length); - (*princ)[entity->length]='\0'; + { + for (i = 0; i < nentities; i++) + { + strncat(*princ, entity[i].data, entity[i].length); + if (i < nentities-1) + { + strcat (*princ, "/"); + } + } if (realm) { strcat (*princ, "@"); (void) strncat(*princ, realm->data, realm->length); - (*princ)[entity->length+1+realm->length]='\0'; } } @@ -1624,7 +1664,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) { @@ -1632,7 +1672,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); @@ -1656,7 +1696,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) @@ -1682,7 +1722,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; @@ -1708,7 +1748,7 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx) return; } else - printf("%p\n", kssl_ctx); + printf("%p\n", (void *)kssl_ctx); printf("\tservice:\t%s\n", (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL"); @@ -1763,6 +1803,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 */, @@ -1860,7 +1903,7 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) ** 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) +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) { char c, *p; @@ -1886,7 +1929,7 @@ struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) ** 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) +static krb5_deltat get_rc_clockskew(krb5_context context) { krb5_rcache rc; krb5_deltat clockskew; @@ -1961,7 +2004,8 @@ krb5_error_code kssl_check_authent( EVP_CIPHER_CTX ciph_ctx; const EVP_CIPHER *enc = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char *p, *unenc_authent; + const unsigned char *p; + unsigned char *unenc_authent; int outl, unencbufsize; struct tm tm_time, *tm_l, *tm_g; time_t now, tl, tg, tr, tz_offset; @@ -2081,7 +2125,7 @@ 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 @@ -2151,7 +2195,7 @@ krb5_error_code kssl_build_principal_2( #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 */