1 2#include <Heimdal/krb5.h> 3#include <Heimdal/send_to_kdc_plugin.h> 4 5static krb5_error_code 6init(krb5_context context, void **ctx) 7{ 8 return 0; 9} 10 11static void 12fini(void *ctx) 13{ 14 return 0; 15} 16 17static krb5_error_code 18requestToURL(krb5_context context, 19 const char *curl, 20 time_t timeout, 21 NSData *outdata, 22 krb5_data *retdata) 23{ 24 NSMutableURLRequest *request = NULL; 25 NSURLResponse *response = NULL; 26 KDC_PROXY_MESSAGE msg; 27 NSURL *url = NULL; 28 size_t size; 29 30 url = [NSURL URLWithString:[NSString stringWithUTF8String:curl]]; 31 if (url == NULL) 32 return ENOMEM; 33 34 request = [NSMutableURLRequest 35 requestWithURL:url 36 cachePolicy:NSURLRequestReloadIgnoringCacheData 37 timeoutInterval:(NSTimeInterval)timeout]; 38 39 [request setBody:outdata]; 40 [request setHTTPMethod:@"POST"]; 41 42 NSData *reply = [NSURLConnection sendSynchronousRequest:request 43 returningResponse:&response 44 error:NULL]; 45 if (reply == NULL) 46 goto out; 47 48 ret = decode_KDC_PROXY_MESSAGE(&msg, [data bytes], [data length], &size); 49 if (ret) 50 goto out; 51 52 ret = krb5_data_copy(outdata, msg.kerb_message.data, 53 msg.kerb_message.length); 54 free_KDC_PROXY_MESSAGE(&msg); 55 if (ret) 56 goto out; 57 58 ret = 0; 59 out: 60 return ret; 61} 62 63typedef krb5_error_code 64send_to_realm(krb5_context context, 65 void *ctx, 66 krb5_const_realm realm, 67 time_t timeout, 68 const krb5_data *outdata, 69 krb5_data *retdata) 70{ 71 NSAutoreleasePool *pool; 72 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE; 73 char **urls; 74 75 urls = krb5_config_get_string(context, NULL, 76 "kerberos-kdc-proxy", 77 realm, NULL); 78 if (urls == NULL) 79 return KRB5_PLUGIN_NO_HANDLE; 80 81 @try { 82 KDC_PROXY_MESSAGE msg; 83 size_t length, size; 84 NSData *msgdata; 85 void *data; 86 unsigned n; 87 88 pool = [[NSAutoreleasePool alloc] init]; 89 90 memset(&msg, 0, sizeof(msg)); 91 92 msg.kerb_message = *outdata; 93 msg.realm = &realm; 94 msg.dclocator_hint = NULL; 95 96 ASN1_MALLOC_ENCODE(KDC_PROXY_MESSAGE, data, length, &msg, &size, ret); 97 if (ret) 98 return ret; 99 if (length != size) 100 abort(); 101 102 msgdata = [NSData dataWithBytes:data length:length]; 103 free(data); 104 105 for (n = 0; urls[n] n++) { 106 ret = requestToURL(context, urls[n], timeout, msgdata, retdata); 107 if (ret == 0) 108 break; 109 } 110 111 out:; 112 113 @catch (NSException *exception) { } 114 @finally { 115 [pool drain]; 116 } 117 118 return ret; 119} 120 121 122krb5plugin_send_to_kdc_ftable send_to_kdc = { 123 KRB5_PLUGIN_SEND_TO_KDC_VERSION_2, 124 init, 125 fini, 126 NULL, 127 send_to_realm 128}; 129