1/* 2 * Copyright (c) 2011 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2011 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#import <stdio.h> 37 38#import <Foundation/Foundation.h> 39#import <Heimdal/krb5.h> 40#import <GSS/gssapi.h> 41#import <GSS/gssapi_plugin.h> 42 43#include <syslog.h> 44#include <assert.h> 45 46/** 47 * Icky code that prints the target name and replace the cred with another cred that hard coded in the module 48 */ 49 50#define GSSC_MAGIC 0x47111147 51 52struct gsssel_ctx { 53 int magic; 54}; 55 56static const char selectuser[] = "lha@KTH.SE"; 57static const char *replacenames[] = { 58 "host@svn.h5l.org", 59 NULL 60}; 61 62static gss_cred_id_t 63isc_replace_cred(gss_name_t target, gss_OID mech, gss_cred_id_t original_cred, OM_uint32 flags) 64{ 65 OM_uint32 maj_stat, min_stat; 66 gss_buffer_desc buffer; 67 gss_name_t name; 68 gss_cred_id_t newcred; 69 bool exchange = false; 70 size_t n; 71 72 /* 73 * Using gss_display_name() is wrong, however it the best we can 74 * do right now. 75 * 76 * We should use gss_import_name() and then compare the name with 77 * gss_compare_name(), the only issue with that is that comparing 78 * names fragile and do not work as expected wrt to case of 79 * string, and in case or Kerberos, hostbased service gets 80 * affected by realm. 81 */ 82 83 maj_stat = gss_display_name(&min_stat, target, &buffer, NULL); 84 if (maj_stat == GSS_S_COMPLETE) { 85 syslog(LOG_ERR, "ISC-replace-cred target name: %.*s", (int)buffer.length, (char *)buffer.value); 86 for (n = 0; replacenames[n]; n++) { 87 if (memmem(buffer.value, buffer.length, replacenames[n], strlen(replacenames[n])) != NULL) 88 exchange = true; 89 } 90 gss_release_buffer(&min_stat, &buffer); 91 } 92 if (!exchange) { 93 syslog(LOG_ERR, "ISC-replace-cred not replacing"); 94 return NULL; 95 } 96 97 buffer.value = (char *)(uintptr_t)selectuser; 98 buffer.length = strlen(selectuser); 99 maj_stat = gss_import_name(&min_stat, &buffer, GSS_C_NT_USER_NAME, &name); 100 if (maj_stat != GSS_S_COMPLETE) 101 return NULL; 102 103 maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, 104 &newcred, NULL, NULL); 105 gss_release_name(&min_stat, &name); 106 if (maj_stat != GSS_S_COMPLETE) 107 return NULL; 108 109 syslog(LOG_ERR, "ISC-replace-cred replacing cred to: %s", selectuser); 110 111 return newcred; 112} 113 114static krb5_error_code 115gsssel_init(krb5_context context, void **ptr) 116{ 117 struct gsssel_ctx *ctx = calloc(1, sizeof(*ctx)); 118 119 if (ctx == NULL) 120 return ENOMEM; 121 122 ctx->magic = GSSC_MAGIC; 123 124 *ptr = ctx; 125 return 0; 126} 127 128static void 129gsssel_fini(void *ptr) 130{ 131 struct gsssel_ctx *ctx = ptr; 132 133 assert(ctx->magic == GSSC_MAGIC); 134 135 free(ctx); 136} 137 138 139gssapi_plugin_ftable gssapi_plugin = { 140 GSSAPI_PLUGIN_VERSION_1, 141 gsssel_init, 142 gsssel_fini, 143 "gssapi credential selector", 144 0, 145 isc_replace_cred 146}; 147