LKDC

From Wikifications
Revision as of 23:05, 2 June 2008 by Dre (Talk | contribs) (typo)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The local KDC in Leopard is pretty rad. In the absence of any real documentation, this page exists as a jumble of observations and theories.

Positioning and Use in Leoaprd

The Local KDC (LKDC) is a Kerberos implementation that extends "single sign-on" capabilities into ad-hoc networks. The LKDC supports the AFP, CIFS, and VNC services included in Mac OS X and Mac OS X Server. At the surface, the LKDC looks pretty much just like a regular Kerberos setup... you can log into one of the above named services and get Kerberos tickets, use standard tools like klist to manage tickets, use kadmin to administer the KDC, etc, etc. Some examples:

{3} andre@donk [~] % sudo klist -k 
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
   3 vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
{10} andre@donk [~] % sudo kadmin.local -q listprincs
Authenticating as principal andre/admin@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B with password.
K/M@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
afpserver/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
andre@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
cifs/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
kadmin/admin@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
kadmin/changepw@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
kadmin/donk.local@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
kadmin/history@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
krbtgt/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
vnc/LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
{13} andre@donk [~] % sudo kadmin.local -q 'get_principal andre'
Authenticating as principal andre/admin@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B with password.
Principal: andre@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
Expiration date: [never]
Last password change: Sat May 10 21:43:57 PDT 2008
Password expiration date: [none]
Maximum ticket life: 0 days 10:00:00
Maximum renewable life: 7 days 00:00:00
Last modified: Sat May 10 21:43:57 PDT 2008 (root/admin@LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD)
Last successful authentication: [never]
Last failed authentication: [never]
Failed password attempts: 0
Number of keys: 4
Key: vno 1, Triple DES cbc mode with HMAC/sha1, no salt
Key: vno 1, ArcFour with HMAC/md5, no salt
Key: vno 1, DES cbc mode with CRC-32, no salt
Key: vno 1, DES cbc mode with CRC-32, Version 4
Attributes: REQUIRES_PRE_AUTH
Policy: [none]
{106} andre@donk [~] % klist
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: andre@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B

Valid Starting     Expires            Service Principal
05/13/08 00:35:00  05/13/08 10:34:58  krbtgt/LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B
	renew until 05/20/08 00:34:58
05/13/08 00:35:00  05/13/08 10:34:58  vnc/LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B
	renew until 05/20/08 00:34:58

Standard Deviation

The crux of the LKDC implementation is the use of a SHA1 hash in place of the server name portion of a kerberos service principal, effectively insulating Kerberos from dynamic network conditions. This significant re-definition of a kerberos principal is really cool, but also not standard. The Kerberos v5 spec (rfc 1510) assumes and requires that the server name portion of a kerberos principal be just that: a server name (or address). To wit:

7.2.1. Name of server principals

   The principal identifier for a server on a host will generally be
   composed of two parts: (1) the realm of the KDC with which the server
   is registered, and (2) a two-component name of type NT-SRV-HST if the
   host name is an Internet domain name or a multi-component name of
   type NT-SRV-XHST if the name of the host is of a form such as X.500
   that allows slash (/) separators.  The first component of the two- or
   multi-component name will identify the service and the latter
   components will identify the host.  Where the name of the host is not
   case sensitive (for example, with Internet domain names) the name of
   the host must be lower case.  For services such as telnet and the
   Berkeley R commands which run with system privileges, the first
   component will be the string "host" instead of a service specific
   identifier.

Also unlike most Kerberos deployments, the clients are not expected to maintain hard-coded references to other LKDCs, or any Kerberos client configuration at all for that matter (although it does continue to work if you have existing configuration).

This presents two primary challenges:

  • Advertising and discovering LKDC realm information in an ad-hoc, peer to peer context
  • Harnessing the authentication process to construct the special kerberos principal and then handing it off to Kerberos

Apple has overcome both of these challenges rather well, although the vast majority of the LKDC implementation should be considered 'private' - don't go building apps around this. The discovery portion of the LKDC implementation only barely extends into the Kerberos layer. How far does it extend? Consider the following:

{15} andre@donk [~] % klist
klist: No Kerberos 5 tickets in credentials cache
{16} andre@donk [~] % cat /Library/Preferences/edu.mit.Kerberos
cat: /Library/Preferences/edu.mit.Kerberos: No such file or directory
{17} andre@donk [~] % cat /etc/krb5.conf
cat: /etc/krb5.conf: No such file or directory
{18} andre@donk [~] % kinit andre@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B
Please enter the password for andre@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B: 
{19} andre@donk [~] % klist
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: andre@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B

Valid Starting     Expires            Service Principal
05/13/08 13:32:39  05/13/08 23:32:37  krbtgt/LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B@LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B

The take-home point here is that as long as you know the realm / principal name, it's business as usual. The "look up KDC for realm" and "look up realm for KDC" functionality is integrated into the system's kerberos frameworks (via the private KerberosHelper framework). It is important to note that all of the secure aspects of the authentication are performed in the standard Kerberos manner.

Advertising and Discovering

The mechanism used to advertise and discover LKDC information is multicast DNS, as it is very well suited to ad-hoc networks. In other more standard Kerberos deployments, it is not unusual to use (regular ol' unicast) DNS to discover Kerberos information in the absence of local configuration (see references at the bottom of the page), but with standard kerberos, the discovery is limited to realm name or KDC name. From the krb5.conf man page [libdefaults] section:

       dns_lookup_kdc
              Indicate whether DNS SRV records shoud be used to locate the KDCs and
              other  servers for a realm, if they are not listed in the information
              for the realm.  The default is to use these records.

       dns_lookup_realm
              Indicate whether DNS TXT records should be used to determine the Ker-
              beros realm of a host.  The default is not to use these records.

Each Mac OS X system advertises its own LKDC. At some point during or after startup, the LKDC realm name is read from Directory Services, e.g.

dscl . -read /Config/KerberosKDC RealName

The LKDC realm name is then advertised in the txt portion of a multicast DNS record called _kerberos in the .local name space. This record may be manually queried as follows:

dns-sd -Q "_kerberos.donk.local" txt

Replace "donk" with the bonjour name of a Leopard machine on your local network (can test on yourself if needed).

The result is a string of hex characters. This command does not terminate, so control-C to stop it. Now take the hex and run it through xxd -r -c 256.

xxd -r -c 256

<paste in the hex string, press return>

The result is the LKDC realm name, such as LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD

Harnessing Authentication

The notion of using a unique hash as the sever name portion of a service principal name is a new idea, so we cannot rely on standard methods for constructing the correct principal name based on the LKDC's realm name. Accordingly, the authentication process is brokered for supported service clients, in order to perform the LKDC realm name discovery and then construct a kerberos service principal name that is correct for the remote LKDC. Once the correct service principal name is obtained, it is handed off to Kerberos and works normally.

The client-side authentication broker (for supported services!) is called NetAuthAgent, and you'll see it running whenever you use vnc, afp, cifs. Think of this as a session manager, of sorts.

On the service configuration end, AppleFileServer and smbd have their service principal names written into their respective configuration files, while the vnc service does not (VNCPrivilegeProxy?).

Most of the advertisement, discovery, and management functions involving the LKDC are provided by a private framework called KerberosHelper, and a Kerberos framework plugin called LKDCLocate.

Using KerberosHelper

Some of the basic methods provided by KerberosHelper might be exercised as follows (big ups to landonf!)

krb.c contains the following:

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>


extern int LKDCGetLocalRealm(char **realm);
extern int LKDCDiscoverRealm(const char *host, char **realm);

// XXX arg1 - 1 seems to trigger the dump to syslog.
extern int LKDCDumpStatus(int32_t arg1);

void find_realm (const char *host) {
    char *realm;
    char *kdc;
    uint32_t arg3;

    /* Find the realm */
    if (LKDCDiscoverRealm(host, &realm) == 0) {
        printf("Disovered Realm (%s): %s\n", host, realm);
    }

    free(realm);
}

int main(int argc, char *argv[]) {
    char *local_realm;

    if (LKDCGetLocalRealm(&local_realm) == 0) {
        printf("Local Realm: %s\n", local_realm);
        free(local_realm);
    }

    /* Dump to syslog. XXX argument '1' is a guess */
    LKDCDumpStatus(1);

    if (argc < 2) {
        printf("Usage: %s <hostname>\n", argv[0]);
        return 1;
    }

    find_realm(argv[1]);

    return 0;
}

Compile with:

gcc krb.c -o krb -F/System/Library/PrivateFrameworks -framework KerberosHelper

Run it with one argument: a bonjour name of a leopard machine on your network. e.g.

{33} andre@donk [work/krb] % ./krb dude.local
Local Realm: LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
Disovered Realm (dude.local): LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B

Also, check your system.log. LKDCDumpStatus produces something like:

May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus: Cache root node = 0x1034f0
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus: node = 0x1034f0 {
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  realmName   = (0x1059d0) LKDC:SHA1.8B0FBACC08E3152A473A68D303E297A13CAA3AFD
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  serviceHost = (0x104d50) donk.local
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  servicePort = 88
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  TTL         = 7200
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                 }
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus: node = 0x106030 {
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  realmName   = (0x106460) LKDC:SHA1.C81B8D1A890D4D4DD079059A54594AA53B9A1A2B
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  serviceHost = (0x105fd0) dude.local
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  servicePort = 88
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                  TTL         = 7200
May 13 02:38:56 donk LKDCHelper[30484]:     LKDCDumpCacheStatus:                 }

Interesting Files

NetAuthAgent

This appears to be a service client helper that manages the authentication process at a high level on behalf of various clients included with Mac OS X. A string dump reveals the following chunk of kerberos service names:

vncserver
webdaveserver
ftpsserver
ftpserver
cifs
afpserver

vncserver, cifs, and afpserver are the only 3 services that are kerberized in the LKDC by default, though NetAuthAgent appears to support others as well. Looking at all strings matching 'kerb', we see:

{5} andre@donk [~] % strings /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent | grep -i kerb  
KerberosSession
BypassKerberos
kerberosClientPrincipalCredentials
kerberosRelease
kerberosClientPrincipal
kerberosKeychainRealm
kerberosPrincipalInfo
MountedByKerberos
SupportsKerberos
/System/Library/CoreServices/Kerberos.app
mInvalidKerberosUserName
checkForKerberosUserName:
isValidKerberosUserName:
useKerberos
kerberosServiceName
kerberosServicePrincipalHint
kerberosSession
kerberosServicePrincipal
kerberosAcquireTicket
Kerberos
AllowKerberosUI
KerberosInfo
kerberosUIOption
kerberosHostDisplayName
kerberosHostAddress
kerberosAlreadyHasTicket
{14} andre@donk [~] % otool -L /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent | cut -d ' ' -f1
/System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthAgent:
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
	/System/Library/Frameworks/Security.framework/Versions/A/Security
	/System/Library/PrivateFrameworks/URLMount.framework/Versions/A/URLMount
	/System/Library/Frameworks/SecurityInterface.framework/Versions/A/SecurityInterface
	/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
	/System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper
	/usr/lib/libgcc_s.1.dylib
	/usr/lib/libSystem.B.dylib
	/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
	/usr/lib/libobjc.A.dylib
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
	/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

NetAuthAgent.app also includes NetAuthSysAgent, which appears to be a variant of NetAuthAgent for handling system-level operations that do not require user interface. It contains lots of filesystem semantics, and also appears to deal with certificates.

{108} andre@donk [~] % otool -L /System/Library/CoreServices/NetAuthAgent.app/Contents/Resources/NetAuthSysAgent | cut -d ' ' -f1
/System/Library/CoreServices/NetAuthAgent.app/Contents/Resources/NetAuthSysAgent:
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
	/System/Library/PrivateFrameworks/URLMount.framework/Versions/A/URLMount
	/System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper
	/System/Library/Frameworks/SecurityInterface.framework/Versions/A/SecurityInterface
	/System/Library/Frameworks/Security.framework/Versions/A/Security
	/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
	/usr/lib/libgcc_s.1.dylib
	/usr/lib/libSystem.B.dylib
	/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
	/usr/lib/libobjc.A.dylib
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation

LKDCLocate

This (non-private?) Kerberos framework plugin looks like it's able to perform DNS queries to retrieve LKDC info. It also seems to interact with a mach service created by LKDCHelper called com.apple.KerberosHelper.LKDCHelper.

{14} andre@donk [~] % strings /System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate       
%s: 
LKDCLookup
Declined to handle address family %d
svc = %d, realm = %s, family= %d, socktype = %d
KDC|MasterKDC
LKDC:
getaddrinfo () == %d
0x%08p: family = %d, socktype = %d, protocol = %d
Running callback 0x%08p
Unexpected address family %d
Callback done 0x%08p, err=%d
inet_ntop failed: %s
addr = %s, port = %d
failed %d
LKDCGetHelperPort
com.apple.KerberosHelper.LKDCHelper
%s: cannot contact helper
LKDCHelperExit
Mach communication failed: %s
LKDCDumpStatus
LKDCSetLogLevel
LKDCGetLocalRealm
[[[ %s
Local realm = %s
]]] %s = %d (%s)
LKDCDiscoverRealm
No place to store discovered realm.
realm = %s
LKDCFindKDCForRealm
No place to store discovered KDC hostname.
KDC Hostname = %s:%u
Communication to the helper failed
Not authorized
Input parameter error
Serializing object failed
Unserializing object failed
Object passed is not a dictionary
A Local KDC was not found
Lookup of the KDC for the requested realm failed
    %s: 
Success
<unknown error>
[...]
{112} andre@donk [~] % otool -L /System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate          
/System/Library/KerberosPlugins/KerberosFrameworkPlugins/LKDCLocate.bundle/Contents/MacOS/LKDCLocate:
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)

KerberosHelper

This private framework appears to provide API that can be used on behalf of service clients (or their agents) to discover the LKDC information of a remote realm.

{6} root@donk [~] # strings /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/KerberosHelper 
LKDCGetHelperPort
com.apple.KerberosHelper.LKDCHelper
%s: cannot contact helper
LKDCHelperExit
Mach communication failed: %s
LKDCDumpStatus
LKDCSetLogLevel
LKDCGetLocalRealm
[[[ %s
Local realm = %s
]]] %s = %d (%s)
LKDCDiscoverRealm
No place to store discovered realm.
realm = %s
LKDCFindKDCForRealm
No place to store discovered KDC hostname.
KDC Hostname = %s:%u
LKDC:
    %s: krb5 call got %d (%s) on %s:%d
realm_for_host
(null)
[[[ %s: hostname=%s hintrealm=%s
/SourceCache/KerberosHelper/KerberosHelper-31/Source/KerberosHelper.c
    %s: krb5_get_host_realm success
    %s: krb5_get_host_realm returned unusable realm!
    %s: LKDCDiscoverRealm success
]]] %s: returning realm=%s
]]] %s: failed to determine realm
[[[ KRBCopyRealm () - required parameters okay
]]] KRBCopyRealm () = %d
[[[ KRBCopyKeychainLookupInfo () - required parameters okay
Username
KeychainAccountName
DisableSaveToKeychain
edu.mit.Kerberos.KerberosAgent
SavePasswordDisabled
    KRBCopyKeychainLookupInfo: DisableSaveToKeychainKey = TRUE
    KRBCopyKeychainLookupInfo: CFPreferencesCopyAppValue == NULL
]]] KRBCopyKeychainLookupInfo () = %d
[[[ KRBCopyServicePrincipal () - required parameters okay
    KRBCopyServicePrincipal: svcName mismatch inService = "%s", svcName = "%s"
    KRBCopyServicePrincipal: useName = "%s"
LKDC:
    KRBCopyServicePrincipal: realm is Local KDC.
    KRBCopyServicePrincipal: Bad inHostName, using svcInstance = "%s"
    KRBCopyServicePrincipal: useInstance = "%s"
    KRBCopyServicePrincipal: Fatal - Bad inHostName & no inAdvertisedPrincipal
%s/%s@%s
    KRBCopyServicePrincipal: principal = "%s/%s@%s"
]]] KRBCopyServicePrincipal () = %d
KRBCopyClientPrincipalInfo
[[[ KRBCopyClientPrincipalInfo () - required parameters okay
Certificate
    KRBCopyClientPrincipalInfo: Certificate information in dictionary
    KRBCopyClientPrincipalInfo: Certificate not present in dictionary
.Mac Sharing Certificate
%@@%@
    KRBCopyClientPrincipalInfo: Using login name = "%s"
    KRBCopyClientPrincipalInfo: principal guess = "%s"
    KRBCopyClientPrincipalInfo: ccache principal match = "%s"
    KRBCopyClientPrincipalInfo: found a single ticket for realm, replacing principal & username
    KRBCopyClientPrincipalInfo: Setting found Username to = "%s"
    KRBCopyClientPrincipalInfo: using principal = "%s"
ClientPrincipal
    KRBCopyClientPrincipalInfo: usingCertificate == %d
UsingCertificate
CetificateHash
CertificateInferredLabel
    KRBCopyClientPrincipalInfo: InferredLabel = "%s"
]]] KRBCopyClientPrincipalInfo () = %d
%@@%s
[[[ KRBTestForExistingTicket () - required parameters okay
    KRBTestForExistingTicket: principal = "%s"
    KRBTestForExistingTicket: Valid Ticket, ccacheName = "%s"
]]] KRBTestForExistingTicket () = %d
KRBAcquireTicket
[[[ KRBAcquireTicket () - required parameters okay
    KRBAcquireTicket: Using a certificate
Password
]]] KRBAcquireTicket () = %d
[[[ KRBCloseSession () - required parameters okay
]]] KRBCloseSession () = %d
parse_principal_name
KRBCreateSession
[[[ %s () - required parameters okay
    %s: LocalKDC realm lookup only
    %s: __KRBCreateUTF8StringFromCFString failed
[[[ %s () decomposing %s
]]] %s () - %d
    %s: processed host name = %s
%s.local
    %s: last char of host name = 0x%02x
success
    %s: getaddrinfo = %s (%d)
    %s: canonical host name = %s
    %s: secondary match = %s
    %s: primary match = %s
    %s: could not find a suitable host/realm mapping
    %s: Using host name = %s, realm = %s
]]] %s () = %d
KerberosKDC
dsRecTypeStandard:Config
realname
Communication to the helper failed
Not authorized
Input parameter error
Serializing object failed
Unserializing object failed
Object passed is not a dictionary
A Local KDC was not found
Lookup of the KDC for the requested realm failed
    %s: 
Success
<unknown error>

LKDCHelper

This executable is part of the KerberosHelper framework and is a launch agent that runs in the user's namespace. This appears to fire up a mach service called com.apple.KerberosHelper.LKDCHelper that is used for IPC with other interested parties (see: elsewhere on this page).

{34} andre@donk [~] % strings /System/Library/PrivateFrameworks/KerberosHelper.framework/Versions/A/Resources/LKDCHelper
Idle exit
do_LKDCDumpStatus
[[[ %s
do_LKDCSetLogLevel
do_LKDCGetLocalRealm
Cached lookup
LocalKDCRealm = %s
do_LKDCDiscoverRealm
Looking up realm for %s
do_LKDCFindKDCForRealm
Looking up host for %s
%s: 
Unauthorized access by euid=%lu pid=%lu
update_idle_timer
0 == gettimeofday(&last_message, NULL)
/SourceCache/KerberosHelper/KerberosHelper-31/Source/LKDCHelper-main.c
idletimer_main
0 == gettimeofday(&now, NULL)
Invalid idle timeout: %s
Usage: [-d] [-t maxidle]
Could not initialize ASL logging.
Starting (uid=%ul)
mach_port_allocate: %s
mach_port_insert_right: %s
com.apple.KerberosHelper.LKDCHelper
bootstrap_register2 failed: %s
CheckIn
Could not create checkin message for launchd.
Could not message launchd.
Launchd checkin failed: %s.
MachServices
Launchd reply does not contain %s dictionary.
Launchd reply does not contain %s Mach port.
Launchd gave me a null Mach port.
Failed to start idletimer thread: %s
mach_msg_server: %s
KerberosKDC
dsRecTypeStandard:Config
realname
_kerberos
LookupRealmCallBack
mDNSError = %d
More than one record, last one wins!!!
LKDCAddLocatorDetails
New entry for (realm=%s host=%s)
Replacing existing entry (realm=%s host=%s) with (realm=%s host=%s)
]]] %s = %d (%s)
LKDCHostnameForRealm
Cache hit
Cache miss
HandleEvents
LKDCLookupRealm
LKDCRealmForHostname
%s.%s
mDNSResult
CallbackError = %d
Timeout!
LKDCDumpCacheStatus
Cache root node = %08p
node = %08p {
                 realmName   = (%08p) %s
                 serviceHost = (%08p) %s
                 servicePort = %u
                 TTL         = %u
                }
Communication to the helper failed
Not authorized
Input parameter error
Serializing object failed
Unserializing object failed
Object passed is not a dictionary
A Local KDC was not found
Lookup of the KDC for the requested realm failed
    %s: 
Success
<unknown error>

configureLocalKDC

/usr/libexec/configureLocalKDC is a perl script that creates the LKDC at installation time (using kdcsetup, which also creates the directory services record), creates service principals and their corresponding keytabs, edits service config files for supported services, and installs a kerberos certificate into the system keychain. This is a pretty nice script, and is certainly worth a look. To give you an idea, consider the following data structure:

        my %afp_config = (service => 'afpserver', realm => $LKDC_realm,
                          prefs => '/Library/Preferences/com.apple.AppleFileServer',
                          key => 'kerberosPrincipal', format => '%s/%s@%2$s');

VNCPrivilegeProxy

/System/Library/CoreServices/RemoteManagement/AppleVNCServer.bundle/Contents/Support/VNCPrivilegeProxy - unsure exactly what this does.

{9} root@donk [Default/config] # strings /System/Library/CoreServices/RemoteManagement/AppleVNCServer.bundle/Contents/Support/VNCPrivilegeProxy
__dyld_make_delayed_module_initializer_calls
__dyld_mod_term_funcs
Starting Privilege Proxy
com.apple.RemoteDesktop.PrivilegeProxy
'%s' server already starting
bootstrap_check_in bootstrap_create_service() failed: status=%d
'%s' server already active
server_init bootstrap_check_in() failed: status=%d
server_init bootstrap_unprivileged() failed: status=%d
server_init task_set_bootstrap_port(): %s
mach_msg_server:
/Library/Preferences/com.apple.VNCSettings.txt
'2, /+0&7!4-)1#
80( 
91)!
:2*"
;3+#>6.&
=5-%
<4,$

Resources

  • http://crpit.com/confpapers/CRPITV26Pirzada2.pdf Kerberos assisted Authentication in Mobile Ad-hoc Networks. Here is an example of a Kerberos implementation designed for ad-hoc networks. Strangely enough, this is not a fully peer-to-peer implementation, and requires the existence of authentication servers other than the one hosting the service you wish to use. It also seems quite a bit more complex than apple's LKDC implementation.
  • http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.28.383 Distributed Authentication in Kerberos Using Public Key Cryptography. This document from 1997 describes how a PKI might be used to perform distributed authentication using Kerberos. This implementation eliminates the need for a centralized KDC (instead relying on a centralized certificate authority), although does not deal with dynamic peer discovery in an ad hoc networking context.