1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#import <KerberosHelper/NetworkAuthenticationHelper.h> 25#import <KerberosHelper/NetworkAuthenticationHelperGSS.h> 26#import <KerberosHelper/KerberosHelper.h> 27#import <Foundation/Foundation.h> 28#import <GSS/gssapi.h> 29 30#include <unistd.h> 31#include <err.h> 32 33 34/* XXX application protocol code here 35 sample code only using GSS-API directly 36 */ 37 38static void 39tryGSSAPI(gss_OID mech, gss_cred_id_t cred, gss_name_t servername, CFTypeRef name) 40{ 41 OM_uint32 maj, junk; 42 43 gss_buffer_desc buffer; 44 gss_ctx_id_t ctx = NULL; 45 46 maj = gss_init_sec_context(&junk, cred, &ctx, servername, mech, 0, GSS_C_INDEFINITE, NULL, NULL, 47 NULL, &buffer, NULL, NULL); 48 if (maj) 49 NSLog(@"ISC failed with %d/%d for %@", maj, junk, name); 50 else { 51 printf("ISC success, got first token\n"); 52 gss_delete_sec_context(&junk, &ctx, NULL); 53 gss_release_buffer(&junk, &buffer); 54 } 55 gss_release_cred(&junk, &cred); 56 gss_release_name(&junk, &servername); 57} 58 59 60static int 61doit(CFStringRef username, CFStringRef password, 62 CFStringRef hostname, CFStringRef protocol) 63{ 64 CFMutableDictionaryRef info = NULL; 65 CFDictionaryRef krbtoken = NULL; 66 67 if (protocol == NULL) 68 protocol = CFSTR("host"); 69 70 info = CFDictionaryCreateMutable(NULL, 0, 71 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 72 73 74 krbtoken = KRBCreateNegTokenLegacyKerberos(NULL); 75 CFDictionaryAddValue(info, kNAHNegTokenInit, krbtoken); 76 CFRelease(krbtoken); 77 78 if (username) 79 CFDictionaryAddValue(info, kNAHUserName, username); 80 81 if (password) 82 CFDictionaryAddValue(info, kNAHPassword, password); 83 84 85 NAHRef nah = NAHCreate(NULL, hostname, protocol, info); 86 if (nah == NULL) 87 errx(1, "NAHCreate"); 88 89 CFArrayRef selections = NAHGetSelections(nah); 90 if (selections == NULL) 91 errx(1, "NAHGetSelections"); 92 93 CFIndex idx, count = CFArrayGetCount(selections); 94 95 printf("num selection: %ld\n", count); 96 97 for (idx = 0; idx < count; idx++) { 98 NAHSelectionRef sel = 99 (NAHSelectionRef)CFArrayGetValueAtIndex(selections, idx); 100 CFErrorRef error; 101 102 CFStringRef clientPrincipal = NAHSelectionGetInfoForKey(sel, kNAHClientPrincipal); 103 CFStringRef serverPrincipal = NAHSelectionGetInfoForKey(sel, kNAHServerPrincipal); 104 105 NSLog(@"trying to get credential: client: %@ server: %@", 106 (NSString *)clientPrincipal, (NSString *)serverPrincipal); 107 108 if (!NAHSelectionAcquireCredential(sel, NULL, &error)) { 109 NSLog(@"failed to acquire cred: %@", error); 110 if (error) 111 CFRelease(error); 112 continue; 113 } 114 115 { 116 gss_name_t servername = NAHSelectionGetGSSAcceptorName(sel, NULL); 117 if (servername == NULL) 118 errx(1, "failed to get server name"); 119 120 gss_cred_id_t cred = NAHSelectionGetGSSCredential(sel, NULL); 121 if (cred == NULL) 122 errx(1, "failed to get client credential"); 123 124 gss_OID mech = NAHSelectionGetGSSMech(sel); 125 if (mech == NULL) 126 errx(1, "failed to get mech oid"); 127 128 129 tryGSSAPI(mech, cred, servername, sel); 130 } 131 132 { 133 CFDictionaryRef authInfo = NAHSelectionCopyAuthInfo(sel); 134 135 gss_cred_id_t cred = NAHAuthenticationInfoCopyClientCredential(authInfo, NULL); 136 gss_name_t servername = NAHAuthenticationInfoCopyServerName(authInfo, NULL); 137 gss_OID mech = NAHAuthenticationInfoGetGSSMechanism(authInfo, NULL); 138 139 tryGSSAPI(mech, cred, servername, @"mech"); 140 } 141 142 } 143 144 145 if (selections) 146 CFRelease(selections); 147 if (nah) 148 CFRelease(nah); 149 150 return 0; 151} 152 153static void 154usage(int exit_code) 155{ 156 printf("%s [-u user] [-p password] [-s service] hostname1...\n", getprogname()); 157 exit(exit_code); 158} 159 160int 161main(int argc, char **argv) 162{ 163 CFStringRef username = NULL, password = NULL; 164 CFStringRef hostname = NULL, service = NULL; 165 int ch, i; 166 167 while ((ch = getopt(argc, argv, "u:p:s:")) != -1) { 168 switch (ch) { 169 case 'u': 170 username = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 171 break; 172 case 'p': 173 password = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 174 break; 175 case 's': 176 service = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 177 break; 178 case '?': 179 usage(0); 180 break; 181 default: 182 usage(1); 183 break; 184 } 185 } 186 argc -= optind; 187 argv += optind; 188 189 if (argc < 0) 190 usage(1); 191 192 for (i = 0; i < argc; i++) { 193 hostname = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8); 194 195 doit(username, password, hostname, service); 196 197 CFRelease(hostname); 198 } 199 200 return 0; 201} 202