/ plugins / KDCProxy / client.c
client.c
  1  
  2  #include <Heimdal/krb5.h>
  3  #include <Heimdal/send_to_kdc_plugin.h>
  4  
  5  static krb5_error_code
  6  init(krb5_context context, void **ctx)
  7  {
  8      return 0;
  9  }
 10  
 11  static void
 12  fini(void *ctx)
 13  {
 14      return 0;
 15  }
 16  
 17  static krb5_error_code
 18  requestToURL(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  
 63  typedef krb5_error_code
 64  send_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  
122  krb5plugin_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  };