Ticket #59424: 0002-Apple-keychain-integration-other-changes.patch

File 0002-Apple-keychain-integration-other-changes.patch, 39.1 KB (added by iEFdev, 5 years ago)
  • new file keychain.m

    - +  
     1/*
     2 * Copyright (c) 2007-2016 Apple Inc. All rights reserved.
     3 *
     4 * @APPLE_BSD_LICENSE_HEADER_START@
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     10 * 1.  Redistributions of source code must retain the above copyright
     11 *     notice, this list of conditions and the following disclaimer.
     12 * 2.  Redistributions in binary form must reproduce the above copyright
     13 *     notice, this list of conditions and the following disclaimer in the
     14 *     documentation and/or other materials provided with the distribution.
     15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
     16 *     contributors may be used to endorse or promote products derived from
     17 *     this software without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 *
     30 * @APPLE_BSD_LICENSE_HEADER_END@
     31 */
     32
     33#include <AvailabilityMacros.h>
     34
     35#if ((!(defined (MAC_OS_X_VERSION_10_6))) || (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_6))
     36/*
     37 * Older versions of sys/acl.h are (arguably) buggy in that the
     38 * __APPLE_API_STRICT_CONFORMANCE macro - that we need for proper sandbox code
     39 * compilation on older systems (10.7-) - affects (or rather restricts) the
     40 * inclusion of macros in sys/kauth.h.
     41 *
     42 * These macros are then used unconditionally and everything blows up if the
     43 * former is set.
     44 *
     45 * This is not a problem with newer sys/acl.h versions, since these define
     46 * internal macros and hence don't rely on the KAUTH_* macros any longer (even
     47 * though they still include sys/kauth.h, which strictly speaking is redundant
     48 * in such a case).
     49 *
     50 * Since we don't need to work around any sandbox header bugs in the keychain
     51 * integration, let's just drop the former macro.
     52 */
     53#  ifdef __APPLE_API_STRICT_CONFORMANCE
     54#    undef __APPLE_API_STRICT_CONFORMANCE
     55#  endif /* defined (__APPLE_API_STRICT_CONFORMANCE) */
     56#endif /* ((!(defined (MAC_OS_X_VERSION_10_6))) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)) */
     57
     58#import <Foundation/Foundation.h>
     59#import <Security/Security.h>
     60#import "SecItemPriv-shim.h"
     61#include <sys/stat.h>
     62#include <stdio.h>
     63
     64#include "xmalloc.h"
     65#include "sshkey.h"
     66#include "ssherr.h"
     67#include "authfile.h"
     68#include "openbsd-compat/openbsd-compat.h"
     69#include "log.h"
     70
     71char *keychain_read_passphrase(const char *filename)
     72{
     73        OSStatus        ret = errSecSuccess;
     74        NSString        *accountString = [NSString stringWithUTF8String: filename];
     75        NSData          *passphraseData = NULL;
     76
     77        if (accountString == nil) {
     78                debug2("Cannot retrieve identity passphrase from the keychain since the path is not UTF8.");
     79                return NULL;
     80        }
     81
     82        NSDictionary    *searchQuery = @{
     83                               (id)kSecClass: (id)kSecClassGenericPassword,
     84                               (id)kSecAttrAccount: accountString,
     85                               (id)kSecAttrLabel: [NSString stringWithFormat: @"SSH: %@", accountString],
     86                               (id)kSecAttrService: @"OpenSSH",
     87#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     88                               (id)kSecAttrNoLegacy: @YES,
     89                               (id)kSecUseAuthenticationUI: (id)kSecUseAuthenticationUIFail,
     90#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     91#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     92                               (id)kSecAttrAccessGroup: @"com.apple.ssh.passphrases",
     93#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     94                               (id)kSecReturnData: @YES};
     95        debug3("Search for item with query: %s", [[searchQuery description] UTF8String]);
     96        ret = SecItemCopyMatching((CFDictionaryRef)searchQuery, (CFTypeRef *)&passphraseData);
     97        if (ret == errSecItemNotFound) {
     98                debug2("Passphrase not found in the keychain.");
     99                return NULL;
     100        } else if (ret != errSecSuccess) {
     101                NSString *errorString = (NSString *)SecCopyErrorMessageString(ret, NULL);
     102                debug2("Unexpected keychain error while searching for an item: %s", [errorString UTF8String]);
     103                [errorString release];
     104                [passphraseData release];
     105                return NULL;
     106        }
     107
     108        if (![passphraseData isKindOfClass: [NSData class]]) {
     109                debug2("Malformed result returned from the keychain");
     110                [passphraseData release];
     111                return NULL;
     112        }
     113
     114        char *passphrase = xcalloc([passphraseData length] + 1, sizeof(char));
     115        [passphraseData getBytes: passphrase length: [passphraseData length]];
     116        [passphraseData release];
     117
     118        // Try to load the key first and only return the passphrase if we know it's the right one
     119        struct sshkey *private = NULL;
     120        int r = sshkey_load_private_type(KEY_UNSPEC, filename, passphrase, &private, NULL);
     121        if (r != SSH_ERR_SUCCESS) {
     122                debug2("Could not unlock key with the passphrase retrieved from the keychain.");
     123                freezero(passphrase, strlen(passphrase));
     124                return NULL;
     125        }
     126        sshkey_free(private);
     127
     128        return passphrase;
     129}
     130
     131void store_in_keychain(const char *filename, const char *passphrase)
     132{
     133        OSStatus        ret = errSecSuccess;
     134        BOOL            updateExistingItem = NO;
     135        NSString        *accountString = [NSString stringWithUTF8String: filename];
     136
     137        if (accountString == nil) {
     138                debug2("Cannot store identity passphrase into the keychain since the path is not UTF8.");
     139                return;
     140        }
     141
     142        NSDictionary    *defaultAttributes = @{
     143                                (id)kSecClass: (id)kSecClassGenericPassword,
     144                                (id)kSecAttrAccount: accountString,
     145                                (id)kSecAttrLabel: [NSString stringWithFormat: @"SSH: %@", accountString],
     146                                (id)kSecAttrService: @"OpenSSH",
     147#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     148                                (id)kSecAttrNoLegacy: @YES,
     149                                (id)kSecUseAuthenticationUI: (id)kSecUseAuthenticationUIFail,
     150#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     151#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     152                                (id)kSecAttrAccessGroup: @"com.apple.ssh.passphrases"};
     153#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     154
     155        CFTypeRef searchResults = NULL;
     156        NSMutableDictionary *searchQuery = [@{(id)kSecReturnRef: @YES} mutableCopy];
     157        [searchQuery addEntriesFromDictionary: defaultAttributes];
     158
     159        debug3("Search for existing item with query: %s", [[searchQuery description] UTF8String]);
     160        ret = SecItemCopyMatching((CFDictionaryRef)searchQuery, &searchResults);
     161        [searchQuery release];
     162        if (ret == errSecSuccess) {
     163                debug3("Item already exists in the keychain, updating.");
     164                updateExistingItem = YES;
     165
     166        } else if (ret == errSecItemNotFound) {
     167                debug3("Item does not exist in the keychain, adding.");
     168        } else {
     169                NSString *errorString = (NSString *)SecCopyErrorMessageString(ret, NULL);
     170                debug3("Unexpected keychain error while searching for an item: %s", [errorString UTF8String]);
     171                [errorString release];
     172        }
     173
     174        if (updateExistingItem) {
     175                NSDictionary *updateQuery = defaultAttributes;
     176                NSDictionary *changes = @{(id)kSecValueData: [NSData dataWithBytesNoCopy: (void *)passphrase length: strlen(passphrase) freeWhenDone: NO]};
     177
     178                ret = SecItemUpdate((CFDictionaryRef)updateQuery, (CFDictionaryRef)changes);
     179                if (ret != errSecSuccess) {
     180                        NSString *errorString = (NSString *)SecCopyErrorMessageString(ret, NULL);
     181                        debug3("Unexpected keychain error while updating the item: %s", [errorString UTF8String]);
     182                        [errorString release];
     183                }
     184        } else {
     185                NSMutableDictionary *addQuery = [@{(id)kSecValueData: [NSData dataWithBytesNoCopy: (void *)passphrase length: strlen(passphrase) freeWhenDone: NO]} mutableCopy];
     186
     187                [addQuery addEntriesFromDictionary: defaultAttributes];
     188                ret = SecItemAdd((CFDictionaryRef)addQuery, NULL);
     189                [addQuery release];
     190                if (ret != errSecSuccess) {
     191                        NSString *errorString = (NSString *)SecCopyErrorMessageString(ret, NULL);
     192                        debug3("Unexpected keychain error while inserting the item: %s", [errorString UTF8String]);
     193                        [errorString release];
     194                }
     195        }
     196}
     197
     198/*
     199 * Remove the passphrase for a given identity from the keychain.
     200 */
     201void
     202remove_from_keychain(const char *filename)
     203{
     204        OSStatus        ret = errSecSuccess;
     205        NSString        *accountString = [NSString stringWithUTF8String: filename];
     206
     207        if (accountString == nil) {
     208                debug2("Cannot delete identity passphrase from the keychain since the path is not UTF8.");
     209                return;
     210        }
     211
     212        NSDictionary    *searchQuery = @{
     213                               (id)kSecClass: (id)kSecClassGenericPassword,
     214                               (id)kSecAttrAccount: accountString,
     215                               (id)kSecAttrService: @"OpenSSH",
     216#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     217                               (id)kSecAttrNoLegacy: @YES,
     218                               (id)kSecUseAuthenticationUI: (id)kSecUseAuthenticationUIFail,
     219#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     220#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     221                               (id)kSecAttrAccessGroup: @"com.apple.ssh.passphrases"};
     222#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     223
     224        ret = SecItemDelete((CFDictionaryRef)searchQuery);
     225        if (ret == errSecSuccess) {
     226                NSString *errorString = (NSString *)SecCopyErrorMessageString(ret, NULL);
     227                debug3("Unexpected keychain error while deleting the item: %s", [errorString UTF8String]);
     228                [errorString release];
     229        }
     230}
     231
     232
     233int
     234load_identities_from_keychain(int (^add_identity)(const char *identity))
     235{
     236        int             ret = 0;
     237        OSStatus        err = errSecSuccess;
     238
     239        NSArray         *searchResults = nil;
     240        NSDictionary    *searchQuery = @{
     241                                (id)kSecClass: (id)kSecClassGenericPassword,
     242                                (id)kSecAttrService: @"OpenSSH",
     243#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     244                                (id)kSecAttrNoLegacy: @YES,
     245                                (id)kSecUseAuthenticationUI: (id)kSecUseAuthenticationUIFail,
     246#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     247#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     248                                (id)kSecAttrAccessGroup: @"com.apple.ssh.passphrases",
     249#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     250                                (id)kSecReturnAttributes: @YES,
     251                                (id)kSecMatchLimit: (id)kSecMatchLimitAll};
     252
     253        err = SecItemCopyMatching((CFDictionaryRef)searchQuery, (CFTypeRef *)&searchResults);
     254        if (err == errSecItemNotFound) {
     255                fprintf(stderr, "No identity found in the keychain.\n");
     256                [searchResults release];
     257                return 0;
     258        } else if (err != errSecSuccess || ![searchResults isKindOfClass: [NSArray class]]) {
     259                return 1;
     260        }
     261
     262        for (NSDictionary *itemAttributes in searchResults) {
     263                NSString        *accountString = itemAttributes[(id)kSecAttrAccount];
     264                struct stat     st;
     265
     266                if (stat([accountString UTF8String], &st) < 0)
     267                        continue;
     268                if (add_identity([accountString UTF8String]))
     269                        ret = 1;
     270        }
     271        [searchResults release];
     272
     273        return ret;
     274}
  • new file keychain.h

    - +  
     1/*
     2 * Copyright (c) 2007-2016 Apple Inc. All rights reserved.
     3 *
     4 * @APPLE_BSD_LICENSE_HEADER_START@
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     10 * 1.  Redistributions of source code must retain the above copyright
     11 *     notice, this list of conditions and the following disclaimer.
     12 * 2.  Redistributions in binary form must reproduce the above copyright
     13 *     notice, this list of conditions and the following disclaimer in the
     14 *     documentation and/or other materials provided with the distribution.
     15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
     16 *     contributors may be used to endorse or promote products derived from
     17 *     this software without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 *
     30 * @APPLE_BSD_LICENSE_HEADER_END@
     31 */
     32
     33void    store_in_keychain(const char *filename, const char *passphrase);
     34void    remove_from_keychain(const char *filename);
     35char    *keychain_read_passphrase(const char *filename);
     36int     load_identities_from_keychain(int (^add_identity)(const char *identity));
  • Makefile.in

    a b PATHS= -DSSHDIR=\"$(sysconfdir)\" \ 
    4141CC=@CC@
    4242LD=@LD@
    4343CFLAGS=@CFLAGS@
     44OBJCFLAGS=@OBJCFLAGS@
    4445CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
    4546LIBS=@LIBS@
    4647K5LIBS=@K5LIBS@
    SED=@SED@ 
    5657ENT=@ENT@
    5758XAUTH_PATH=@XAUTH_PATH@
    5859LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
     60KEYCHAIN_LDFLAGS=@KEYCHAIN_LDFLAGS@
    5961EXEEXT=@EXEEXT@
    6062MANFMT=@MANFMT@
    6163MKDIR_P=@MKDIR_P@
    SSHDOBJS=sshd.o auth-rhosts.o auth-passw 
    121123        sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
    122124        sandbox-solaris.o uidswap.o
    123125
     126KEYCHAINOBJS=keychain.o
     127
    124128MANPAGES        = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
    125129MANPAGES_IN     = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
    126130MANTYPE         = @MANTYPE@
    all: configure-check $(CONFIGFILES) $(MA 
    156160$(LIBSSH_OBJS): Makefile.in config.h
    157161$(SSHOBJS): Makefile.in config.h
    158162$(SSHDOBJS): Makefile.in config.h
     163$(KEYCHAINOBJS): Makefile.in config.h
    159164configure-check: $(srcdir)/configure
    160165
    161166$(srcdir)/configure: configure.ac aclocal.m4
    $(srcdir)/configure: configure.ac acloca 
    164169
    165170.c.o:
    166171        $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
     172.m.o:
     173        $(CC) $(OBJCFLAGS) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
    167174
    168175LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
    169176$(LIBCOMPAT): always
    libssh.a: $(LIBSSH_OBJS) 
    174181        $(AR) rv $@ $(LIBSSH_OBJS)
    175182        $(RANLIB) $@
    176183
    177 ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
    178         $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
     184ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) $(KEYCHAINOBJS)
     185        $(LD) -o $@ $(SSHOBJS) $(KEYCHAINOBJS) $(LDFLAGS) $(KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
    179186
    180187sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
    181188        $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
    sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(S 
    183190scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
    184191        $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
    185192
    186 ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
    187         $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
     193ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(KEYCHAINOBJS)
     194        $(LD) -o $@ ssh-add.o $(KEYCHAINOBJS) $(LDFLAGS) $(KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
    188195
    189 ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
    190         $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
     196ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o $(KEYCHAINOBJS)
     197        $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(KEYCHAINOBJS) $(LDFLAGS) $(KEYCHAIN_LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
    191198
    192199ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o sshsig.o
    193200        $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
  • audit-bsm.c

    a b  
    6262#include <bsm/audit_record.h>
    6363#include <locale.h>
    6464
     65#ifdef __APPLE__
     66#include <AvailabilityMacros.h>
     67#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     68#include <bsm/audit_session.h>
     69#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     70#include "auth-options.h"
     71#include "misc.h"
     72#include "servconf.h"
     73extern ServerOptions options;
     74extern struct sshauthopt *auth_opts;
     75#endif
     76
    6577#if defined(HAVE_GETAUDIT_ADDR)
    6678#define AuditInfoStruct         auditinfo_addr
    6779#define AuditInfoTermID         au_tid_addr_t
    bsm_audit_session_setup(void) 
    305317                return;
    306318        }
    307319
     320#ifdef __APPLE__
     321        bzero(&info, sizeof (info));
     322#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     323        info.ai_flags = AU_SESSION_FLAG_IS_REMOTE;
     324        if (the_authctxt->valid)  {
     325            info.ai_flags |=  AU_SESSION_FLAG_HAS_AUTHENTICATED;
     326        }
     327        if (auth_opts->permit_pty_flag && options.permit_tty) {
     328                info.ai_flags |=  AU_SESSION_FLAG_HAS_TTY;
     329        }
     330#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     331#endif
     332
    308333        if (the_authctxt->valid)
    309334                info.ai_auid = the_authctxt->pw->pw_uid;
    310335        else
  • configure.ac

    a b AC_LANG([C]) 
    2020
    2121AC_CONFIG_HEADER([config.h])
    2222AC_PROG_CC([cc gcc])
     23AC_PROG_OBJC([cc clang gcc])
    2324AC_CANONICAL_HOST
    2425AC_C_BIGENDIAN
    2526
    main() { if (NSVersionOfRunTimeLibrary(" 
    667668        AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
    668669            [Prepend the address family to IP tunnel traffic])
    669670        m4_pattern_allow([AU_IPv])
    670         AC_CHECK_DECL([AU_IPv4], [],
    671             AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
    672             [#include <bsm/audit.h>]
    673         AC_DEFINE([LASTLOG_WRITE_PUTUTXLINE], [1],
    674             [Define if pututxline updates lastlog too])
     671        AC_CHECK_DECL([AU_IPv4],
     672            AC_DEFINE([LASTLOG_WRITE_PUTUTXLINE], [1],
     673                [Define if pututxline updates lastlog too]),
     674            AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]),
     675            [[#include <bsm/audit.h>]]
    675676        )
    676677        AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV],
    677678                [Define to a Set Process Title type if your system is
    AC_CHECK_MEMBER([struct utmp.ut_line], [ 
    51525153#endif
    51535154        ])
    51545155
     5156dnl Keychain support
     5157AC_ARG_WITH(keychain,
     5158        [  --with-keychain=apple   Use macOS Keychain],
     5159        [
     5160                case "$withval" in
     5161                apple|no)
     5162                        KEYCHAIN=$withval
     5163                        ;;
     5164                *)
     5165                        AC_MSG_ERROR(invalid keychain type: $withval)
     5166                        ;;
     5167                esac
     5168        ]
     5169)
     5170if test ! -z "$KEYCHAIN" -a "$KEYCHAIN" != "no"; then
     5171        case "$KEYCHAIN" in
     5172        apple)
     5173                AC_CHECK_HEADERS(Security/Security.h, [
     5174                                CPPFLAGS="$CPPFLAGS -D__APPLE_KEYCHAIN__ -D__APPLE_MEMBERSHIP__ -D__APPLE_TMPDIR__ -D__APPLE_LAUNCHD__"
     5175                                OBJCFLAGS="$OBJCFLAGS -F/System/Library/Frameworks/Security.framework -F/System/Library/Frameworks/DirectoryService.framework -F/System/Library/Frameworks/CoreFoundation.framework"
     5176                                KEYCHAIN_LDFLAGS="-framework Security -framework CoreFoundation -framework Foundation -lobjc"
     5177                                AC_SUBST(KEYCHAIN_LDFLAGS)
     5178                                ],
     5179                                AC_MSG_WARN([Security framework not found. Disabling macOS Keychain support.]))
     5180                ;;
     5181        esac
     5182fi
     5183
    51555184dnl Adding -Werror to CFLAGS early prevents configure tests from running.
    51565185dnl Add now.
    51575186CFLAGS="$CFLAGS $werror_flags"
  • groupaccess.c

    a b  
    3939#include "match.h"
    4040#include "log.h"
    4141
     42#ifdef __APPLE_MEMBERSHIP__
     43int32_t getgrouplist_2(const char *, gid_t, gid_t **);
     44#endif
     45
    4246static int ngroups;
    4347static char **groups_byname;
    4448
    ga_init(const char *user, gid_t base) 
    5660        if (ngroups > 0)
    5761                ga_free();
    5862
     63#ifdef __APPLE_MEMBERSHIP__
     64        (void)retry;
     65        if ((ngroups = getgrouplist_2(user, base, &groups_bygid)) == -1) {
     66                logit("getgrouplist_2 failed");
     67                /*
     68                 * getgrouplist_2 only fails on memory error; in which case
     69                 * groups_bygid will be left NULL so no need to free.
     70                 */
     71                return 0;
     72        }
     73        groups_byname = xcalloc(ngroups, sizeof(*groups_byname));
     74#else
    5975        ngroups = NGROUPS_MAX;
    6076#if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
    6177        ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX));
    ga_init(const char *user, gid_t base) 
    6985                    sizeof(*groups_bygid));
    7086        }
    7187        groups_byname = xcalloc(ngroups, sizeof(*groups_byname));
     88#endif /* __APPLE_MEMBERSHIP__ */
    7289
    7390        for (i = 0, j = 0; i < ngroups; i++)
    7491                if ((gr = getgrgid(groups_bygid[i])) != NULL)
  • readconf.c

    a b typedef enum { 
    167167        oHashKnownHosts,
    168168        oTunnel, oTunnelDevice,
    169169        oLocalCommand, oPermitLocalCommand, oRemoteCommand,
     170#ifdef __APPLE_KEYCHAIN__
     171        oUseKeychain,
     172#endif
    170173        oVisualHostKey,
    171174        oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
    172175        oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
    static struct { 
    291294        { "localcommand", oLocalCommand },
    292295        { "permitlocalcommand", oPermitLocalCommand },
    293296        { "remotecommand", oRemoteCommand },
     297#ifdef __APPLE_KEYCHAIN__
     298        { "usekeychain", oUseKeychain},
     299#endif
    294300        { "visualhostkey", oVisualHostKey },
    295301        { "kexalgorithms", oKexAlgorithms },
    296302        { "ipqos", oIPQoS },
    parse_keytypes: 
    15201526                charptr = &options->remote_command;
    15211527                goto parse_command;
    15221528
     1529#ifdef __APPLE_KEYCHAIN__
     1530        case oUseKeychain:
     1531                intptr = &options->use_keychain;
     1532                goto parse_flag;
     1533#endif
     1534
    15231535        case oVisualHostKey:
    15241536                intptr = &options->visual_host_key;
    15251537                goto parse_flag;
    initialize_options(Options * options) 
    19291941        options->local_command = NULL;
    19301942        options->permit_local_command = -1;
    19311943        options->remote_command = NULL;
     1944#ifdef __APPLE_KEYCHAIN__
     1945        options->use_keychain = -1;
     1946#endif
    19321947        options->add_keys_to_agent = -1;
    19331948        options->identity_agent = NULL;
    19341949        options->visual_host_key = -1;
    fill_default_options(Options * options) 
    21682183        /* options->hostname will be set in the main program if appropriate */
    21692184        /* options->host_key_alias should not be set by default */
    21702185        /* options->preferred_authentications will be set in ssh */
     2186
     2187#ifdef __APPLE_KEYCHAIN__
     2188        if (options->use_keychain == -1)
     2189                options->use_keychain = 0;
     2190#endif
    21712191}
    21722192
    21732193struct fwdarg {
  • readconf.h

    a b typedef struct { 
    137137        char    *local_command;
    138138        int     permit_local_command;
    139139        char    *remote_command;
     140#ifdef __APPLE_KEYCHAIN__
     141        int     use_keychain;
     142#endif
    140143        int     visual_host_key;
    141144
    142145        int     request_tty;
  • session.c

    a b do_setup_env(struct ssh *ssh, Session *s 
    11851185                child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
    11861186                    original_command);
    11871187
     1188#ifdef __APPLE_TMPDIR__
     1189        char tmpdir[MAXPATHLEN] = {0};
     1190        size_t len = 0;
     1191
     1192        len = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, sizeof(tmpdir));
     1193        if (len > 0) {
     1194                child_set_env(&env, &envsize, "TMPDIR", tmpdir);
     1195                debug2("%s: set TMPDIR", __func__);
     1196        } else {
     1197                // errno is set by confstr
     1198                errno = 0;
     1199                debug2("%s: unable to set TMPDIR", __func__);
     1200        }
     1201#endif /* __APPLE_TMPDIR__ */
     1202
    11881203        if (debug_flag) {
    11891204                /* dump the environment */
    11901205                fprintf(stderr, "Environment:\n");
  • ssh-add.0

    a b NAME 
    44     ssh-add M-bM-^@M-^S adds private key identities to the authentication agent
    55
    66SYNOPSIS
    7      ssh-add [-cDdkLlqvXx] [-E fingerprint_hash] [-t life] [file ...]
     7     ssh-add [-AcDdKkLlqvXx] [-E fingerprint_hash] [-t life] [file ...]
    88     ssh-add -s pkcs11
    99     ssh-add -e pkcs11
    1010     ssh-add -T pubkey ...
    DESCRIPTION 
    2828
    2929     The options are as follows:
    3030
     31     -A      Add identities to the agent using any passphrases stored in your
     32             macOS keychain.
     33
    3134     -c      Indicates that added identities should be subject to confirmation
    3235             before being used for authentication.  Confirmation is performed
    3336             by ssh-askpass(1).  Successful confirmation is signaled by a zero
    DESCRIPTION 
    5255     -e pkcs11
    5356             Remove keys provided by the PKCS#11 shared library pkcs11.
    5457
     58     -K      When adding identities, each passphrase will also be stored in
     59             your macOS keychain.  When removing identities with -d, each
     60             passphrase will be removed from your macOS keychain.
     61
    5562     -k      When loading keys into or deleting keys from the agent, process
    5663             plain private keys only and skip certificates.
    5764
  • ssh-add.1

    a b  
    4343.Nd adds private key identities to the authentication agent
    4444.Sh SYNOPSIS
    4545.Nm ssh-add
    46 .Op Fl cDdkLlqvXx
     46.Op Fl AcDdKKkLlqvXx
    4747.Op Fl E Ar fingerprint_hash
    4848.Op Fl t Ar life
    4949.Op Ar
    to work. 
    8787.Pp
    8888The options are as follows:
    8989.Bl -tag -width Ds
     90.It Fl A
     91Add identities to the agent using any passphrases stored in your macOS
     92keychain.
    9093.It Fl c
    9194Indicates that added identities should be subject to confirmation before
    9295being used for authentication.
    The default is 
    121124.It Fl e Ar pkcs11
    122125Remove keys provided by the PKCS#11 shared library
    123126.Ar pkcs11 .
     127.It Fl K
     128When adding identities, each passphrase will also be stored in your macOS
     129keychain.  When removing identities with -d, each passphrase will be removed
     130from your macOS keychain.
    124131.It Fl k
    125132When loading keys into or deleting keys from the agent, process plain private
    126133keys only and skip certificates.
  • ssh-add.c

    a b  
    6767#include "ssherr.h"
    6868#include "digest.h"
    6969
     70#ifdef __APPLE_KEYCHAIN__
     71#include "keychain.h"
     72static int use_keychain = 0;
     73#endif
     74
    7075/* argv0 */
    7176extern char *__progname;
    7277
    delete_file(int agent_fd, const char *fi 
    115120        char *certpath = NULL, *comment = NULL;
    116121        int r, ret = -1;
    117122
     123#ifdef __APPLE_KEYCHAIN__
     124        if (use_keychain)
     125                remove_from_keychain(filename);
     126#endif
     127
    118128        if ((r = sshkey_load_public(filename, &public,  &comment)) != 0) {
    119129                printf("Bad key file %s: %s\n", filename, ssh_err(r));
    120130                return -1;
    add_file(int agent_fd, const char *filen 
    246256                            filename, ssh_err(r));
    247257                        goto fail_load;
    248258                }
     259#ifdef __APPLE_KEYCHAIN__
     260                if (use_keychain && private != NULL)
     261                        store_in_keychain(filename, pass);
     262#endif
     263        }
     264
     265#ifdef __APPLE_KEYCHAIN__
     266        // try the keychain
     267        if (private == NULL && use_keychain) {
     268                clear_pass();
     269                pass = keychain_read_passphrase(filename);
     270                if (pass != NULL)
     271                        sshkey_parse_private_fileblob(keyblob, pass, &private, &comment);
    249272        }
     273#endif
     274
    250275        if (private == NULL) {
    251276                /* clear passphrase since it did not work */
    252277                clear_pass();
    add_file(int agent_fd, const char *filen 
    258283                                goto fail_load;
    259284                        if ((r = sshkey_parse_private_fileblob(keyblob, pass,
    260285                            &private, &comment)) == 0)
     286#ifdef __APPLE_KEYCHAIN__
     287                        {
     288                                if (use_keychain && private != NULL)
     289                                        store_in_keychain(filename, pass);
    261290                                break;
     291                        }
     292#else
     293                                break;
     294#endif
    262295                        else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
    263296                                fprintf(stderr,
    264297                                    "Error loading key \"%s\": %s\n",
    usage(void) 
    563596        fprintf(stderr, "  -T pubkey   Test if ssh-agent can access matching private key.\n");
    564597        fprintf(stderr, "  -q          Be quiet after a successful operation.\n");
    565598        fprintf(stderr, "  -v          Be more verbose.\n");
     599#ifdef __APPLE_KEYCHAIN__
     600        fprintf(stderr, "  -A          Add all identities stored in your macOS keychain.\n");
     601        fprintf(stderr, "  -K          Store passphrases in your macOS keychain.\n");
     602        fprintf(stderr, "              With -d, remove passphrases from your macOS keychain.\n");
     603#endif
    566604}
    567605
    568606int
  • ssh-agent.c

    a b  
    7070#include <time.h>
    7171#include <string.h>
    7272#include <unistd.h>
     73#ifdef __APPLE_LAUNCHD__
     74#include <launch.h>
     75#include <AvailabilityMacros.h>
     76#endif
    7377#ifdef HAVE_UTIL_H
    7478# include <util.h>
    7579#endif
    int 
    10881092main(int ac, char **av)
    10891093{
    10901094        int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
     1095        #ifdef __APPLE_LAUNCHD__
     1096        int l_flag = 0;
     1097        #endif
    10911098        int sock, fd, ch, result, saved_errno;
    10921099        char *shell, *format, *pidstr, *agentsocket = NULL;
    10931100#ifdef HAVE_SETRLIMIT
    main(int ac, char **av) 
    11191126        __progname = ssh_get_progname(av[0]);
    11201127        seed_rng();
    11211128
     1129#ifdef __APPLE_LAUNCHD__
     1130        while ((ch = getopt(ac, av, "cDdklsE:a:P:t:")) != -1) {
     1131#else
    11221132        while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
     1133#endif
    11231134                switch (ch) {
    11241135                case 'E':
    11251136                        fingerprint_hash = ssh_digest_alg_by_name(optarg);
    main(int ac, char **av) 
    11391150                                fatal("-P option already specified");
    11401151                        pkcs11_whitelist = xstrdup(optarg);
    11411152                        break;
     1153#ifdef __APPLE_LAUNCHD__
     1154                case 'l':
     1155                        l_flag++;
     1156                        break;
     1157#endif
    11421158                case 's':
    11431159                        if (c_flag)
    11441160                                usage();
    main(int ac, char **av) 
    12411257         * Create socket early so it will exist before command gets run from
    12421258         * the parent.
    12431259         */
     1260#ifdef __APPLE_LAUNCHD__
     1261        if (l_flag) {
     1262#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     1263                int *fds = NULL;
     1264                size_t count = 0;
     1265                result = launch_activate_socket("Listeners", &fds, &count);
     1266
     1267                if (result != 0 || fds == NULL || count < 1) {
     1268                        errno = result;
     1269                        perror("launch_activate_socket()");
     1270                        exit(1);
     1271                }
     1272
     1273                size_t i;
     1274                for (i = 0; i < count; i++) {
     1275                        new_socket(AUTH_SOCKET, fds[i]);
     1276                }
     1277
     1278                if (fds)
     1279                        free(fds);
     1280
     1281                goto skip2;
     1282#else /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     1283                launch_data_t resp, msg, tmp;
     1284                size_t listeners_i;
     1285
     1286                msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
     1287
     1288                resp = launch_msg(msg);
     1289
     1290                if (NULL == resp) {
     1291                        perror("launch_msg");
     1292                        exit(1);
     1293                }
     1294                launch_data_free(msg);
     1295                switch (launch_data_get_type(resp)) {
     1296                case LAUNCH_DATA_ERRNO:
     1297                        errno = launch_data_get_errno(resp);
     1298                        perror("launch_msg response");
     1299                        exit(1);
     1300                case LAUNCH_DATA_DICTIONARY:
     1301                        break;
     1302                default:
     1303                        fprintf(stderr, "launch_msg unknown response");
     1304                        exit(1);
     1305                }
     1306                tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS);
     1307
     1308                if (NULL == tmp) {
     1309                        fprintf(stderr, "no sockets\n");
     1310                        exit(1);
     1311                }
     1312
     1313                tmp = launch_data_dict_lookup(tmp, "Listeners");
     1314
     1315                if (NULL == tmp) {
     1316                        fprintf(stderr, "no known listeners\n");
     1317                        exit(1);
     1318                }
     1319
     1320                for (listeners_i = 0; listeners_i < launch_data_array_get_count(tmp); listeners_i++) {
     1321                        launch_data_t obj_at_ind = launch_data_array_get_index(tmp, listeners_i);
     1322                        new_socket(AUTH_SOCKET, launch_data_get_fd(obj_at_ind));
     1323                }
     1324
     1325                launch_data_free(resp);
     1326#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     1327        } else {
     1328#endif
    12441329        prev_mask = umask(0177);
    12451330        sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
    12461331        if (sock < 0) {
    main(int ac, char **av) 
    12481333                *socket_name = '\0'; /* Don't unlink any existing file */
    12491334                cleanup_exit(1);
    12501335        }
     1336
    12511337        umask(prev_mask);
     1338#ifdef __APPLE_LAUNCHD__
     1339        }
     1340#endif
     1341
     1342#ifdef __APPLE_LAUNCHD__
     1343#if ((!(defined (MAC_OS_X_VERSION_10_11))) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11))
     1344        if (l_flag)
     1345                goto skip2;
     1346#endif /* ((!(defined (MAC_OS_X_VERSION_10_11))) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)) */
     1347#endif /* defined (__APPLE_LAUNCHD__) */
    12521348
    12531349        /*
    12541350         * Fork, and have the parent execute the command, if any, or present
    skip: 
    13261422        pkcs11_init(0);
    13271423#endif
    13281424        new_socket(AUTH_SOCKET, sock);
     1425#ifdef __APPLE_LAUNCHD__
     1426skip2:
     1427#endif
    13291428        if (ac > 0)
    13301429                parent_alive_interval = 10;
    13311430        idtab_init();
  • sshconnect2.c

    a b  
    7373#include "ssherr.h"
    7474#include "utf8.h"
    7575
     76#ifdef __APPLE_KEYCHAIN__
     77#include "keychain.h"
     78int found_in_keychain = 0;
     79#endif
     80
    7681#ifdef GSSAPI
    7782#include "ssh-gss.h"
    7883#endif
    load_identity_file(Identity *id) 
    14151420        snprintf(prompt, sizeof prompt,
    14161421            "Enter passphrase for key '%.100s': ", id->filename);
    14171422        for (i = 0; i <= options.number_of_password_prompts; i++) {
     1423#ifdef __APPLE_KEYCHAIN__
     1424                if (i == 0 && options.use_keychain && (passphrase = keychain_read_passphrase(id->filename)) != NULL) {
     1425                        found_in_keychain = 1;
     1426                        debug2("using passphrase from keychain");
     1427                } else
     1428#endif
    14181429                if (i == 0)
    14191430                        passphrase = "";
    14201431                else {
    load_identity_file(Identity *id) 
    14501461                        quit = 1;
    14511462                        break;
    14521463                }
     1464
     1465#ifdef __APPLE_KEYCHAIN__
     1466                if (!quit && private != NULL && !(id->key && id->isprivate) && options.use_keychain && !found_in_keychain) {
     1467                        debug2("storing passphrase in keychain");
     1468                        store_in_keychain(id->filename, passphrase);
     1469                }
     1470#endif
     1471
    14531472                if (!quit && private != NULL && id->agent_fd == -1 &&
    14541473                    !(id->key && id->isprivate))
    14551474                        maybe_add_key_to_agent(id->filename, private, comment,
  • ssh-agent.0

    a b SYNOPSIS 
    77     ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]
    88               [-P pkcs11_whitelist] [-t life] [command [arg ...]]
    99     ssh-agent [-c | -s] -k
     10     ssh-agent -l
    1011
    1112DESCRIPTION
    1213     ssh-agent is a program to hold private keys used for public key
    DESCRIPTION 
    6465             for an identity with ssh-add(1) overrides this value.  Without
    6566             this option the default maximum lifetime is forever.
    6667
     68     -l      Start in launchd mode.  This feature should only be used by macOS
     69             itself.  It is not very useful to users.
     70
    6771     If a command line is given, this is executed as a subprocess of the
    6872     agent.  When the command dies, so does the agent.
    6973
  • ssh-agent.1

    a b  
    5252.Nm ssh-agent
    5353.Op Fl c | s
    5454.Fl k
     55.Nm ssh-agent
     56.Fl l
    5557.Sh DESCRIPTION
    5658.Nm
    5759is a program to hold private keys used for public key authentication
    A lifetime specified for an identity wit 
    148150.Xr ssh-add 1
    149151overrides this value.
    150152Without this option the default maximum lifetime is forever.
     153.It Fl l
     154Start in launchd mode.
     155This feature should only be used by macOS itself.
     156It is not very useful to users.
    151157.El
    152158.Pp
    153159If a command line is given, this is executed as a subprocess of the agent.
  • new file SecItemPriv-shim.h

    - +  
     1/*
     2 * Copyright (c) 2006-2013 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/*
     25    @header SecItemPriv
     26    SecItemPriv defines private constants and SPI functions for access to
     27    Security items (certificates, identities, keys, and keychain items.)
     28
     29    ====== MACPORTS NOTICE ======
     30    Apple uses this private header file for building its OpenSSH keychain
     31    integration. They are able to do this because they have either converted
     32    all (or most?) upstream projects into Xcode projects and can then use
     33    private headers, but our users can't.
     34
     35    Private header files are never installed onto user systems and there
     36    aren't any SDKs that users could install to get them.
     37
     38    Luckily, the Security Framework *is* (currently) free software, so we do
     39    have access to it via https://opensource.apple.com
     40
     41    We can, hence, take a look at it and copy relevant parts/declarations.
     42
     43    We cannot, however, make sure that the declarations in here are actually
     44    defined in the Security Framework binaries/libraries themselves, so
     45    building this part, especially on older systems, might still fail.
     46    ====== MACPORTS NOTICE ======
     47*/
     48
     49#ifndef _SECURITY_SECITEMPRIV_H_
     50#define _SECURITY_SECITEMPRIV_H_
     51
     52#include <CoreFoundation/CFDictionary.h>
     53#include <CoreFoundation/CFData.h>
     54#include <CoreFoundation/CFError.h>
     55#include <TargetConditionals.h>
     56#include <Security/SecBase.h>
     57
     58#if ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9))
     59#include <xpc/xpc.h>
     60
     61#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
     62#include <Security/SecTask.h>
     63#endif
     64#endif /* ((defined (MAC_OS_X_VERSION_10_9)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) */
     65
     66__BEGIN_DECLS
     67
     68/*
     69    @enum Attribute Key Constants (Private)
     70    @discussion Predefined item attribute keys used to get or set values in a
     71        dictionary. Not all attributes apply to each item class. The table
     72        below lists the currently defined attributes for each item class:
     73
     74        @constant kSecAttrNoLegacy Specifies a dictionary key whose
     75        value is a CFBooleanRef indicating that the query must be run on the
     76        syncable backend even for non syncable items.
     77*/
     78
     79#if ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))
     80extern const CFStringRef kSecAttrNoLegacy
     81    __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.3) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3);
     82#endif /* ((defined (MAC_OS_X_VERSION_10_11)) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) */
     83
     84__END_DECLS
     85
     86#endif /* !_SECURITY_SECITEMPRIV_H_ */