diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/src/ssl/kssl.c | 1417 |
1 files changed, 738 insertions, 679 deletions
diff --git a/src/lib/libssl/src/ssl/kssl.c b/src/lib/libssl/src/ssl/kssl.c index a90c90fa6e..2bbe3ab647 100644 --- a/src/lib/libssl/src/ssl/kssl.c +++ b/src/lib/libssl/src/ssl/kssl.c | |||
| @@ -87,11 +87,12 @@ | |||
| 87 | 87 | ||
| 88 | /* memory allocation functions for non-temporary storage | 88 | /* memory allocation functions for non-temporary storage |
| 89 | * (e.g. stuff that gets saved into the kssl context) */ | 89 | * (e.g. stuff that gets saved into the kssl context) */ |
| 90 | static void* kssl_calloc(size_t nmemb, size_t size) | 90 | static void* |
| 91 | kssl_calloc(size_t nmemb, size_t size) | ||
| 91 | { | 92 | { |
| 92 | void* p; | 93 | void* p; |
| 93 | 94 | ||
| 94 | p=OPENSSL_malloc(nmemb*size); | 95 | p = OPENSSL_malloc(nmemb*size); |
| 95 | if (p){ | 96 | if (p){ |
| 96 | memset(p, 0, nmemb*size); | 97 | memset(p, 0, nmemb*size); |
| 97 | } | 98 | } |
| @@ -105,11 +106,11 @@ static void* kssl_calloc(size_t nmemb, size_t size) | |||
| 105 | 106 | ||
| 106 | char | 107 | char |
| 107 | *kstring(char *string) | 108 | *kstring(char *string) |
| 108 | { | 109 | { |
| 109 | static char *null = "[NULL]"; | 110 | static char *null = "[NULL]"; |
| 110 | 111 | ||
| 111 | return ((string == NULL)? null: string); | 112 | return ((string == NULL) ? null : string); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | /* Given KRB5 enctype (basically DES or 3DES), | 115 | /* Given KRB5 enctype (basically DES or 3DES), |
| 115 | ** return closest match openssl EVP_ encryption algorithm. | 116 | ** return closest match openssl EVP_ encryption algorithm. |
| @@ -118,25 +119,25 @@ char | |||
| 118 | */ | 119 | */ |
| 119 | const EVP_CIPHER * | 120 | const EVP_CIPHER * |
| 120 | kssl_map_enc(krb5_enctype enctype) | 121 | kssl_map_enc(krb5_enctype enctype) |
| 121 | { | 122 | { |
| 122 | switch (enctype) | 123 | switch (enctype) { |
| 123 | { | 124 | case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ |
| 124 | case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ | ||
| 125 | case ENCTYPE_DES_CBC_CRC: | 125 | case ENCTYPE_DES_CBC_CRC: |
| 126 | case ENCTYPE_DES_CBC_MD4: | 126 | case ENCTYPE_DES_CBC_MD4: |
| 127 | case ENCTYPE_DES_CBC_MD5: | 127 | case ENCTYPE_DES_CBC_MD5: |
| 128 | case ENCTYPE_DES_CBC_RAW: | 128 | case ENCTYPE_DES_CBC_RAW: |
| 129 | return EVP_des_cbc(); | 129 | return EVP_des_cbc(); |
| 130 | break; | 130 | break; |
| 131 | case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ | 131 | case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ |
| 132 | case ENCTYPE_DES3_CBC_SHA: | 132 | case ENCTYPE_DES3_CBC_SHA: |
| 133 | case ENCTYPE_DES3_CBC_RAW: | 133 | case ENCTYPE_DES3_CBC_RAW: |
| 134 | return EVP_des_ede3_cbc(); | 134 | return EVP_des_ede3_cbc(); |
| 135 | break; | 135 | break; |
| 136 | default: return NULL; | 136 | default: |
| 137 | break; | 137 | return NULL; |
| 138 | } | 138 | break; |
| 139 | } | 139 | } |
| 140 | } | ||
| 140 | 141 | ||
| 141 | 142 | ||
| 142 | /* Return true:1 if p "looks like" the start of the real authenticator | 143 | /* Return true:1 if p "looks like" the start of the real authenticator |
| @@ -144,31 +145,58 @@ kssl_map_enc(krb5_enctype enctype) | |||
| 144 | ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and | 145 | ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and |
| 145 | ** xx and yy are possibly multi-byte length fields. | 146 | ** xx and yy are possibly multi-byte length fields. |
| 146 | */ | 147 | */ |
| 147 | static int kssl_test_confound(unsigned char *p) | 148 | static int |
| 148 | { | 149 | kssl_test_confound(unsigned char *p) |
| 150 | { | ||
| 149 | int len = 2; | 151 | int len = 2; |
| 150 | int xx = 0, yy = 0; | 152 | int xx = 0, yy = 0; |
| 151 | 153 | ||
| 152 | if (*p++ != 0x62) return 0; | 154 | if (*p++ != 0x62) |
| 153 | if (*p > 0x82) return 0; | 155 | return 0; |
| 154 | switch(*p) { | 156 | if (*p > 0x82) |
| 155 | case 0x82: p++; xx = (*p++ << 8); xx += *p++; break; | 157 | return 0; |
| 156 | case 0x81: p++; xx = *p++; break; | 158 | switch (*p) { |
| 157 | case 0x80: return 0; | 159 | case 0x82: |
| 158 | default: xx = *p++; break; | 160 | p++; |
| 159 | } | 161 | xx = (*p++ << 8); |
| 160 | if (*p++ != 0x30) return 0; | 162 | xx += *p++; |
| 161 | if (*p > 0x82) return 0; | 163 | break; |
| 162 | switch(*p) { | 164 | case 0x81: |
| 163 | case 0x82: p++; len+=2; yy = (*p++ << 8); yy += *p++; break; | 165 | p++; |
| 164 | case 0x81: p++; len++; yy = *p++; break; | 166 | xx = *p++; |
| 165 | case 0x80: return 0; | 167 | break; |
| 166 | default: yy = *p++; break; | 168 | case 0x80: |
| 167 | } | 169 | return 0; |
| 168 | 170 | default: | |
| 169 | return (xx - len == yy)? 1: 0; | 171 | xx = *p++; |
| 172 | break; | ||
| 173 | } | ||
| 174 | if (*p++ != 0x30) | ||
| 175 | return 0; | ||
| 176 | if (*p > 0x82) | ||
| 177 | return 0; | ||
| 178 | switch (*p) { | ||
| 179 | case 0x82: | ||
| 180 | p++; | ||
| 181 | len += 2; | ||
| 182 | yy = (*p++ << 8); | ||
| 183 | yy += *p++; | ||
| 184 | break; | ||
| 185 | case 0x81: | ||
| 186 | p++; | ||
| 187 | len++; | ||
| 188 | yy = *p++; | ||
| 189 | break; | ||
| 190 | case 0x80: | ||
| 191 | return 0; | ||
| 192 | default: | ||
| 193 | yy = *p++; | ||
| 194 | break; | ||
| 170 | } | 195 | } |
| 171 | 196 | ||
| 197 | return (xx - len == yy) ? 1: 0; | ||
| 198 | } | ||
| 199 | |||
| 172 | /* Allocate, fill, and return cksumlens array of checksum lengths. | 200 | /* Allocate, fill, and return cksumlens array of checksum lengths. |
| 173 | ** This array holds just the unique elements from the krb5_cksumarray[]. | 201 | ** This array holds just the unique elements from the krb5_cksumarray[]. |
| 174 | ** array[n] == 0 signals end of data. | 202 | ** array[n] == 0 signals end of data. |
| @@ -179,8 +207,9 @@ static int kssl_test_confound(unsigned char *p) | |||
| 179 | ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 | 207 | ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 |
| 180 | ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. | 208 | ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. |
| 181 | */ | 209 | */ |
| 182 | static size_t *populate_cksumlens(void) | 210 | static size_t |
| 183 | { | 211 | *populate_cksumlens(void) |
| 212 | { | ||
| 184 | int i, j, n; | 213 | int i, j, n; |
| 185 | static size_t *cklens = NULL; | 214 | static size_t *cklens = NULL; |
| 186 | 215 | ||
| @@ -189,26 +218,30 @@ static size_t *populate_cksumlens(void) | |||
| 189 | #else | 218 | #else |
| 190 | n = 0x0010; | 219 | n = 0x0010; |
| 191 | #endif /* KRB5_MIT_OLD11 */ | 220 | #endif /* KRB5_MIT_OLD11 */ |
| 192 | 221 | ||
| 193 | #ifdef KRB5CHECKAUTH | 222 | #ifdef KRB5CHECKAUTH |
| 194 | if (!cklens && !(cklens = (size_t *) calloc(sizeof(int),n+1))) return NULL; | 223 | if (!cklens && !(cklens = (size_t *) |
| 195 | 224 | calloc(sizeof(int), n + 1))) return NULL; | |
| 196 | for (i=0; i < n; i++) { | 225 | |
| 197 | if (!valid_cksumtype(i)) continue; /* array has holes */ | 226 | for (i = 0; i < n; i++) { |
| 198 | for (j=0; j < n; j++) { | 227 | if (!valid_cksumtype(i)) |
| 199 | if (cklens[j] == 0) { | 228 | continue; /* array has holes */ |
| 200 | cklens[j] = krb5_checksum_size(NULL,i); | 229 | for (j = 0; j < n; j++) { |
| 201 | break; /* krb5 elem was new: add */ | 230 | if (cklens[j] == 0) { |
| 202 | } | 231 | cklens[j] = krb5_checksum_size(NULL, i); |
| 203 | if (cklens[j] == krb5_checksum_size(NULL,i)) { | 232 | break; |
| 204 | break; /* ignore duplicate elements */ | 233 | /* krb5 elem was new: add */ |
| 205 | } | 234 | } |
| 235 | if (cklens[j] == krb5_checksum_size(NULL, i)) { | ||
| 236 | break; | ||
| 237 | /* ignore duplicate elements */ | ||
| 206 | } | 238 | } |
| 207 | } | 239 | } |
| 240 | } | ||
| 208 | #endif /* KRB5CHECKAUTH */ | 241 | #endif /* KRB5CHECKAUTH */ |
| 209 | 242 | ||
| 210 | return cklens; | 243 | return cklens; |
| 211 | } | 244 | } |
| 212 | 245 | ||
| 213 | /* Return pointer to start of real authenticator within authenticator, or | 246 | /* Return pointer to start of real authenticator within authenticator, or |
| 214 | ** return NULL on error. | 247 | ** return NULL on error. |
| @@ -217,24 +250,26 @@ static size_t *populate_cksumlens(void) | |||
| 217 | ** This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the | 250 | ** This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the |
| 218 | ** krb5_auth_con_getcksumtype() function advertised in its krb5.h. | 251 | ** krb5_auth_con_getcksumtype() function advertised in its krb5.h. |
| 219 | */ | 252 | */ |
| 220 | unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) | 253 | unsigned char |
| 221 | { | 254 | *kssl_skip_confound(krb5_enctype etype, unsigned char *a) |
| 255 | { | ||
| 222 | int i, conlen; | 256 | int i, conlen; |
| 223 | size_t cklen; | 257 | size_t cklen; |
| 224 | static size_t *cksumlens = NULL; | 258 | static size_t *cksumlens = NULL; |
| 225 | unsigned char *test_auth; | 259 | unsigned char *test_auth; |
| 226 | 260 | ||
| 227 | conlen = (etype)? 8: 0; | 261 | conlen = (etype) ? 8: 0; |
| 228 | 262 | ||
| 229 | if (!cksumlens && !(cksumlens = populate_cksumlens())) return NULL; | 263 | if (!cksumlens && !(cksumlens = populate_cksumlens())) |
| 230 | for (i=0; (cklen = cksumlens[i]) != 0; i++) | 264 | return NULL; |
| 231 | { | 265 | for (i = 0; (cklen = cksumlens[i]) != 0; i++) { |
| 232 | test_auth = a + conlen + cklen; | 266 | test_auth = a + conlen + cklen; |
| 233 | if (kssl_test_confound(test_auth)) return test_auth; | 267 | if (kssl_test_confound(test_auth)) |
| 234 | } | 268 | return test_auth; |
| 269 | } | ||
| 235 | 270 | ||
| 236 | return NULL; | 271 | return NULL; |
| 237 | } | 272 | } |
| 238 | 273 | ||
| 239 | 274 | ||
| 240 | /* Set kssl_err error info when reason text is a simple string | 275 | /* Set kssl_err error info when reason text is a simple string |
| @@ -242,89 +277,84 @@ unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) | |||
| 242 | */ | 277 | */ |
| 243 | void | 278 | void |
| 244 | kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) | 279 | kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) |
| 245 | { | 280 | { |
| 246 | if (kssl_err == NULL) return; | 281 | if (kssl_err == NULL) |
| 282 | return; | ||
| 247 | 283 | ||
| 248 | kssl_err->reason = reason; | 284 | kssl_err->reason = reason; |
| 249 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); | 285 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); |
| 250 | return; | 286 | return; |
| 251 | } | 287 | } |
| 252 | 288 | ||
| 253 | 289 | ||
| 254 | /* Display contents of krb5_data struct, for debugging | 290 | /* Display contents of krb5_data struct, for debugging |
| 255 | */ | 291 | */ |
| 256 | void | 292 | void |
| 257 | print_krb5_data(char *label, krb5_data *kdata) | 293 | print_krb5_data(char *label, krb5_data *kdata) |
| 258 | { | 294 | { |
| 259 | int i; | 295 | int i; |
| 260 | 296 | ||
| 261 | printf("%s[%d] ", label, kdata->length); | 297 | printf("%s[%d] ", label, kdata->length); |
| 262 | for (i=0; i < (int)kdata->length; i++) | 298 | for (i = 0; i < (int)kdata->length; i++) { |
| 263 | { | 299 | if (0 && isprint((int) kdata->data[i])) |
| 264 | if (0 && isprint((int) kdata->data[i])) | 300 | printf( "%c ", kdata->data[i]); |
| 265 | printf( "%c ", kdata->data[i]); | ||
| 266 | else | 301 | else |
| 267 | printf( "%02x ", (unsigned char) kdata->data[i]); | 302 | printf( "%02x ", (unsigned char) kdata->data[i]); |
| 268 | } | 303 | } |
| 269 | printf("\n"); | 304 | printf("\n"); |
| 270 | } | 305 | } |
| 271 | 306 | ||
| 272 | 307 | ||
| 273 | /* Display contents of krb5_authdata struct, for debugging | 308 | /* Display contents of krb5_authdata struct, for debugging |
| 274 | */ | 309 | */ |
| 275 | void | 310 | void |
| 276 | print_krb5_authdata(char *label, krb5_authdata **adata) | 311 | print_krb5_authdata(char *label, krb5_authdata **adata) |
| 277 | { | 312 | { |
| 278 | if (adata == NULL) | 313 | if (adata == NULL) { |
| 279 | { | ||
| 280 | printf("%s, authdata==0\n", label); | 314 | printf("%s, authdata==0\n", label); |
| 281 | return; | 315 | return; |
| 282 | } | 316 | } |
| 283 | printf("%s [%p]\n", label, (void *)adata); | 317 | printf("%s [%p]\n", label, (void *)adata); |
| 284 | #if 0 | 318 | #if 0 |
| 285 | { | 319 | { |
| 286 | int i; | 320 | int i; |
| 287 | printf("%s[at%d:%d] ", label, adata->ad_type, adata->length); | 321 | printf("%s[at%d:%d] ", label, adata->ad_type, adata->length); |
| 288 | for (i=0; i < adata->length; i++) | 322 | for (i = 0; i < adata->length; i++) { |
| 289 | { | 323 | printf((isprint(adata->contents[i]))? "%c ": "%02x", |
| 290 | printf((isprint(adata->contents[i]))? "%c ": "%02x", | 324 | adata->contents[i]); |
| 291 | adata->contents[i]); | ||
| 292 | } | 325 | } |
| 293 | printf("\n"); | 326 | printf("\n"); |
| 294 | } | 327 | } |
| 295 | #endif | 328 | #endif |
| 296 | } | 329 | } |
| 297 | 330 | ||
| 298 | 331 | ||
| 299 | /* Display contents of krb5_keyblock struct, for debugging | 332 | /* Display contents of krb5_keyblock struct, for debugging |
| 300 | */ | 333 | */ |
| 301 | void | 334 | void |
| 302 | print_krb5_keyblock(char *label, krb5_keyblock *keyblk) | 335 | print_krb5_keyblock(char *label, krb5_keyblock *keyblk) |
| 303 | { | 336 | { |
| 304 | int i; | 337 | int i; |
| 305 | 338 | ||
| 306 | if (keyblk == NULL) | 339 | if (keyblk == NULL) { |
| 307 | { | ||
| 308 | printf("%s, keyblk==0\n", label); | 340 | printf("%s, keyblk==0\n", label); |
| 309 | return; | 341 | return; |
| 310 | } | 342 | } |
| 311 | #ifdef KRB5_HEIMDAL | 343 | #ifdef KRB5_HEIMDAL |
| 312 | printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, | 344 | printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, |
| 313 | keyblk->keyvalue->length); | 345 | keyblk->keyvalue->length); |
| 314 | for (i=0; i < (int)keyblk->keyvalue->length; i++) | 346 | for (i = 0; i < (int)keyblk->keyvalue->length; i++) { |
| 315 | { | ||
| 316 | printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); | 347 | printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); |
| 317 | } | 348 | } |
| 318 | printf("\n"); | 349 | printf("\n"); |
| 319 | #else | 350 | #else |
| 320 | printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); | 351 | printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); |
| 321 | for (i=0; i < (int)keyblk->length; i++) | 352 | for (i = 0; i < (int)keyblk->length; i++) { |
| 322 | { | 353 | printf("%02x", keyblk->contents[i]); |
| 323 | printf("%02x",keyblk->contents[i]); | 354 | } |
| 324 | } | ||
| 325 | printf("\n"); | 355 | printf("\n"); |
| 326 | #endif | 356 | #endif |
| 327 | } | 357 | } |
| 328 | 358 | ||
| 329 | 359 | ||
| 330 | /* Display contents of krb5_principal_data struct, for debugging | 360 | /* Display contents of krb5_principal_data struct, for debugging |
| @@ -332,23 +362,24 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk) | |||
| 332 | */ | 362 | */ |
| 333 | static void | 363 | static void |
| 334 | print_krb5_princ(char *label, krb5_principal_data *princ) | 364 | print_krb5_princ(char *label, krb5_principal_data *princ) |
| 335 | { | 365 | { |
| 336 | int i, ui, uj; | 366 | int i, ui, uj; |
| 337 | 367 | ||
| 338 | printf("%s principal Realm: ", label); | 368 | printf("%s principal Realm: ", label); |
| 339 | if (princ == NULL) return; | 369 | if (princ == NULL) |
| 340 | for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.data[ui]); | 370 | return; |
| 341 | printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); | 371 | for (ui = 0; ui < (int)princ->realm.length; ui++) |
| 342 | for (i=0; i < (int)princ->length; i++) | 372 | putchar(princ->realm.data[ui]); |
| 343 | { | 373 | printf(" (nametype %d) has %d strings:\n", princ->type, princ->length); |
| 374 | for (i = 0; i < (int)princ->length; i++) { | ||
| 344 | printf("\t%d [%d]: ", i, princ->data[i].length); | 375 | printf("\t%d [%d]: ", i, princ->data[i].length); |
| 345 | for (uj=0; uj < (int)princ->data[i].length; uj++) { | 376 | for (uj = 0; uj < (int)princ->data[i].length; uj++) { |
| 346 | putchar(princ->data[i].data[uj]); | 377 | putchar(princ->data[i].data[uj]); |
| 347 | } | ||
| 348 | printf("\n"); | ||
| 349 | } | 378 | } |
| 379 | printf("\n"); | ||
| 380 | } | ||
| 350 | return; | 381 | return; |
| 351 | } | 382 | } |
| 352 | 383 | ||
| 353 | 384 | ||
| 354 | /* Given krb5 service (typically "kssl") and hostname in kssl_ctx, | 385 | /* Given krb5 service (typically "kssl") and hostname in kssl_ctx, |
| @@ -362,11 +393,12 @@ print_krb5_princ(char *label, krb5_principal_data *princ) | |||
| 362 | ** 20010606 VRS May also return optional authenticator. | 393 | ** 20010606 VRS May also return optional authenticator. |
| 363 | */ | 394 | */ |
| 364 | krb5_error_code | 395 | krb5_error_code |
| 365 | kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | 396 | kssl_cget_tkt( |
| 366 | /* OUT */ krb5_data **enc_ticketp, | 397 | /* UPDATE */ KSSL_CTX *kssl_ctx, |
| 367 | /* UPDATE */ krb5_data *authenp, | 398 | /* OUT */ krb5_data **enc_ticketp, |
| 368 | /* OUT */ KSSL_ERR *kssl_err) | 399 | /* UPDATE */ krb5_data *authenp, |
| 369 | { | 400 | /* OUT */ KSSL_ERR *kssl_err) |
| 401 | { | ||
| 370 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 402 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
| 371 | krb5_context krb5context = NULL; | 403 | krb5_context krb5context = NULL; |
| 372 | krb5_auth_context krb5auth_context = NULL; | 404 | krb5_auth_context krb5auth_context = NULL; |
| @@ -377,47 +409,40 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 377 | kssl_err_set(kssl_err, 0, ""); | 409 | kssl_err_set(kssl_err, 0, ""); |
| 378 | memset((char *)&krb5creds, 0, sizeof(krb5creds)); | 410 | memset((char *)&krb5creds, 0, sizeof(krb5creds)); |
| 379 | 411 | ||
| 380 | if (!kssl_ctx) | 412 | if (!kssl_ctx) { |
| 381 | { | ||
| 382 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 413 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 383 | "No kssl_ctx defined.\n"); | 414 | "No kssl_ctx defined.\n"); |
| 384 | goto err; | 415 | goto err; |
| 385 | } | 416 | } else if (!kssl_ctx->service_host) { |
| 386 | else if (!kssl_ctx->service_host) | ||
| 387 | { | ||
| 388 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 417 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 389 | "kssl_ctx service_host undefined.\n"); | 418 | "kssl_ctx service_host undefined.\n"); |
| 390 | goto err; | 419 | goto err; |
| 391 | } | 420 | } |
| 392 | 421 | ||
| 393 | if ((krb5rc = krb5_init_context(&krb5context)) != 0) | 422 | if ((krb5rc = krb5_init_context(&krb5context)) != 0) { |
| 394 | { | ||
| 395 | BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, | 423 | BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, |
| 396 | "krb5_init_context() fails: %d\n", krb5rc); | 424 | "krb5_init_context() fails: %d\n", krb5rc); |
| 397 | kssl_err->reason = SSL_R_KRB5_C_INIT; | 425 | kssl_err->reason = SSL_R_KRB5_C_INIT; |
| 398 | goto err; | 426 | goto err; |
| 399 | } | 427 | } |
| 400 | 428 | ||
| 401 | if ((krb5rc = krb5_sname_to_principal(krb5context, | 429 | if ((krb5rc = krb5_sname_to_principal( |
| 402 | kssl_ctx->service_host, | 430 | krb5context, kssl_ctx->service_host, |
| 403 | (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, | 431 | (kssl_ctx->service_name) ? kssl_ctx->service_name : KRB5SVC, |
| 404 | KRB5_NT_SRV_HST, &krb5creds.server)) != 0) | 432 | KRB5_NT_SRV_HST, &krb5creds.server)) != 0) { |
| 405 | { | ||
| 406 | BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, | 433 | BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, |
| 407 | "krb5_sname_to_principal() fails for %s/%s\n", | 434 | "krb5_sname_to_principal() fails for %s/%s\n", |
| 408 | kssl_ctx->service_host, | 435 | kssl_ctx->service_host, |
| 409 | (kssl_ctx->service_name)? kssl_ctx->service_name: | 436 | (kssl_ctx->service_name) ? kssl_ctx->service_name: KRB5SVC); |
| 410 | KRB5SVC); | ||
| 411 | kssl_err->reason = SSL_R_KRB5_C_INIT; | 437 | kssl_err->reason = SSL_R_KRB5_C_INIT; |
| 412 | goto err; | 438 | goto err; |
| 413 | } | 439 | } |
| 414 | 440 | ||
| 415 | if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) | 441 | if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) { |
| 416 | { | ||
| 417 | kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, | 442 | kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, |
| 418 | "krb5_cc_default fails.\n"); | 443 | "krb5_cc_default fails.\n"); |
| 419 | goto err; | 444 | goto err; |
| 420 | } | 445 | } |
| 421 | 446 | ||
| 422 | if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, | 447 | if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, |
| 423 | &krb5creds.client)) != 0) | 448 | &krb5creds.client)) != 0) |
| @@ -428,12 +453,11 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 428 | } | 453 | } |
| 429 | 454 | ||
| 430 | if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, | 455 | if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, |
| 431 | &krb5creds, &krb5credsp)) != 0) | 456 | &krb5creds, &krb5credsp)) != 0) { |
| 432 | { | ||
| 433 | kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, | 457 | kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, |
| 434 | "krb5_get_credentials() fails.\n"); | 458 | "krb5_get_credentials() fails.\n"); |
| 435 | goto err; | 459 | goto err; |
| 436 | } | 460 | } |
| 437 | 461 | ||
| 438 | *enc_ticketp = &krb5credsp->ticket; | 462 | *enc_ticketp = &krb5credsp->ticket; |
| 439 | #ifdef KRB5_HEIMDAL | 463 | #ifdef KRB5_HEIMDAL |
| @@ -448,8 +472,7 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 448 | ** 20010605 VRS reinstated to offer Authenticator to KerberosWrapper | 472 | ** 20010605 VRS reinstated to offer Authenticator to KerberosWrapper |
| 449 | */ | 473 | */ |
| 450 | krb5_app_req.length = 0; | 474 | krb5_app_req.length = 0; |
| 451 | if (authenp) | 475 | if (authenp) { |
| 452 | { | ||
| 453 | krb5_data krb5in_data; | 476 | krb5_data krb5in_data; |
| 454 | const unsigned char *p; | 477 | const unsigned char *p; |
| 455 | long arlen; | 478 | long arlen; |
| @@ -459,63 +482,61 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 459 | krb5in_data.data = NULL; | 482 | krb5in_data.data = NULL; |
| 460 | krb5in_data.length = 0; | 483 | krb5in_data.length = 0; |
| 461 | if ((krb5rc = krb5_mk_req_extended(krb5context, | 484 | if ((krb5rc = krb5_mk_req_extended(krb5context, |
| 462 | &krb5auth_context, 0, &krb5in_data, krb5credsp, | 485 | &krb5auth_context, 0, &krb5in_data, krb5credsp, |
| 463 | &krb5_app_req)) != 0) | 486 | &krb5_app_req)) != 0) { |
| 464 | { | ||
| 465 | kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, | 487 | kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, |
| 466 | "krb5_mk_req_extended() fails.\n"); | 488 | "krb5_mk_req_extended() fails.\n"); |
| 467 | goto err; | 489 | goto err; |
| 468 | } | 490 | } |
| 469 | 491 | ||
| 470 | arlen = krb5_app_req.length; | 492 | arlen = krb5_app_req.length; |
| 471 | p = (unsigned char *)krb5_app_req.data; | 493 | p = (unsigned char *)krb5_app_req.data; |
| 472 | ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen); | 494 | ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen); |
| 473 | if (ap_req) | 495 | if (ap_req) { |
| 474 | { | ||
| 475 | authenp->length = i2d_KRB5_ENCDATA( | 496 | authenp->length = i2d_KRB5_ENCDATA( |
| 476 | ap_req->authenticator, NULL); | 497 | ap_req->authenticator, NULL); |
| 477 | if (authenp->length && | 498 | if (authenp->length && |
| 478 | (authenp->data = malloc(authenp->length))) | 499 | (authenp->data = malloc(authenp->length))) { |
| 479 | { | ||
| 480 | unsigned char *adp = (unsigned char *)authenp->data; | 500 | unsigned char *adp = (unsigned char *)authenp->data; |
| 481 | authenp->length = i2d_KRB5_ENCDATA( | 501 | authenp->length = i2d_KRB5_ENCDATA( |
| 482 | ap_req->authenticator, &adp); | 502 | ap_req->authenticator, &adp); |
| 483 | } | ||
| 484 | } | 503 | } |
| 485 | |||
| 486 | if (ap_req) KRB5_APREQ_free((KRB5_APREQ *) ap_req); | ||
| 487 | if (krb5_app_req.length) | ||
| 488 | kssl_krb5_free_data_contents(krb5context,&krb5_app_req); | ||
| 489 | } | 504 | } |
| 505 | |||
| 506 | if (ap_req) | ||
| 507 | KRB5_APREQ_free((KRB5_APREQ *) ap_req); | ||
| 508 | if (krb5_app_req.length) | ||
| 509 | kssl_krb5_free_data_contents(krb5context, &krb5_app_req); | ||
| 510 | } | ||
| 490 | #ifdef KRB5_HEIMDAL | 511 | #ifdef KRB5_HEIMDAL |
| 491 | if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) | 512 | if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) { |
| 492 | { | ||
| 493 | kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, | 513 | kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, |
| 494 | "kssl_ctx_setkey() fails.\n"); | 514 | "kssl_ctx_setkey() fails.\n"); |
| 495 | } | 515 | } |
| 496 | #else | 516 | #else |
| 497 | if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) | 517 | if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) { |
| 498 | { | ||
| 499 | kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, | 518 | kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, |
| 500 | "kssl_ctx_setkey() fails.\n"); | 519 | "kssl_ctx_setkey() fails.\n"); |
| 501 | } | 520 | } |
| 502 | #endif | 521 | #endif |
| 503 | else krb5rc = 0; | 522 | else |
| 523 | krb5rc = 0; | ||
| 504 | 524 | ||
| 505 | err: | 525 | err: |
| 506 | #ifdef KSSL_DEBUG | 526 | #ifdef KSSL_DEBUG |
| 507 | kssl_ctx_show(kssl_ctx); | 527 | kssl_ctx_show(kssl_ctx); |
| 508 | #endif /* KSSL_DEBUG */ | 528 | #endif /* KSSL_DEBUG */ |
| 509 | 529 | ||
| 510 | if (krb5creds.client) krb5_free_principal(krb5context, | 530 | if (krb5creds.client) |
| 511 | krb5creds.client); | 531 | krb5_free_principal(krb5context, krb5creds.client); |
| 512 | if (krb5creds.server) krb5_free_principal(krb5context, | 532 | if (krb5creds.server) |
| 513 | krb5creds.server); | 533 | krb5_free_principal(krb5context, krb5creds.server); |
| 514 | if (krb5auth_context) krb5_auth_con_free(krb5context, | 534 | if (krb5auth_context) |
| 515 | krb5auth_context); | 535 | krb5_auth_con_free(krb5context, krb5auth_context); |
| 516 | if (krb5context) krb5_free_context(krb5context); | 536 | if (krb5context) |
| 537 | krb5_free_context(krb5context); | ||
| 517 | return (krb5rc); | 538 | return (krb5rc); |
| 518 | } | 539 | } |
| 519 | 540 | ||
| 520 | 541 | ||
| 521 | /* Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. | 542 | /* Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. |
| @@ -530,76 +551,71 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 530 | ** like the real thing. | 551 | ** like the real thing. |
| 531 | */ | 552 | */ |
| 532 | static krb5_error_code | 553 | static krb5_error_code |
| 533 | kssl_TKT2tkt( /* IN */ krb5_context krb5context, | 554 | kssl_TKT2tkt( |
| 534 | /* IN */ KRB5_TKTBODY *asn1ticket, | 555 | /* IN */ krb5_context krb5context, |
| 535 | /* OUT */ krb5_ticket **krb5ticket, | 556 | /* IN */ KRB5_TKTBODY *asn1ticket, |
| 536 | /* OUT */ KSSL_ERR *kssl_err ) | 557 | /* OUT */ krb5_ticket **krb5ticket, |
| 537 | { | 558 | /* OUT */ KSSL_ERR *kssl_err ) |
| 559 | { | ||
| 538 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 560 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
| 539 | krb5_ticket *new5ticket = NULL; | 561 | krb5_ticket *new5ticket = NULL; |
| 540 | ASN1_GENERALSTRING *gstr_svc, *gstr_host; | 562 | ASN1_GENERALSTRING *gstr_svc, *gstr_host; |
| 541 | 563 | ||
| 542 | *krb5ticket = NULL; | 564 | *krb5ticket = NULL; |
| 543 | 565 | ||
| 544 | if (asn1ticket == NULL || asn1ticket->realm == NULL || | 566 | if (asn1ticket == NULL || asn1ticket->realm == NULL || |
| 545 | asn1ticket->sname == NULL || | 567 | asn1ticket->sname == NULL || |
| 546 | sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) | 568 | sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) { |
| 547 | { | ||
| 548 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 569 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 549 | "Null field in asn1ticket.\n"); | 570 | "Null field in asn1ticket.\n"); |
| 550 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 571 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 551 | return KRB5KRB_ERR_GENERIC; | 572 | return KRB5KRB_ERR_GENERIC; |
| 552 | } | 573 | } |
| 553 | 574 | ||
| 554 | if ((new5ticket = (krb5_ticket *) calloc(1, sizeof(krb5_ticket)))==NULL) | 575 | if ((new5ticket = |
| 555 | { | 576 | (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) { |
| 556 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 577 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 557 | "Unable to allocate new krb5_ticket.\n"); | 578 | "Unable to allocate new krb5_ticket.\n"); |
| 558 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 579 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 559 | return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ | 580 | return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ |
| 560 | } | 581 | } |
| 561 | 582 | ||
| 562 | gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); | 583 | gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); |
| 563 | gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); | 584 | gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); |
| 564 | 585 | ||
| 565 | if ((krb5rc = kssl_build_principal_2(krb5context, | 586 | if ((krb5rc = kssl_build_principal_2(krb5context, &new5ticket->server, |
| 566 | &new5ticket->server, | 587 | asn1ticket->realm->length, (char *)asn1ticket->realm->data, |
| 567 | asn1ticket->realm->length, (char *)asn1ticket->realm->data, | 588 | gstr_svc->length, (char *)gstr_svc->data, gstr_host->length, |
| 568 | gstr_svc->length, (char *)gstr_svc->data, | 589 | (char *)gstr_host->data)) != 0) { |
| 569 | gstr_host->length, (char *)gstr_host->data)) != 0) | ||
| 570 | { | ||
| 571 | free(new5ticket); | 590 | free(new5ticket); |
| 572 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 591 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 573 | "Error building ticket server principal.\n"); | 592 | "Error building ticket server principal.\n"); |
| 574 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 593 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 575 | return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ | 594 | return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ |
| 576 | } | 595 | } |
| 577 | 596 | ||
| 578 | krb5_princ_type(krb5context, new5ticket->server) = | 597 | krb5_princ_type(krb5context, new5ticket->server) = |
| 579 | asn1ticket->sname->nametype->data[0]; | 598 | asn1ticket->sname->nametype->data[0]; |
| 580 | new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; | 599 | new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; |
| 581 | new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; | 600 | new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; |
| 582 | new5ticket->enc_part.ciphertext.length = | 601 | new5ticket->enc_part.ciphertext.length = |
| 583 | asn1ticket->encdata->cipher->length; | 602 | asn1ticket->encdata->cipher->length; |
| 584 | if ((new5ticket->enc_part.ciphertext.data = | 603 | if ((new5ticket->enc_part.ciphertext.data = |
| 585 | calloc(1, asn1ticket->encdata->cipher->length)) == NULL) | 604 | calloc(1, asn1ticket->encdata->cipher->length)) == NULL) { |
| 586 | { | ||
| 587 | free(new5ticket); | 605 | free(new5ticket); |
| 588 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 606 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 589 | "Error allocating cipher in krb5ticket.\n"); | 607 | "Error allocating cipher in krb5ticket.\n"); |
| 590 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 608 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 591 | return KRB5KRB_ERR_GENERIC; | 609 | return KRB5KRB_ERR_GENERIC; |
| 592 | } | 610 | } else { |
| 593 | else | ||
| 594 | { | ||
| 595 | memcpy(new5ticket->enc_part.ciphertext.data, | 611 | memcpy(new5ticket->enc_part.ciphertext.data, |
| 596 | asn1ticket->encdata->cipher->data, | 612 | asn1ticket->encdata->cipher->data, |
| 597 | asn1ticket->encdata->cipher->length); | 613 | asn1ticket->encdata->cipher->length); |
| 598 | } | 614 | } |
| 599 | 615 | ||
| 600 | *krb5ticket = new5ticket; | 616 | *krb5ticket = new5ticket; |
| 601 | return 0; | 617 | return 0; |
| 602 | } | 618 | } |
| 603 | 619 | ||
| 604 | 620 | ||
| 605 | /* Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), | 621 | /* Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), |
| @@ -610,11 +626,12 @@ kssl_TKT2tkt( /* IN */ krb5_context krb5context, | |||
| 610 | ** 19990702 VRS Started. | 626 | ** 19990702 VRS Started. |
| 611 | */ | 627 | */ |
| 612 | krb5_error_code | 628 | krb5_error_code |
| 613 | kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | 629 | kssl_sget_tkt( |
| 614 | /* IN */ krb5_data *indata, | 630 | /* UPDATE */ KSSL_CTX *kssl_ctx, |
| 615 | /* OUT */ krb5_ticket_times *ttimes, | 631 | /* IN */ krb5_data *indata, |
| 616 | /* OUT */ KSSL_ERR *kssl_err ) | 632 | /* OUT */ krb5_ticket_times *ttimes, |
| 617 | { | 633 | /* OUT */ KSSL_ERR *kssl_err ) |
| 634 | { | ||
| 618 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 635 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
| 619 | static krb5_context krb5context = NULL; | 636 | static krb5_context krb5context = NULL; |
| 620 | static krb5_auth_context krb5auth_context = NULL; | 637 | static krb5_auth_context krb5auth_context = NULL; |
| @@ -628,100 +645,86 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 628 | 645 | ||
| 629 | kssl_err_set(kssl_err, 0, ""); | 646 | kssl_err_set(kssl_err, 0, ""); |
| 630 | 647 | ||
| 631 | if (!kssl_ctx) | 648 | if (!kssl_ctx) { |
| 632 | { | ||
| 633 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 649 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 634 | "No kssl_ctx defined.\n"); | 650 | "No kssl_ctx defined.\n"); |
| 635 | goto err; | 651 | goto err; |
| 636 | } | 652 | } |
| 637 | 653 | ||
| 638 | #ifdef KSSL_DEBUG | 654 | #ifdef KSSL_DEBUG |
| 639 | printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); | 655 | printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); |
| 640 | #endif /* KSSL_DEBUG */ | 656 | #endif /* KSSL_DEBUG */ |
| 641 | 657 | ||
| 642 | if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) | 658 | if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) { |
| 643 | { | ||
| 644 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 659 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 645 | "krb5_init_context() fails.\n"); | 660 | "krb5_init_context() fails.\n"); |
| 646 | goto err; | 661 | goto err; |
| 647 | } | 662 | } |
| 648 | if (krb5auth_context && | 663 | if (krb5auth_context && |
| 649 | (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) | 664 | (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) { |
| 650 | { | ||
| 651 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 665 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 652 | "krb5_auth_con_free() fails.\n"); | 666 | "krb5_auth_con_free() fails.\n"); |
| 653 | goto err; | 667 | goto err; |
| 654 | } | 668 | } else |
| 655 | else krb5auth_context = NULL; | 669 | krb5auth_context = NULL; |
| 656 | if (!krb5auth_context && | 670 | if (!krb5auth_context && |
| 657 | (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) | 671 | (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) { |
| 658 | { | ||
| 659 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 672 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 660 | "krb5_auth_con_init() fails.\n"); | 673 | "krb5_auth_con_init() fails.\n"); |
| 661 | goto err; | 674 | goto err; |
| 662 | } | 675 | } |
| 663 | 676 | ||
| 664 | |||
| 665 | if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, | 677 | if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, |
| 666 | &rcache))) | 678 | &rcache))) { |
| 667 | { | 679 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 668 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 680 | "krb5_auth_con_getrcache() fails.\n"); |
| 669 | "krb5_auth_con_getrcache() fails.\n"); | 681 | goto err; |
| 670 | goto err; | 682 | } |
| 671 | } | 683 | |
| 672 | |||
| 673 | if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, | 684 | if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, |
| 674 | (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, | 685 | (kssl_ctx->service_name) ? kssl_ctx->service_name : KRB5SVC, |
| 675 | KRB5_NT_SRV_HST, &krb5server)) != 0) | 686 | KRB5_NT_SRV_HST, &krb5server)) != 0) { |
| 676 | { | ||
| 677 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 687 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 678 | "krb5_sname_to_principal() fails.\n"); | 688 | "krb5_sname_to_principal() fails.\n"); |
| 679 | goto err; | 689 | goto err; |
| 690 | } | ||
| 691 | |||
| 692 | if (rcache == NULL) { | ||
| 693 | if ((krb5rc = krb5_get_server_rcache(krb5context, | ||
| 694 | krb5_princ_component(krb5context, krb5server, 0), | ||
| 695 | &rcache))) { | ||
| 696 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | ||
| 697 | "krb5_get_server_rcache() fails.\n"); | ||
| 698 | goto err; | ||
| 680 | } | 699 | } |
| 700 | } | ||
| 681 | 701 | ||
| 682 | if (rcache == NULL) | 702 | if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, |
| 683 | { | 703 | rcache))) { |
| 684 | if ((krb5rc = krb5_get_server_rcache(krb5context, | 704 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 685 | krb5_princ_component(krb5context, krb5server, 0), | 705 | "krb5_auth_con_setrcache() fails.\n"); |
| 686 | &rcache))) | 706 | goto err; |
| 687 | { | 707 | } |
| 688 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | ||
| 689 | "krb5_get_server_rcache() fails.\n"); | ||
| 690 | goto err; | ||
| 691 | } | ||
| 692 | } | ||
| 693 | |||
| 694 | if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) | ||
| 695 | { | ||
| 696 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | ||
| 697 | "krb5_auth_con_setrcache() fails.\n"); | ||
| 698 | goto err; | ||
| 699 | } | ||
| 700 | 708 | ||
| 701 | 709 | ||
| 702 | /* kssl_ctx->keytab_file == NULL ==> use Kerberos default | 710 | /* kssl_ctx->keytab_file == NULL ==> use Kerberos default |
| 703 | */ | 711 | */ |
| 704 | if (kssl_ctx->keytab_file) | 712 | if (kssl_ctx->keytab_file) { |
| 705 | { | ||
| 706 | krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, | 713 | krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, |
| 707 | &krb5keytab); | 714 | &krb5keytab); |
| 708 | if (krb5rc) | 715 | if (krb5rc) { |
| 709 | { | ||
| 710 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 716 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 711 | "krb5_kt_resolve() fails.\n"); | 717 | "krb5_kt_resolve() fails.\n"); |
| 712 | goto err; | 718 | goto err; |
| 713 | } | ||
| 714 | } | 719 | } |
| 715 | else | 720 | } else { |
| 716 | { | 721 | krb5rc = krb5_kt_default(krb5context, &krb5keytab); |
| 717 | krb5rc = krb5_kt_default(krb5context,&krb5keytab); | 722 | if (krb5rc) { |
| 718 | if (krb5rc) | 723 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 719 | { | 724 | "krb5_kt_default() fails.\n"); |
| 720 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | ||
| 721 | "krb5_kt_default() fails.\n"); | ||
| 722 | goto err; | 725 | goto err; |
| 723 | } | ||
| 724 | } | 726 | } |
| 727 | } | ||
| 725 | 728 | ||
| 726 | /* Actual Kerberos5 krb5_recvauth() has initial conversation here | 729 | /* Actual Kerberos5 krb5_recvauth() has initial conversation here |
| 727 | ** o check KRB5_SENDAUTH_BADAUTHVERS | 730 | ** o check KRB5_SENDAUTH_BADAUTHVERS |
| @@ -739,157 +742,156 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, | |||
| 739 | 742 | ||
| 740 | p = (unsigned char *)indata->data; | 743 | p = (unsigned char *)indata->data; |
| 741 | if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p, | 744 | if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p, |
| 742 | (long) indata->length)) == NULL) | 745 | (long)indata->length)) == NULL) { |
| 743 | { | ||
| 744 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 746 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 745 | "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); | 747 | "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); |
| 746 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 748 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 747 | goto err; | 749 | goto err; |
| 748 | } | 750 | } |
| 749 | 751 | ||
| 750 | /* Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) */ | 752 | /* Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) */ |
| 751 | if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, | 753 | if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, |
| 752 | kssl_err)) != 0) | 754 | kssl_err)) != 0) { |
| 753 | { | ||
| 754 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 755 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 755 | "Error converting ASN.1 ticket to krb5_ticket.\n"); | 756 | "Error converting ASN.1 ticket to krb5_ticket.\n"); |
| 756 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 757 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 757 | goto err; | 758 | goto err; |
| 758 | } | 759 | } |
| 759 | 760 | ||
| 760 | if (! krb5_principal_compare(krb5context, krb5server, | 761 | if (!krb5_principal_compare(krb5context, krb5server, |
| 761 | krb5ticket->server)) { | 762 | krb5ticket->server)) { |
| 762 | krb5rc = KRB5_PRINC_NOMATCH; | 763 | krb5rc = KRB5_PRINC_NOMATCH; |
| 763 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 764 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 764 | "server principal != ticket principal\n"); | 765 | "server principal != ticket principal\n"); |
| 765 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 766 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 766 | goto err; | 767 | goto err; |
| 767 | } | 768 | } |
| 768 | if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, | 769 | if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, |
| 769 | krb5ticket->server, krb5ticket->enc_part.kvno, | 770 | krb5ticket->server, krb5ticket->enc_part.kvno, |
| 770 | krb5ticket->enc_part.enctype, &kt_entry)) != 0) { | 771 | krb5ticket->enc_part.enctype, &kt_entry)) != 0) { |
| 771 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 772 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 772 | "krb5_kt_get_entry() fails with %x.\n", krb5rc); | 773 | "krb5_kt_get_entry() fails with %x.\n", krb5rc); |
| 773 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 774 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 774 | goto err; | 775 | goto err; |
| 775 | } | 776 | } |
| 776 | if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, | 777 | if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, |
| 777 | krb5ticket)) != 0) { | 778 | krb5ticket)) != 0) { |
| 778 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, | 779 | BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, |
| 779 | "krb5_decrypt_tkt_part() failed.\n"); | 780 | "krb5_decrypt_tkt_part() failed.\n"); |
| 780 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; | 781 | kssl_err->reason = SSL_R_KRB5_S_RD_REQ; |
| 781 | goto err; | 782 | goto err; |
| 782 | } | 783 | } else { |
| 783 | else { | ||
| 784 | krb5_kt_free_entry(krb5context, &kt_entry); | 784 | krb5_kt_free_entry(krb5context, &kt_entry); |
| 785 | #ifdef KSSL_DEBUG | 785 | #ifdef KSSL_DEBUG |
| 786 | { | 786 | { |
| 787 | int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs; | 787 | int i; |
| 788 | printf("Decrypted ticket fields:\n"); | 788 | krb5_address **paddr = krb5ticket->enc_part2->caddrs; |
| 789 | printf("\tflags: %X, transit-type: %X", | 789 | printf("Decrypted ticket fields:\n"); |
| 790 | printf("\tflags: %X, transit-type: %X", | ||
| 790 | krb5ticket->enc_part2->flags, | 791 | krb5ticket->enc_part2->flags, |
| 791 | krb5ticket->enc_part2->transited.tr_type); | 792 | krb5ticket->enc_part2->transited.tr_type); |
| 792 | print_krb5_data("\ttransit-data: ", | 793 | print_krb5_data("\ttransit-data: ", |
| 793 | &(krb5ticket->enc_part2->transited.tr_contents)); | 794 | &(krb5ticket->enc_part2->transited.tr_contents)); |
| 794 | printf("\tcaddrs: %p, authdata: %p\n", | 795 | printf("\tcaddrs: %p, authdata: %p\n", |
| 795 | krb5ticket->enc_part2->caddrs, | 796 | krb5ticket->enc_part2->caddrs, |
| 796 | krb5ticket->enc_part2->authorization_data); | 797 | krb5ticket->enc_part2->authorization_data); |
| 797 | if (paddr) | 798 | if (paddr) { |
| 798 | { | 799 | printf("\tcaddrs:\n"); |
| 799 | printf("\tcaddrs:\n"); | 800 | for (i = 0; paddr[i] != NULL; i++) { |
| 800 | for (i=0; paddr[i] != NULL; i++) | 801 | krb5_data d; |
| 801 | { | 802 | d.length = paddr[i]->length; |
| 802 | krb5_data d; | 803 | d.data = paddr[i]->contents; |
| 803 | d.length=paddr[i]->length; | 804 | print_krb5_data("\t\tIP: ", &d); |
| 804 | d.data=paddr[i]->contents; | ||
| 805 | print_krb5_data("\t\tIP: ", &d); | ||
| 806 | } | 805 | } |
| 807 | } | 806 | } |
| 808 | printf("\tstart/auth/end times: %d / %d / %d\n", | 807 | printf("\tstart/auth/end times: %d / %d / %d\n", |
| 809 | krb5ticket->enc_part2->times.starttime, | 808 | krb5ticket->enc_part2->times.starttime, |
| 810 | krb5ticket->enc_part2->times.authtime, | 809 | krb5ticket->enc_part2->times.authtime, |
| 811 | krb5ticket->enc_part2->times.endtime); | 810 | krb5ticket->enc_part2->times.endtime); |
| 812 | } | 811 | } |
| 813 | #endif /* KSSL_DEBUG */ | 812 | #endif /* KSSL_DEBUG */ |
| 814 | } | 813 | } |
| 815 | 814 | ||
| 816 | krb5rc = KRB5_NO_TKT_SUPPLIED; | 815 | krb5rc = KRB5_NO_TKT_SUPPLIED; |
| 817 | if (!krb5ticket || !krb5ticket->enc_part2 || | 816 | if (!krb5ticket || !krb5ticket->enc_part2 || |
| 818 | !krb5ticket->enc_part2->client || | 817 | !krb5ticket->enc_part2->client || |
| 819 | !krb5ticket->enc_part2->client->data || | 818 | !krb5ticket->enc_part2->client->data || |
| 820 | !krb5ticket->enc_part2->session) | 819 | !krb5ticket->enc_part2->session) { |
| 821 | { | ||
| 822 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, | ||
| 823 | "bad ticket from krb5_rd_req.\n"); | ||
| 824 | } | ||
| 825 | else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, | ||
| 826 | &krb5ticket->enc_part2->client->realm, | ||
| 827 | krb5ticket->enc_part2->client->data, | ||
| 828 | krb5ticket->enc_part2->client->length)) | ||
| 829 | { | ||
| 830 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, | 820 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, |
| 831 | "kssl_ctx_setprinc() fails.\n"); | 821 | "bad ticket from krb5_rd_req.\n"); |
| 832 | } | 822 | } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, |
| 833 | else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) | 823 | &krb5ticket->enc_part2->client->realm, |
| 834 | { | 824 | krb5ticket->enc_part2->client->data, |
| 825 | krb5ticket->enc_part2->client->length)) { | ||
| 835 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, | 826 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, |
| 836 | "kssl_ctx_setkey() fails.\n"); | 827 | "kssl_ctx_setprinc() fails.\n"); |
| 837 | } | 828 | } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) { |
| 838 | else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) | 829 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, |
| 839 | { | 830 | "kssl_ctx_setkey() fails.\n"); |
| 831 | } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) { | ||
| 840 | krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; | 832 | krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; |
| 841 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, | 833 | kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, |
| 842 | "invalid ticket from krb5_rd_req.\n"); | 834 | "invalid ticket from krb5_rd_req.\n"); |
| 843 | } | 835 | } else |
| 844 | else krb5rc = 0; | 836 | krb5rc = 0; |
| 845 | 837 | ||
| 846 | kssl_ctx->enctype = krb5ticket->enc_part.enctype; | 838 | kssl_ctx->enctype = krb5ticket->enc_part.enctype; |
| 847 | ttimes->authtime = krb5ticket->enc_part2->times.authtime; | 839 | ttimes->authtime = krb5ticket->enc_part2->times.authtime; |
| 848 | ttimes->starttime = krb5ticket->enc_part2->times.starttime; | 840 | ttimes->starttime = krb5ticket->enc_part2->times.starttime; |
| 849 | ttimes->endtime = krb5ticket->enc_part2->times.endtime; | 841 | ttimes->endtime = krb5ticket->enc_part2->times.endtime; |
| 850 | ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; | 842 | ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; |
| 851 | 843 | ||
| 852 | err: | 844 | err: |
| 853 | #ifdef KSSL_DEBUG | 845 | #ifdef KSSL_DEBUG |
| 854 | kssl_ctx_show(kssl_ctx); | 846 | kssl_ctx_show(kssl_ctx); |
| 855 | #endif /* KSSL_DEBUG */ | 847 | #endif /* KSSL_DEBUG */ |
| 856 | 848 | ||
| 857 | if (asn1ticket) KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); | 849 | if (asn1ticket) |
| 858 | if (krb5keytab) krb5_kt_close(krb5context, krb5keytab); | 850 | KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); |
| 859 | if (krb5ticket) krb5_free_ticket(krb5context, krb5ticket); | 851 | if (krb5keytab) |
| 860 | if (krb5server) krb5_free_principal(krb5context, krb5server); | 852 | krb5_kt_close(krb5context, krb5keytab); |
| 853 | if (krb5ticket) | ||
| 854 | krb5_free_ticket(krb5context, krb5ticket); | ||
| 855 | if (krb5server) | ||
| 856 | krb5_free_principal(krb5context, krb5server); | ||
| 861 | return (krb5rc); | 857 | return (krb5rc); |
| 862 | } | 858 | } |
| 863 | 859 | ||
| 864 | 860 | ||
| 865 | /* Allocate & return a new kssl_ctx struct. | 861 | /* Allocate & return a new kssl_ctx struct. |
| 866 | */ | 862 | */ |
| 867 | KSSL_CTX * | 863 | KSSL_CTX * |
| 868 | kssl_ctx_new(void) | 864 | kssl_ctx_new(void) |
| 869 | { | 865 | { |
| 870 | return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX))); | 866 | return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX))); |
| 871 | } | 867 | } |
| 872 | 868 | ||
| 873 | 869 | ||
| 874 | /* Frees a kssl_ctx struct and any allocated memory it holds. | 870 | /* Frees a kssl_ctx struct and any allocated memory it holds. |
| 875 | ** Returns NULL. | 871 | ** Returns NULL. |
| 876 | */ | 872 | */ |
| 877 | KSSL_CTX * | 873 | KSSL_CTX * |
| 878 | kssl_ctx_free(KSSL_CTX *kssl_ctx) | 874 | kssl_ctx_free(KSSL_CTX *kssl_ctx) |
| 879 | { | 875 | { |
| 880 | if (kssl_ctx == NULL) return kssl_ctx; | 876 | if (kssl_ctx == NULL) |
| 877 | return kssl_ctx; | ||
| 881 | 878 | ||
| 882 | if (kssl_ctx->key) OPENSSL_cleanse(kssl_ctx->key, | 879 | if (kssl_ctx->key) |
| 883 | kssl_ctx->length); | 880 | OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); |
| 884 | if (kssl_ctx->key) kssl_free(kssl_ctx->key); | 881 | if (kssl_ctx->key) |
| 885 | if (kssl_ctx->client_princ) kssl_free(kssl_ctx->client_princ); | 882 | kssl_free(kssl_ctx->key); |
| 886 | if (kssl_ctx->service_host) kssl_free(kssl_ctx->service_host); | 883 | if (kssl_ctx->client_princ) |
| 887 | if (kssl_ctx->service_name) kssl_free(kssl_ctx->service_name); | 884 | kssl_free(kssl_ctx->client_princ); |
| 888 | if (kssl_ctx->keytab_file) kssl_free(kssl_ctx->keytab_file); | 885 | if (kssl_ctx->service_host) |
| 886 | kssl_free(kssl_ctx->service_host); | ||
| 887 | if (kssl_ctx->service_name) | ||
| 888 | kssl_free(kssl_ctx->service_name); | ||
| 889 | if (kssl_ctx->keytab_file) | ||
| 890 | kssl_free(kssl_ctx->keytab_file); | ||
| 889 | 891 | ||
| 890 | kssl_free(kssl_ctx); | 892 | kssl_free(kssl_ctx); |
| 891 | return (KSSL_CTX *) NULL; | 893 | return (KSSL_CTX *) NULL; |
| 892 | } | 894 | } |
| 893 | 895 | ||
| 894 | 896 | ||
| 895 | /* Given an array of (krb5_data *) entity (and optional realm), | 897 | /* Given an array of (krb5_data *) entity (and optional realm), |
| @@ -897,55 +899,57 @@ kssl_ctx_free(KSSL_CTX *kssl_ctx) | |||
| 897 | ** of the kssl_ctx struct. | 899 | ** of the kssl_ctx struct. |
| 898 | */ | 900 | */ |
| 899 | krb5_error_code | 901 | krb5_error_code |
| 900 | kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, | 902 | kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, krb5_data *realm, |
| 901 | krb5_data *realm, krb5_data *entity, int nentities) | 903 | krb5_data *entity, int nentities) |
| 902 | { | 904 | { |
| 903 | char **princ; | 905 | char **princ; |
| 904 | int length; | 906 | int length; |
| 905 | int i; | 907 | int i; |
| 906 | 908 | ||
| 907 | if (kssl_ctx == NULL || entity == NULL) return KSSL_CTX_ERR; | 909 | if (kssl_ctx == NULL || entity == NULL) |
| 910 | return KSSL_CTX_ERR; | ||
| 908 | 911 | ||
| 909 | switch (which) | 912 | switch (which) { |
| 910 | { | 913 | case KSSL_CLIENT: |
| 911 | case KSSL_CLIENT: princ = &kssl_ctx->client_princ; break; | 914 | princ = &kssl_ctx->client_princ; |
| 912 | case KSSL_SERVER: princ = &kssl_ctx->service_host; break; | 915 | break; |
| 913 | default: return KSSL_CTX_ERR; break; | 916 | case KSSL_SERVER: |
| 914 | } | 917 | princ = &kssl_ctx->service_host; |
| 915 | if (*princ) kssl_free(*princ); | 918 | break; |
| 919 | default: | ||
| 920 | return KSSL_CTX_ERR; | ||
| 921 | break; | ||
| 922 | } | ||
| 923 | if (*princ) | ||
| 924 | kssl_free(*princ); | ||
| 916 | 925 | ||
| 917 | /* Add up all the entity->lengths */ | 926 | /* Add up all the entity->lengths */ |
| 918 | length = 0; | 927 | length = 0; |
| 919 | for (i=0; i < nentities; i++) | 928 | for (i = 0; i < nentities; i++) { |
| 920 | { | ||
| 921 | length += entity[i].length; | 929 | length += entity[i].length; |
| 922 | } | 930 | } |
| 923 | /* Add in space for the '/' character(s) (if any) */ | 931 | /* Add in space for the '/' character(s) (if any) */ |
| 924 | length += nentities-1; | 932 | length += nentities - 1; |
| 925 | /* Space for the ('@'+realm+NULL | NULL) */ | 933 | /* Space for the ('@'+realm+NULL | NULL) */ |
| 926 | length += ((realm)? realm->length + 2: 1); | 934 | length += ((realm) ? realm->length + 2 : 1); |
| 927 | 935 | ||
| 928 | if ((*princ = kssl_calloc(1, length)) == NULL) | 936 | if ((*princ = kssl_calloc(1, length)) == NULL) |
| 929 | return KSSL_CTX_ERR; | 937 | return KSSL_CTX_ERR; |
| 930 | else | 938 | else { |
| 931 | { | 939 | for (i = 0; i < nentities; i++) { |
| 932 | for (i = 0; i < nentities; i++) | ||
| 933 | { | ||
| 934 | strncat(*princ, entity[i].data, entity[i].length); | 940 | strncat(*princ, entity[i].data, entity[i].length); |
| 935 | if (i < nentities-1) | 941 | if (i < nentities - 1) { |
| 936 | { | ||
| 937 | strcat (*princ, "/"); | 942 | strcat (*princ, "/"); |
| 938 | } | ||
| 939 | } | 943 | } |
| 940 | if (realm) | 944 | } |
| 941 | { | 945 | if (realm) { |
| 942 | strcat (*princ, "@"); | 946 | strcat (*princ, "@"); |
| 943 | (void) strncat(*princ, realm->data, realm->length); | 947 | (void) strncat(*princ, realm->data, realm->length); |
| 944 | } | ||
| 945 | } | 948 | } |
| 949 | } | ||
| 946 | 950 | ||
| 947 | return KSSL_CTX_OK; | 951 | return KSSL_CTX_OK; |
| 948 | } | 952 | } |
| 949 | 953 | ||
| 950 | 954 | ||
| 951 | /* Set one of the plain (char *) string members of the kssl_ctx struct. | 955 | /* Set one of the plain (char *) string members of the kssl_ctx struct. |
| @@ -955,26 +959,36 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, | |||
| 955 | */ | 959 | */ |
| 956 | krb5_error_code | 960 | krb5_error_code |
| 957 | kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) | 961 | kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) |
| 958 | { | 962 | { |
| 959 | char **string; | 963 | char **string; |
| 960 | 964 | ||
| 961 | if (!kssl_ctx) return KSSL_CTX_ERR; | 965 | if (!kssl_ctx) |
| 966 | return KSSL_CTX_ERR; | ||
| 962 | 967 | ||
| 963 | switch (which) | 968 | switch (which) { |
| 964 | { | 969 | case KSSL_SERVICE: |
| 965 | case KSSL_SERVICE: string = &kssl_ctx->service_name; break; | 970 | string = &kssl_ctx->service_name; |
| 966 | case KSSL_SERVER: string = &kssl_ctx->service_host; break; | 971 | break; |
| 967 | case KSSL_CLIENT: string = &kssl_ctx->client_princ; break; | 972 | case KSSL_SERVER: |
| 968 | case KSSL_KEYTAB: string = &kssl_ctx->keytab_file; break; | 973 | string = &kssl_ctx->service_host; |
| 969 | default: return KSSL_CTX_ERR; break; | 974 | break; |
| 970 | } | 975 | case KSSL_CLIENT: |
| 971 | if (*string) kssl_free(*string); | 976 | string = &kssl_ctx->client_princ; |
| 977 | break; | ||
| 978 | case KSSL_KEYTAB: | ||
| 979 | string = &kssl_ctx->keytab_file; | ||
| 980 | break; | ||
| 981 | default: | ||
| 982 | return KSSL_CTX_ERR; | ||
| 983 | break; | ||
| 984 | } | ||
| 985 | if (*string) | ||
| 986 | kssl_free(*string); | ||
| 972 | 987 | ||
| 973 | if (!text) | 988 | if (!text) { |
| 974 | { | ||
| 975 | *string = '\0'; | 989 | *string = '\0'; |
| 976 | return KSSL_CTX_OK; | 990 | return KSSL_CTX_OK; |
| 977 | } | 991 | } |
| 978 | 992 | ||
| 979 | if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) | 993 | if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) |
| 980 | return KSSL_CTX_ERR; | 994 | return KSSL_CTX_ERR; |
| @@ -982,7 +996,7 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) | |||
| 982 | memcpy(*string, text, strlen(text) + 1); | 996 | memcpy(*string, text, strlen(text) + 1); |
| 983 | 997 | ||
| 984 | return KSSL_CTX_OK; | 998 | return KSSL_CTX_OK; |
| 985 | } | 999 | } |
| 986 | 1000 | ||
| 987 | 1001 | ||
| 988 | /* Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx | 1002 | /* Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx |
| @@ -990,21 +1004,20 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) | |||
| 990 | */ | 1004 | */ |
| 991 | krb5_error_code | 1005 | krb5_error_code |
| 992 | kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) | 1006 | kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) |
| 993 | { | 1007 | { |
| 994 | int length; | 1008 | int length; |
| 995 | krb5_enctype enctype; | 1009 | krb5_enctype enctype; |
| 996 | krb5_octet FAR *contents = NULL; | 1010 | krb5_octet FAR *contents = NULL; |
| 997 | 1011 | ||
| 998 | if (!kssl_ctx) return KSSL_CTX_ERR; | 1012 | if (!kssl_ctx) |
| 1013 | return KSSL_CTX_ERR; | ||
| 999 | 1014 | ||
| 1000 | if (kssl_ctx->key) | 1015 | if (kssl_ctx->key) { |
| 1001 | { | ||
| 1002 | OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); | 1016 | OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); |
| 1003 | kssl_free(kssl_ctx->key); | 1017 | kssl_free(kssl_ctx->key); |
| 1004 | } | 1018 | } |
| 1005 | 1019 | ||
| 1006 | if (session) | 1020 | if (session) { |
| 1007 | { | ||
| 1008 | 1021 | ||
| 1009 | #ifdef KRB5_HEIMDAL | 1022 | #ifdef KRB5_HEIMDAL |
| 1010 | length = session->keyvalue->length; | 1023 | length = session->keyvalue->length; |
| @@ -1016,186 +1029,182 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) | |||
| 1016 | contents = session->contents; | 1029 | contents = session->contents; |
| 1017 | #endif | 1030 | #endif |
| 1018 | kssl_ctx->enctype = enctype; | 1031 | kssl_ctx->enctype = enctype; |
| 1019 | kssl_ctx->length = length; | 1032 | kssl_ctx->length = length; |
| 1020 | } | 1033 | } else { |
| 1021 | else | ||
| 1022 | { | ||
| 1023 | kssl_ctx->enctype = ENCTYPE_UNKNOWN; | 1034 | kssl_ctx->enctype = ENCTYPE_UNKNOWN; |
| 1024 | kssl_ctx->length = 0; | 1035 | kssl_ctx->length = 0; |
| 1025 | return KSSL_CTX_OK; | 1036 | return KSSL_CTX_OK; |
| 1026 | } | 1037 | } |
| 1027 | 1038 | ||
| 1028 | if ((kssl_ctx->key = | 1039 | if ((kssl_ctx->key = |
| 1029 | (krb5_octet FAR *) kssl_calloc(1, kssl_ctx->length)) == NULL) | 1040 | (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) { |
| 1030 | { | 1041 | kssl_ctx->length = 0; |
| 1031 | kssl_ctx->length = 0; | ||
| 1032 | return KSSL_CTX_ERR; | 1042 | return KSSL_CTX_ERR; |
| 1033 | } | 1043 | } else |
| 1034 | else | ||
| 1035 | memcpy(kssl_ctx->key, contents, length); | 1044 | memcpy(kssl_ctx->key, contents, length); |
| 1036 | 1045 | ||
| 1037 | return KSSL_CTX_OK; | 1046 | return KSSL_CTX_OK; |
| 1038 | } | 1047 | } |
| 1039 | 1048 | ||
| 1040 | 1049 | ||
| 1041 | /* Display contents of kssl_ctx struct | 1050 | /* Display contents of kssl_ctx struct |
| 1042 | */ | 1051 | */ |
| 1043 | void | 1052 | void |
| 1044 | kssl_ctx_show(KSSL_CTX *kssl_ctx) | 1053 | kssl_ctx_show(KSSL_CTX *kssl_ctx) |
| 1045 | { | 1054 | { |
| 1046 | int i; | 1055 | int i; |
| 1047 | 1056 | ||
| 1048 | printf("kssl_ctx: "); | 1057 | printf("kssl_ctx: "); |
| 1049 | if (kssl_ctx == NULL) | 1058 | if (kssl_ctx == NULL) { |
| 1050 | { | ||
| 1051 | printf("NULL\n"); | 1059 | printf("NULL\n"); |
| 1052 | return; | 1060 | return; |
| 1053 | } | 1061 | } else |
| 1054 | else | ||
| 1055 | printf("%p\n", (void *)kssl_ctx); | 1062 | printf("%p\n", (void *)kssl_ctx); |
| 1056 | 1063 | ||
| 1057 | printf("\tservice:\t%s\n", | 1064 | printf("\tservice:\t%s\n", |
| 1058 | (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL"); | 1065 | (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL"); |
| 1059 | printf("\tclient:\t%s\n", | 1066 | printf("\tclient:\t%s\n", |
| 1060 | (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL"); | 1067 | (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL"); |
| 1061 | printf("\tserver:\t%s\n", | 1068 | printf("\tserver:\t%s\n", |
| 1062 | (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL"); | 1069 | (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL"); |
| 1063 | printf("\tkeytab:\t%s\n", | 1070 | printf("\tkeytab:\t%s\n", |
| 1064 | (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL"); | 1071 | (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL"); |
| 1065 | printf("\tkey [%d:%d]:\t", | 1072 | printf("\tkey [%d:%d]:\t", |
| 1066 | kssl_ctx->enctype, kssl_ctx->length); | 1073 | kssl_ctx->enctype, kssl_ctx->length); |
| 1067 | 1074 | ||
| 1068 | for (i=0; i < kssl_ctx->length && kssl_ctx->key; i++) | 1075 | for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) { |
| 1069 | { | ||
| 1070 | printf("%02x", kssl_ctx->key[i]); | 1076 | printf("%02x", kssl_ctx->key[i]); |
| 1071 | } | 1077 | } |
| 1072 | printf("\n"); | 1078 | printf("\n"); |
| 1073 | return; | 1079 | return; |
| 1074 | } | 1080 | } |
| 1075 | 1081 | ||
| 1076 | int | 1082 | int |
| 1077 | kssl_keytab_is_available(KSSL_CTX *kssl_ctx) | 1083 | kssl_keytab_is_available(KSSL_CTX *kssl_ctx) |
| 1078 | { | 1084 | { |
| 1079 | krb5_context krb5context = NULL; | 1085 | krb5_context krb5context = NULL; |
| 1080 | krb5_keytab krb5keytab = NULL; | 1086 | krb5_keytab krb5keytab = NULL; |
| 1081 | krb5_keytab_entry entry; | 1087 | krb5_keytab_entry entry; |
| 1082 | krb5_principal princ = NULL; | 1088 | krb5_principal princ = NULL; |
| 1083 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 1089 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
| 1084 | int rc = 0; | 1090 | int rc = 0; |
| 1085 | 1091 | ||
| 1086 | if ((krb5rc = krb5_init_context(&krb5context))) | 1092 | if ((krb5rc = krb5_init_context(&krb5context))) |
| 1087 | return(0); | 1093 | return (0); |
| 1088 | 1094 | ||
| 1089 | /* kssl_ctx->keytab_file == NULL ==> use Kerberos default | 1095 | /* kssl_ctx->keytab_file == NULL ==> use Kerberos default |
| 1090 | */ | 1096 | */ |
| 1091 | if (kssl_ctx->keytab_file) | 1097 | if (kssl_ctx->keytab_file) { |
| 1092 | { | 1098 | krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, |
| 1093 | krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, | 1099 | &krb5keytab); |
| 1094 | &krb5keytab); | 1100 | if (krb5rc) |
| 1095 | if (krb5rc) | 1101 | goto exit; |
| 1096 | goto exit; | 1102 | } else { |
| 1097 | } | 1103 | krb5rc = krb5_kt_default(krb5context, &krb5keytab); |
| 1098 | else | 1104 | if (krb5rc) |
| 1099 | { | 1105 | goto exit; |
| 1100 | krb5rc = krb5_kt_default(krb5context,&krb5keytab); | 1106 | } |
| 1101 | if (krb5rc) | 1107 | |
| 1102 | goto exit; | 1108 | /* the host key we are looking for */ |
| 1103 | } | 1109 | krb5rc = krb5_sname_to_principal(krb5context, NULL, |
| 1104 | 1110 | kssl_ctx->service_name ? kssl_ctx->service_name : KRB5SVC, | |
| 1105 | /* the host key we are looking for */ | 1111 | KRB5_NT_SRV_HST, &princ); |
| 1106 | krb5rc = krb5_sname_to_principal(krb5context, NULL, | 1112 | |
| 1107 | kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC, | 1113 | if (krb5rc) |
| 1108 | KRB5_NT_SRV_HST, &princ); | 1114 | goto exit; |
| 1109 | 1115 | ||
| 1110 | if (krb5rc) | 1116 | krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, |
| 1111 | goto exit; | 1117 | 0 /* IGNORE_VNO */, |
| 1112 | 1118 | 0 /* IGNORE_ENCTYPE */, | |
| 1113 | krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, | 1119 | &entry); |
| 1114 | princ, | 1120 | if (krb5rc == KRB5_KT_NOTFOUND) { |
| 1115 | 0 /* IGNORE_VNO */, | 1121 | rc = 1; |
| 1116 | 0 /* IGNORE_ENCTYPE */, | 1122 | goto exit; |
| 1117 | &entry); | 1123 | } else if (krb5rc) |
| 1118 | if ( krb5rc == KRB5_KT_NOTFOUND ) { | 1124 | goto exit; |
| 1119 | rc = 1; | 1125 | |
| 1120 | goto exit; | 1126 | krb5_kt_free_entry(krb5context, &entry); |
| 1121 | } else if ( krb5rc ) | 1127 | rc = 1; |
| 1122 | goto exit; | 1128 | |
| 1123 | 1129 | exit: | |
| 1124 | krb5_kt_free_entry(krb5context, &entry); | 1130 | if (krb5keytab) |
| 1125 | rc = 1; | 1131 | krb5_kt_close(krb5context, krb5keytab); |
| 1126 | 1132 | if (princ) | |
| 1127 | exit: | 1133 | krb5_free_principal(krb5context, princ); |
| 1128 | if (krb5keytab) krb5_kt_close(krb5context, krb5keytab); | 1134 | if (krb5context) |
| 1129 | if (princ) krb5_free_principal(krb5context, princ); | 1135 | krb5_free_context(krb5context); |
| 1130 | if (krb5context) krb5_free_context(krb5context); | 1136 | return (rc); |
| 1131 | return(rc); | ||
| 1132 | } | 1137 | } |
| 1133 | 1138 | ||
| 1134 | int | 1139 | int |
| 1135 | kssl_tgt_is_available(KSSL_CTX *kssl_ctx) | 1140 | kssl_tgt_is_available(KSSL_CTX *kssl_ctx) |
| 1136 | { | 1141 | { |
| 1137 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 1142 | krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
| 1138 | krb5_context krb5context = NULL; | 1143 | krb5_context krb5context = NULL; |
| 1139 | krb5_ccache krb5ccdef = NULL; | 1144 | krb5_ccache krb5ccdef = NULL; |
| 1140 | krb5_creds krb5creds, *krb5credsp = NULL; | 1145 | krb5_creds krb5creds, *krb5credsp = NULL; |
| 1141 | int rc = 0; | 1146 | int rc = 0; |
| 1142 | 1147 | ||
| 1143 | memset((char *)&krb5creds, 0, sizeof(krb5creds)); | 1148 | memset((char *)&krb5creds, 0, sizeof(krb5creds)); |
| 1144 | 1149 | ||
| 1145 | if (!kssl_ctx) | 1150 | if (!kssl_ctx) |
| 1146 | return(0); | 1151 | return (0); |
| 1147 | 1152 | ||
| 1148 | if (!kssl_ctx->service_host) | 1153 | if (!kssl_ctx->service_host) |
| 1149 | return(0); | 1154 | return (0); |
| 1150 | 1155 | ||
| 1151 | if ((krb5rc = krb5_init_context(&krb5context)) != 0) | 1156 | if ((krb5rc = krb5_init_context(&krb5context)) != 0) |
| 1152 | goto err; | 1157 | goto err; |
| 1153 | 1158 | ||
| 1154 | if ((krb5rc = krb5_sname_to_principal(krb5context, | 1159 | if ((krb5rc = krb5_sname_to_principal( |
| 1155 | kssl_ctx->service_host, | 1160 | krb5context, kssl_ctx->service_host, |
| 1156 | (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, | 1161 | (kssl_ctx->service_name) ? kssl_ctx->service_name : KRB5SVC, |
| 1157 | KRB5_NT_SRV_HST, &krb5creds.server)) != 0) | 1162 | KRB5_NT_SRV_HST, &krb5creds.server)) != 0) |
| 1158 | goto err; | 1163 | goto err; |
| 1159 | 1164 | ||
| 1160 | if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) | 1165 | if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) |
| 1161 | goto err; | 1166 | goto err; |
| 1162 | 1167 | ||
| 1163 | if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, | 1168 | if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, |
| 1164 | &krb5creds.client)) != 0) | 1169 | &krb5creds.client)) != 0) |
| 1165 | goto err; | 1170 | goto err; |
| 1166 | 1171 | ||
| 1167 | if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, | 1172 | if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, |
| 1168 | &krb5creds, &krb5credsp)) != 0) | 1173 | &krb5creds, &krb5credsp)) != 0) |
| 1169 | goto err; | 1174 | goto err; |
| 1170 | 1175 | ||
| 1171 | rc = 1; | 1176 | rc = 1; |
| 1172 | 1177 | ||
| 1173 | err: | 1178 | err: |
| 1174 | #ifdef KSSL_DEBUG | 1179 | #ifdef KSSL_DEBUG |
| 1175 | kssl_ctx_show(kssl_ctx); | 1180 | kssl_ctx_show(kssl_ctx); |
| 1176 | #endif /* KSSL_DEBUG */ | 1181 | #endif /* KSSL_DEBUG */ |
| 1177 | 1182 | ||
| 1178 | if (krb5creds.client) krb5_free_principal(krb5context, krb5creds.client); | 1183 | if (krb5creds.client) |
| 1179 | if (krb5creds.server) krb5_free_principal(krb5context, krb5creds.server); | 1184 | krb5_free_principal(krb5context, krb5creds.client); |
| 1180 | if (krb5context) krb5_free_context(krb5context); | 1185 | if (krb5creds.server) |
| 1181 | return(rc); | 1186 | krb5_free_principal(krb5context, krb5creds.server); |
| 1182 | } | 1187 | if (krb5context) |
| 1188 | krb5_free_context(krb5context); | ||
| 1189 | return (rc); | ||
| 1190 | } | ||
| 1183 | 1191 | ||
| 1184 | void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) | 1192 | void |
| 1185 | { | 1193 | kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) |
| 1194 | { | ||
| 1186 | #ifdef KRB5_HEIMDAL | 1195 | #ifdef KRB5_HEIMDAL |
| 1187 | data->length = 0; | 1196 | data->length = 0; |
| 1188 | if (data->data) | 1197 | if (data->data) |
| 1189 | free(data->data); | 1198 | free(data->data); |
| 1190 | #elif defined(KRB5_MIT_OLD11) | 1199 | #elif defined(KRB5_MIT_OLD11) |
| 1191 | if (data->data) { | 1200 | if (data->data) { |
| 1192 | krb5_xfree(data->data); | 1201 | krb5_xfree(data->data); |
| 1193 | data->data = 0; | 1202 | data->data = 0; |
| 1194 | } | 1203 | } |
| 1195 | #else | 1204 | #else |
| 1196 | krb5_free_data_contents(NULL, data); | 1205 | krb5_free_data_contents(NULL, data); |
| 1197 | #endif | 1206 | #endif |
| 1198 | } | 1207 | } |
| 1199 | 1208 | ||
| 1200 | /* Given pointers to KerberosTime and struct tm structs, convert the | 1209 | /* Given pointers to KerberosTime and struct tm structs, convert the |
| 1201 | ** KerberosTime string to struct tm. Note that KerberosTime is a | 1210 | ** KerberosTime string to struct tm. Note that KerberosTime is a |
| @@ -1204,25 +1213,52 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) | |||
| 1204 | ** Return pointer to the (partially) filled in struct tm on success, | 1213 | ** Return pointer to the (partially) filled in struct tm on success, |
| 1205 | ** return NULL on failure. | 1214 | ** return NULL on failure. |
| 1206 | */ | 1215 | */ |
| 1207 | static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) | 1216 | static struct tm |
| 1208 | { | 1217 | *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) { |
| 1209 | char c, *p; | 1218 | char c, *p; |
| 1210 | 1219 | ||
| 1211 | if (!k_tm) return NULL; | 1220 | if (!k_tm) |
| 1212 | if (gtime == NULL || gtime->length < 14) return NULL; | 1221 | return NULL; |
| 1213 | if (gtime->data == NULL) return NULL; | 1222 | if (gtime == NULL || gtime->length < 14) |
| 1223 | return NULL; | ||
| 1224 | if (gtime->data == NULL) | ||
| 1225 | return NULL; | ||
| 1214 | 1226 | ||
| 1215 | p = (char *)>ime->data[14]; | 1227 | p = (char *)>ime->data[14]; |
| 1216 | 1228 | ||
| 1217 | c = *p; *p = '\0'; p -= 2; k_tm->tm_sec = atoi(p); *(p+2) = c; | 1229 | c = *p; |
| 1218 | c = *p; *p = '\0'; p -= 2; k_tm->tm_min = atoi(p); *(p+2) = c; | 1230 | *p = '\0'; |
| 1219 | c = *p; *p = '\0'; p -= 2; k_tm->tm_hour = atoi(p); *(p+2) = c; | 1231 | p -= 2; |
| 1220 | c = *p; *p = '\0'; p -= 2; k_tm->tm_mday = atoi(p); *(p+2) = c; | 1232 | k_tm->tm_sec = atoi(p); |
| 1221 | c = *p; *p = '\0'; p -= 2; k_tm->tm_mon = atoi(p)-1; *(p+2) = c; | 1233 | *(p + 2) = c; |
| 1222 | c = *p; *p = '\0'; p -= 4; k_tm->tm_year = atoi(p)-1900; *(p+4) = c; | 1234 | c = *p; |
| 1235 | *p = '\0'; | ||
| 1236 | p -= 2; | ||
| 1237 | k_tm->tm_min = atoi(p); | ||
| 1238 | *(p + 2) = c; | ||
| 1239 | c = *p; | ||
| 1240 | *p = '\0'; | ||
| 1241 | p -= 2; | ||
| 1242 | k_tm->tm_hour = atoi(p); | ||
| 1243 | *(p + 2) = c; | ||
| 1244 | c = *p; | ||
| 1245 | *p = '\0'; | ||
| 1246 | p -= 2; | ||
| 1247 | k_tm->tm_mday = atoi(p); | ||
| 1248 | *(p + 2) = c; | ||
| 1249 | c = *p; | ||
| 1250 | *p = '\0'; | ||
| 1251 | p -= 2; | ||
| 1252 | k_tm->tm_mon = atoi(p) - 1; | ||
| 1253 | *(p + 2) = c; | ||
| 1254 | c = *p; | ||
| 1255 | *p = '\0'; | ||
| 1256 | p -= 4; | ||
| 1257 | k_tm->tm_year = atoi(p) - 1900; | ||
| 1258 | *(p + 4) = c; | ||
| 1223 | 1259 | ||
| 1224 | return k_tm; | 1260 | return k_tm; |
| 1225 | } | 1261 | } |
| 1226 | 1262 | ||
| 1227 | 1263 | ||
| 1228 | /* Helper function for kssl_validate_times(). | 1264 | /* Helper function for kssl_validate_times(). |
| @@ -1230,19 +1266,22 @@ static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) | |||
| 1230 | ** So we try to sneek the clockskew out through the replay cache. | 1266 | ** So we try to sneek the clockskew out through the replay cache. |
| 1231 | ** If that fails just return a likely default (300 seconds). | 1267 | ** If that fails just return a likely default (300 seconds). |
| 1232 | */ | 1268 | */ |
| 1233 | static krb5_deltat get_rc_clockskew(krb5_context context) | 1269 | static krb5_deltat |
| 1234 | { | 1270 | get_rc_clockskew(krb5_context context) |
| 1271 | { | ||
| 1235 | krb5_rcache rc; | 1272 | krb5_rcache rc; |
| 1236 | krb5_deltat clockskew; | 1273 | krb5_deltat clockskew; |
| 1237 | 1274 | ||
| 1238 | if (krb5_rc_default(context, &rc)) return KSSL_CLOCKSKEW; | 1275 | if (krb5_rc_default(context, &rc)) |
| 1239 | if (krb5_rc_initialize(context, rc, 0)) return KSSL_CLOCKSKEW; | 1276 | return KSSL_CLOCKSKEW; |
| 1277 | if (krb5_rc_initialize(context, rc, 0)) | ||
| 1278 | return KSSL_CLOCKSKEW; | ||
| 1240 | if (krb5_rc_get_lifespan(context, rc, &clockskew)) { | 1279 | if (krb5_rc_get_lifespan(context, rc, &clockskew)) { |
| 1241 | clockskew = KSSL_CLOCKSKEW; | 1280 | clockskew = KSSL_CLOCKSKEW; |
| 1242 | } | ||
| 1243 | (void) krb5_rc_destroy(context, rc); | ||
| 1244 | return clockskew; | ||
| 1245 | } | 1281 | } |
| 1282 | (void)krb5_rc_destroy(context, rc); | ||
| 1283 | return clockskew; | ||
| 1284 | } | ||
| 1246 | 1285 | ||
| 1247 | 1286 | ||
| 1248 | /* kssl_validate_times() combines (and more importantly exposes) | 1287 | /* kssl_validate_times() combines (and more importantly exposes) |
| @@ -1255,34 +1294,41 @@ static krb5_deltat get_rc_clockskew(krb5_context context) | |||
| 1255 | ** See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c | 1294 | ** See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c |
| 1256 | ** 20010420 VRS | 1295 | ** 20010420 VRS |
| 1257 | */ | 1296 | */ |
| 1258 | krb5_error_code kssl_validate_times( krb5_timestamp atime, | 1297 | krb5_error_code |
| 1259 | krb5_ticket_times *ttimes) | 1298 | kssl_validate_times(krb5_timestamp atime, krb5_ticket_times *ttimes) |
| 1260 | { | 1299 | { |
| 1261 | krb5_deltat skew; | 1300 | krb5_deltat skew; |
| 1262 | krb5_timestamp start, now; | 1301 | krb5_timestamp start, now; |
| 1263 | krb5_error_code rc; | 1302 | krb5_error_code rc; |
| 1264 | krb5_context context; | 1303 | krb5_context context; |
| 1265 | 1304 | ||
| 1266 | if ((rc = krb5_init_context(&context))) return SSL_R_KRB5_S_BAD_TICKET; | 1305 | if ((rc = krb5_init_context(&context))) |
| 1267 | skew = get_rc_clockskew(context); | 1306 | return SSL_R_KRB5_S_BAD_TICKET; |
| 1268 | if ((rc = krb5_timeofday(context,&now))) return SSL_R_KRB5_S_BAD_TICKET; | 1307 | skew = get_rc_clockskew(context); |
| 1308 | |||
| 1309 | if ((rc = krb5_timeofday(context, &now))) | ||
| 1310 | return SSL_R_KRB5_S_BAD_TICKET; | ||
| 1269 | krb5_free_context(context); | 1311 | krb5_free_context(context); |
| 1270 | 1312 | ||
| 1271 | if (atime && labs(atime - now) >= skew) return SSL_R_KRB5_S_TKT_SKEW; | 1313 | if (atime && labs(atime - now) >= skew) |
| 1314 | return SSL_R_KRB5_S_TKT_SKEW; | ||
| 1272 | 1315 | ||
| 1273 | if (! ttimes) return 0; | 1316 | if (!ttimes) |
| 1317 | return 0; | ||
| 1274 | 1318 | ||
| 1275 | start = (ttimes->starttime != 0)? ttimes->starttime: ttimes->authtime; | 1319 | start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; |
| 1276 | if (start - now > skew) return SSL_R_KRB5_S_TKT_NYV; | 1320 | if (start - now > skew) |
| 1277 | if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED; | 1321 | return SSL_R_KRB5_S_TKT_NYV; |
| 1322 | if ((now - ttimes->endtime) > skew) | ||
| 1323 | return SSL_R_KRB5_S_TKT_EXPIRED; | ||
| 1278 | 1324 | ||
| 1279 | #ifdef KSSL_DEBUG | 1325 | #ifdef KSSL_DEBUG |
| 1280 | printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", | 1326 | printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", |
| 1281 | start, atime, now, skew, ttimes->endtime); | 1327 | start, atime, now, skew, ttimes->endtime); |
| 1282 | #endif /* KSSL_DEBUG */ | 1328 | #endif /* KSSL_DEBUG */ |
| 1283 | 1329 | ||
| 1284 | return 0; | 1330 | return 0; |
| 1285 | } | 1331 | } |
| 1286 | 1332 | ||
| 1287 | 1333 | ||
| 1288 | /* Decode and decrypt given DER-encoded authenticator, then pass | 1334 | /* Decode and decrypt given DER-encoded authenticator, then pass |
| @@ -1292,12 +1338,13 @@ krb5_error_code kssl_validate_times( krb5_timestamp atime, | |||
| 1292 | ** Note that kssl_check_authent() makes use of the KRB5 session key; | 1338 | ** Note that kssl_check_authent() makes use of the KRB5 session key; |
| 1293 | ** you must call kssl_sget_tkt() to get the key before calling this routine. | 1339 | ** you must call kssl_sget_tkt() to get the key before calling this routine. |
| 1294 | */ | 1340 | */ |
| 1295 | krb5_error_code kssl_check_authent( | 1341 | krb5_error_code |
| 1296 | /* IN */ KSSL_CTX *kssl_ctx, | 1342 | kssl_check_authent( |
| 1297 | /* IN */ krb5_data *authentp, | 1343 | /* IN */ KSSL_CTX *kssl_ctx, |
| 1298 | /* OUT */ krb5_timestamp *atimep, | 1344 | /* IN */ krb5_data *authentp, |
| 1299 | /* OUT */ KSSL_ERR *kssl_err ) | 1345 | /* OUT */ krb5_timestamp *atimep, |
| 1300 | { | 1346 | /* OUT */ KSSL_ERR *kssl_err ) |
| 1347 | { | ||
| 1301 | krb5_error_code krb5rc = 0; | 1348 | krb5_error_code krb5rc = 0; |
| 1302 | KRB5_ENCDATA *dec_authent = NULL; | 1349 | KRB5_ENCDATA *dec_authent = NULL; |
| 1303 | KRB5_AUTHENTBODY *auth = NULL; | 1350 | KRB5_AUTHENTBODY *auth = NULL; |
| @@ -1323,114 +1370,112 @@ krb5_error_code kssl_check_authent( | |||
| 1323 | #endif | 1370 | #endif |
| 1324 | #endif /* KRB5CHECKAUTH */ | 1371 | #endif /* KRB5CHECKAUTH */ |
| 1325 | 1372 | ||
| 1326 | if (authentp == NULL || authentp->length == 0) return 0; | 1373 | if (authentp == NULL || authentp->length == 0) |
| 1374 | return 0; | ||
| 1327 | 1375 | ||
| 1328 | #ifdef KSSL_DEBUG | 1376 | #ifdef KSSL_DEBUG |
| 1329 | { | 1377 | { |
| 1330 | unsigned int ui; | 1378 | unsigned int ui; |
| 1331 | printf("kssl_check_authent: authenticator[%d]:\n",authentp->length); | 1379 | printf("kssl_check_authent: authenticator[%d]:\n", authentp->length); |
| 1332 | p = authentp->data; | 1380 | p = authentp->data; |
| 1333 | for (ui=0; ui < authentp->length; ui++) printf("%02x ",p[ui]); | 1381 | |
| 1334 | printf("\n"); | 1382 | for (ui = 0; ui < authentp->length; ui++) printf("%02x ", p[ui]); |
| 1335 | } | 1383 | printf("\n"); |
| 1384 | } | ||
| 1336 | #endif /* KSSL_DEBUG */ | 1385 | #endif /* KSSL_DEBUG */ |
| 1337 | 1386 | ||
| 1338 | unencbufsize = 2 * authentp->length; | 1387 | unencbufsize = 2 * authentp->length; |
| 1339 | if ((unenc_authent = calloc(1, unencbufsize)) == NULL) | 1388 | if ((unenc_authent = calloc(1, unencbufsize)) == NULL) { |
| 1340 | { | ||
| 1341 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1389 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1342 | "Unable to allocate authenticator buffer.\n"); | 1390 | "Unable to allocate authenticator buffer.\n"); |
| 1343 | krb5rc = KRB5KRB_ERR_GENERIC; | 1391 | krb5rc = KRB5KRB_ERR_GENERIC; |
| 1344 | goto err; | 1392 | goto err; |
| 1345 | } | 1393 | } |
| 1346 | 1394 | ||
| 1347 | p = (unsigned char *)authentp->data; | 1395 | p = (unsigned char *)authentp->data; |
| 1348 | if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, | 1396 | if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, |
| 1349 | (long) authentp->length)) == NULL) | 1397 | (long)authentp->length)) == NULL) { |
| 1350 | { | ||
| 1351 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1398 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1352 | "Error decoding authenticator.\n"); | 1399 | "Error decoding authenticator.\n"); |
| 1353 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 1400 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
| 1354 | goto err; | 1401 | goto err; |
| 1355 | } | 1402 | } |
| 1356 | 1403 | ||
| 1357 | enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ | 1404 | enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ |
| 1358 | #if !defined(KRB5_MIT_OLD11) | 1405 | #if !defined(KRB5_MIT_OLD11) |
| 1359 | switch ( enctype ) { | 1406 | switch (enctype ) { |
| 1360 | case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ | 1407 | case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ |
| 1361 | case ENCTYPE_DES3_CBC_SHA: | 1408 | case ENCTYPE_DES3_CBC_SHA: |
| 1362 | case ENCTYPE_DES3_CBC_RAW: | 1409 | case ENCTYPE_DES3_CBC_RAW: |
| 1363 | krb5rc = 0; /* Skip, can't handle derived keys */ | 1410 | krb5rc = 0; |
| 1364 | goto err; | 1411 | /* Skip, can't handle derived keys */ |
| 1365 | } | 1412 | goto err; |
| 1413 | } | ||
| 1366 | #endif | 1414 | #endif |
| 1367 | enc = kssl_map_enc(enctype); | 1415 | enc = kssl_map_enc(enctype); |
| 1368 | memset(iv, 0, sizeof iv); /* per RFC 1510 */ | 1416 | memset(iv, 0, sizeof iv); |
| 1417 | /* per RFC 1510 */ | ||
| 1369 | 1418 | ||
| 1370 | if (enc == NULL) | 1419 | if (enc == NULL) { |
| 1371 | { | ||
| 1372 | /* Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. | 1420 | /* Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. |
| 1373 | ** This enctype indicates the authenticator was encrypted | 1421 | ** This enctype indicates the authenticator was encrypted |
| 1374 | ** using key-usage derived keys which openssl cannot decrypt. | 1422 | ** using key-usage derived keys which openssl cannot decrypt. |
| 1375 | */ | 1423 | */ |
| 1376 | goto err; | 1424 | goto err; |
| 1377 | } | 1425 | } |
| 1378 | 1426 | ||
| 1379 | if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0)) | 1427 | if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) { |
| 1380 | { | 1428 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1381 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1429 | "EVP_CipherInit error decrypting authenticator.\n"); |
| 1382 | "EVP_CipherInit error decrypting authenticator.\n"); | 1430 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
| 1383 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 1431 | goto err; |
| 1384 | goto err; | 1432 | } |
| 1385 | } | 1433 | outl = dec_authent->cipher->length; |
| 1386 | outl = dec_authent->cipher->length; | 1434 | if (!EVP_Cipher(&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) { |
| 1387 | if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl)) | 1435 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1388 | { | 1436 | "EVP_Cipher error decrypting authenticator.\n"); |
| 1389 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1437 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
| 1390 | "EVP_Cipher error decrypting authenticator.\n"); | 1438 | goto err; |
| 1391 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 1439 | } |
| 1392 | goto err; | 1440 | EVP_CIPHER_CTX_cleanup(&ciph_ctx); |
| 1393 | } | ||
| 1394 | EVP_CIPHER_CTX_cleanup(&ciph_ctx); | ||
| 1395 | 1441 | ||
| 1396 | #ifdef KSSL_DEBUG | 1442 | #ifdef KSSL_DEBUG |
| 1397 | { | 1443 | { |
| 1398 | int padl; | 1444 | int padl; |
| 1399 | printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); | 1445 | printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); |
| 1400 | for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); | 1446 | for (padl = 0; padl < outl; padl++) printf("%02x ", unenc_authent[padl]); |
| 1401 | printf("\n"); | 1447 | printf("\n"); |
| 1402 | } | 1448 | } |
| 1403 | #endif /* KSSL_DEBUG */ | 1449 | #endif /* KSSL_DEBUG */ |
| 1404 | 1450 | ||
| 1405 | if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) | 1451 | if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) { |
| 1406 | { | ||
| 1407 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1452 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1408 | "confounded by authenticator.\n"); | 1453 | "confounded by authenticator.\n"); |
| 1409 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 1454 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
| 1410 | goto err; | 1455 | goto err; |
| 1411 | } | 1456 | } |
| 1412 | outl -= p - unenc_authent; | 1457 | outl -= p - unenc_authent; |
| 1413 | 1458 | ||
| 1414 | if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p, | 1459 | if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p, |
| 1415 | (long) outl))==NULL) | 1460 | (long)outl)) == NULL) { |
| 1416 | { | ||
| 1417 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 1461 | kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
| 1418 | "Error decoding authenticator body.\n"); | 1462 | "Error decoding authenticator body.\n"); |
| 1419 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 1463 | krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
| 1420 | goto err; | 1464 | goto err; |
| 1421 | } | 1465 | } |
| 1422 | 1466 | ||
| 1423 | memset(&tm_time,0,sizeof(struct tm)); | 1467 | memset(&tm_time, 0, sizeof(struct tm)); |
| 1424 | if (k_gmtime(auth->ctime, &tm_time) && | 1468 | if (k_gmtime(auth->ctime, &tm_time) && |
| 1425 | ((tr = mktime(&tm_time)) != (time_t)(-1))) | 1469 | ((tr = mktime(&tm_time)) != (time_t)(-1))) { |
| 1426 | { | 1470 | now = time(&now); |
| 1427 | now = time(&now); | 1471 | tm_l = localtime(&now); |
| 1428 | tm_l = localtime(&now); tl = mktime(tm_l); | 1472 | tl = mktime(tm_l); |
| 1429 | tm_g = gmtime(&now); tg = mktime(tm_g); | 1473 | tm_g = gmtime(&now); |
| 1430 | tz_offset = tg - tl; | 1474 | tg = mktime(tm_g); |
| 1475 | tz_offset = tg - tl; | ||
| 1431 | 1476 | ||
| 1432 | *atimep = (krb5_timestamp)(tr - tz_offset); | 1477 | *atimep = (krb5_timestamp)(tr - tz_offset); |
| 1433 | } | 1478 | } |
| 1434 | 1479 | ||
| 1435 | #ifdef KSSL_DEBUG | 1480 | #ifdef KSSL_DEBUG |
| 1436 | printf("kssl_check_authent: returns %d for client time ", *atimep); | 1481 | printf("kssl_check_authent: returns %d for client time ", *atimep); |
| @@ -1439,13 +1484,16 @@ krb5_error_code kssl_check_authent( | |||
| 1439 | else printf("NULL\n"); | 1484 | else printf("NULL\n"); |
| 1440 | #endif /* KSSL_DEBUG */ | 1485 | #endif /* KSSL_DEBUG */ |
| 1441 | 1486 | ||
| 1442 | err: | 1487 | err: |
| 1443 | if (auth) KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); | 1488 | if (auth) |
| 1444 | if (dec_authent) KRB5_ENCDATA_free(dec_authent); | 1489 | KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); |
| 1445 | if (unenc_authent) free(unenc_authent); | 1490 | if (dec_authent) |
| 1491 | KRB5_ENCDATA_free(dec_authent); | ||
| 1492 | if (unenc_authent) | ||
| 1493 | free(unenc_authent); | ||
| 1446 | EVP_CIPHER_CTX_cleanup(&ciph_ctx); | 1494 | EVP_CIPHER_CTX_cleanup(&ciph_ctx); |
| 1447 | return krb5rc; | 1495 | return krb5rc; |
| 1448 | } | 1496 | } |
| 1449 | 1497 | ||
| 1450 | 1498 | ||
| 1451 | /* Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), | 1499 | /* Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), |
| @@ -1453,33 +1501,38 @@ krb5_error_code kssl_check_authent( | |||
| 1453 | ** Returns krb5_error_code == ENOMEM on alloc error, otherwise | 1501 | ** Returns krb5_error_code == ENOMEM on alloc error, otherwise |
| 1454 | ** passes back newly constructed principal, which should be freed by caller. | 1502 | ** passes back newly constructed principal, which should be freed by caller. |
| 1455 | */ | 1503 | */ |
| 1456 | krb5_error_code kssl_build_principal_2( | 1504 | krb5_error_code |
| 1457 | /* UPDATE */ krb5_context context, | 1505 | kssl_build_principal_2( |
| 1458 | /* OUT */ krb5_principal *princ, | 1506 | /* UPDATE */ krb5_context context, |
| 1459 | /* IN */ int rlen, const char *realm, | 1507 | /* OUT */ krb5_principal *princ, |
| 1460 | /* IN */ int slen, const char *svc, | 1508 | /* IN */ int rlen, const char *realm, |
| 1461 | /* IN */ int hlen, const char *host) | 1509 | /* IN */ int slen, const char *svc, |
| 1462 | { | 1510 | /* IN */ int hlen, const char *host) |
| 1511 | { | ||
| 1463 | krb5_data *p_data = NULL; | 1512 | krb5_data *p_data = NULL; |
| 1464 | krb5_principal new_p = NULL; | 1513 | krb5_principal new_p = NULL; |
| 1465 | char *new_r = NULL; | 1514 | char *new_r = NULL; |
| 1466 | 1515 | ||
| 1467 | if ((p_data = (krb5_data *) calloc(2, sizeof(krb5_data))) == NULL || | 1516 | if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL || |
| 1468 | (new_p = (krb5_principal) calloc(1, sizeof(krb5_principal_data))) | 1517 | (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data))) |
| 1469 | == NULL) goto err; | 1518 | == NULL) |
| 1519 | goto err; | ||
| 1470 | new_p->length = 2; | 1520 | new_p->length = 2; |
| 1471 | new_p->data = p_data; | 1521 | new_p->data = p_data; |
| 1472 | 1522 | ||
| 1473 | if ((new_r = calloc(1, rlen + 1)) == NULL) goto err; | 1523 | if ((new_r = calloc(1, rlen + 1)) == NULL) |
| 1524 | goto err; | ||
| 1474 | memcpy(new_r, realm, rlen); | 1525 | memcpy(new_r, realm, rlen); |
| 1475 | krb5_princ_set_realm_length(context, new_p, rlen); | 1526 | krb5_princ_set_realm_length(context, new_p, rlen); |
| 1476 | krb5_princ_set_realm_data(context, new_p, new_r); | 1527 | krb5_princ_set_realm_data(context, new_p, new_r); |
| 1477 | 1528 | ||
| 1478 | if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) goto err; | 1529 | if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) |
| 1530 | goto err; | ||
| 1479 | memcpy(new_p->data[0].data, svc, slen); | 1531 | memcpy(new_p->data[0].data, svc, slen); |
| 1480 | new_p->data[0].length = slen; | 1532 | new_p->data[0].length = slen; |
| 1481 | 1533 | ||
| 1482 | if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) goto err; | 1534 | if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) |
| 1535 | goto err; | ||
| 1483 | memcpy(new_p->data[1].data, host, hlen); | 1536 | memcpy(new_p->data[1].data, host, hlen); |
| 1484 | new_p->data[1].length = hlen; | 1537 | new_p->data[1].length = hlen; |
| 1485 | 1538 | ||
| @@ -1487,32 +1540,38 @@ krb5_error_code kssl_build_principal_2( | |||
| 1487 | *princ = new_p; | 1540 | *princ = new_p; |
| 1488 | return 0; | 1541 | return 0; |
| 1489 | 1542 | ||
| 1490 | err: | 1543 | err: |
| 1491 | if (new_p && new_p[0].data) free(new_p[0].data); | 1544 | if (new_p && new_p[0].data) |
| 1492 | if (new_p && new_p[1].data) free(new_p[1].data); | 1545 | free(new_p[0].data); |
| 1493 | if (new_p) free(new_p); | 1546 | if (new_p && new_p[1].data) |
| 1494 | if (new_r) free(new_r); | 1547 | free(new_p[1].data); |
| 1548 | if (new_p) | ||
| 1549 | free(new_p); | ||
| 1550 | if (new_r) | ||
| 1551 | free(new_r); | ||
| 1495 | return ENOMEM; | 1552 | return ENOMEM; |
| 1496 | } | 1553 | } |
| 1497 | 1554 | ||
| 1498 | void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) | 1555 | void |
| 1499 | { | 1556 | SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) |
| 1557 | { | ||
| 1500 | s->kssl_ctx = kctx; | 1558 | s->kssl_ctx = kctx; |
| 1501 | } | 1559 | } |
| 1502 | 1560 | ||
| 1503 | KSSL_CTX * SSL_get0_kssl_ctx(SSL *s) | 1561 | KSSL_CTX * |
| 1504 | { | 1562 | SSL_get0_kssl_ctx(SSL *s) |
| 1563 | { | ||
| 1505 | return s->kssl_ctx; | 1564 | return s->kssl_ctx; |
| 1506 | } | 1565 | } |
| 1507 | 1566 | ||
| 1508 | char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) | 1567 | char * |
| 1509 | { | 1568 | kssl_ctx_get0_client_princ(KSSL_CTX *kctx) |
| 1569 | { | ||
| 1510 | if (kctx) | 1570 | if (kctx) |
| 1511 | return kctx->client_princ; | 1571 | return kctx->client_princ; |
| 1512 | return NULL; | 1572 | return NULL; |
| 1513 | } | 1573 | } |
| 1514 | 1574 | ||
| 1515 | #else /* !OPENSSL_NO_KRB5 */ | 1575 | #else /* !OPENSSL_NO_KRB5 */ |
| 1516 | 1576 | ||
| 1517 | #endif /* !OPENSSL_NO_KRB5 */ | 1577 | #endif /* !OPENSSL_NO_KRB5 */ |
| 1518 | |||
