+++ /dev/null
-rotty?Data
+++ /dev/null
-AppleCSPDL?Data
+++ /dev/null
-PBUserInfo
-AppleX509CL?Data
MacOSError::throwMe(errSecInvalidCallback);
}
-void CCallbackMgr::AlertClients(SecKeychainEvent inEvent,
+void CCallbackMgr::AlertClients(const list<CallbackInfo> &eventCallbacks,
+ SecKeychainEvent inEvent,
pid_t inPid,
const Keychain &inKeychain,
const Item &inItem)
secdebug("kcnotify", "dispatch event %ld pid %d keychain %p item %p",
inEvent, inPid, &inKeychain, !!inItem ? &*inItem : NULL);
- // Deal with events that we care about ourselves first.
- if (inEvent == kSecDeleteEvent && inKeychain.get() && inItem.get())
- inKeychain->didDeleteItem(inItem.get());
-
// Iterate through callbacks, looking for those registered for inEvent
const SecKeychainEventMask theMask = 1U << inEvent;
- for ( CallbackInfoListIterator ix = CCallbackMgr::Instance().mEventCallbacks.begin();
- ix != CCallbackMgr::Instance().mEventCallbacks.end(); ++ix )
+ for (ConstCallbackInfoListIterator ix = eventCallbacks.begin(); ix != eventCallbacks.end(); ++ix)
{
if (!(ix->mEventMask & theMask))
continue;
* If it wasn't 'us', we should remove our cached reference to the item that was deleted.
*
***********************************************************************************/
-void CCallbackMgr::Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary)
+void CCallbackMgr::Event(Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary)
{
// Decode from userInfo the event type, 'keychain' CFDict, and 'item' CFDict
SecKeychainEvent thisEvent = whichEvent;
pid_t thisPid;
- const NameValuePair* pidRef = dictionary.FindByName (PID_KEY);
+ const NameValuePair* pidRef = dictionary.FindByName(PID_KEY);
if (pidRef == 0)
{
thisPid = 0;
}
else
{
- thisPid = *reinterpret_cast<pid_t*>(pidRef->Value ().data ());
+ thisPid = *reinterpret_cast<pid_t*>(pidRef->Value().data());
}
Keychain thisKeychain = 0;
-
- // make sure we have a database identifier
- if (dictionary.FindByName (SSUID_KEY) != 0)
- {
- DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary);
- thisKeychain = globals().storageManager.keychain (dbid);
- }
-
- const NameValuePair* item = dictionary.FindByName (ITEM_KEY);
Item thisItem;
+ list<CallbackInfo> eventCallbacks;
- if (item && thisKeychain)
- {
- PrimaryKey pk(item->Value ());
- thisItem = thisKeychain->item(pk);
- }
+ {
+ // Lock the global API lock before doing stuff with StorageManager.
+ StLock<Mutex> _(globals().apiLock);
+
+ // make sure we have a database identifier
+ if (dictionary.FindByName (SSUID_KEY) != 0)
+ {
+ DLDbIdentifier dbid = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary (dictionary);
+ thisKeychain = globals().storageManager.keychain(dbid);
+ }
+
+ const NameValuePair* item = dictionary.FindByName(ITEM_KEY);
+
+ if (item && thisKeychain)
+ {
+ PrimaryKey pk(item->Value());
+ thisItem = thisKeychain->item(pk);
+ }
+
+ // Deal with events that we care about ourselves first.
+ if (thisEvent == kSecDeleteEvent && thisKeychain.get() && thisItem.get())
+ thisKeychain->didDeleteItem(thisItem.get());
+
+ eventCallbacks = CCallbackMgr::Instance().mEventCallbacks;
+ // We can safely release the global API lock now since thisKeychain and thisItem
+ // are CFRetained and will be until they go out of scope.
+ }
// Notify our process of this event.
- CCallbackMgr::AlertClients(thisEvent, thisPid, thisKeychain, thisItem);
+ CCallbackMgr::AlertClients(eventCallbacks, thisEvent, thisPid, thisKeychain, thisItem);
}
void Event (Listener::Domain domain, Listener::Event whichEvent, NameValueDictionary &dictionary);
- static void AlertClients( SecKeychainEvent inEvent, pid_t inPid,
- const Keychain& inKeychain, const Item &inItem);
+ static void AlertClients(const list<CallbackInfo> &eventCallbacks, SecKeychainEvent inEvent, pid_t inPid,
+ const Keychain& inKeychain, const Item &inItem);
list<CallbackInfo> mEventCallbacks;
static CCallbackMgr* mCCallbackMgr;
Policy("SecPolicy"),
PolicyCursor("SecPolicySearch"),
Trust("SecTrust"),
- TrustedApplication("SecTrustedApplication")
+ TrustedApplication("SecTrustedApplication"),
+ allocator(CFAllocatorCreate(NULL, &CFClass::allocatorContext))
{
}
//
// CFClass
//
+CFAllocatorContext CFClass::allocatorContext =
+{
+ 0,
+ NULL,
+ NULL, /* retain */
+ NULL, /* release */
+ NULL, /* copyDescription */
+ allocatorAllocate, /* allocate */
+ allocatorReallocate, /* reallocate */
+ allocatorDeallocate, /* deallocate */
+ allocatorPreferredSize /* preferredSize */
+};
+
CFClass::CFClass(const char *name)
{
// initialize the CFRuntimeClass structure
className = name;
init = NULL;
copy = NULL;
- finalize = finalizeType;
+ finalize = NULL;
equal = equalType;
hash = hashType;
copyFormattingDesc = copyFormattingDescType;
assert(typeID != _kCFRuntimeNotATypeID);
}
-void
-CFClass::finalizeType(CFTypeRef cf)
-{
- /*
- * Called on a CFRelease of any Sec object: single thread through
- * same lock held by public API calls. This is a recursive lock
- * so it's safe to do this for CF objects allocated and released
- * within the Sec layer.
- */
- StLock<Mutex> _(globals().apiLock);
- SecCFObject *obj = SecCFObject::optional(cf);
- if (!obj->isNew())
- obj->~SecCFObject();
-}
-
Boolean
CFClass::equalType(CFTypeRef cf1, CFTypeRef cf2)
{
{
return SecCFObject::optional(cf)->copyDebugDesc();
}
+
+//
+// CFAllocatorContext callbacks.
+//
+void *
+CFClass::allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info)
+{
+ return malloc(allocSize);
+}
+
+void *
+CFClass::allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info)
+{
+ return realloc(ptr, newsize);
+}
+
+void
+CFClass::allocatorDeallocate(void *ptr, void *info)
+{
+ /*
+ * Called on a CFRelease of any Sec object: single thread through
+ * same lock held by public API calls. This is a recursive lock
+ * so it's safe to do this for CF objects allocated and released
+ * within the Sec layer.
+ */
+ StLock<Mutex> _(globals().apiLock);
+ CFTypeRef cf = reinterpret_cast<CFTypeRef>(reinterpret_cast<intptr_t>(ptr) + sizeof(CFAllocatorRef));
+ CFIndex rc = CFGetRetainCount(cf);
+ if (rc == 1)
+ {
+ SecCFObject *obj = SecCFObject::optional(cf);
+ if (!obj->isNew())
+ obj->~SecCFObject();
+ free(ptr);
+ }
+ else if (rc > 1)
+ {
+ // Since CFRelease did nothing other than call CFAllocatorDeallocate() followed
+ // by a CFRelease() of the allocator we need to counter that here.
+ CFRetain(CFGetAllocator(cf));
+ CFRelease(cf);
+ }
+ else
+ {
+ // Something bad happened we're screwed
+ }
+}
+
+CFIndex
+CFClass::allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info)
+{
+ return size;
+}
CFClass(const char *name);
private:
- static void finalizeType(CFTypeRef cf);
static Boolean equalType(CFTypeRef cf1, CFTypeRef cf2);
static CFHashCode hashType(CFTypeRef cf);
static CFStringRef copyFormattingDescType(CFTypeRef cf, CFDictionaryRef dict);
static CFStringRef copyDebugDescType(CFTypeRef cf);
+ // CFAllocatorContext callbacks.
+ static void *allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info);
+ static void *allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);
+ static void allocatorDeallocate(void *ptr, void *info);
+ static CFIndex allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info);
+
public:
CFTypeID typeID;
+ static CFAllocatorContext allocatorContext;
};
/* Singleton that registers all the CFClass instances with the CFRuntime.
CFClass PolicyCursor;
CFClass Trust;
CFClass TrustedApplication;
+
+ CFAllocatorRef allocator;
};
extern SecCFTypes &gTypes();
void *
SecCFObject::allocate(size_t size, CFTypeID typeID) throw(std::bad_alloc)
{
- void *p = const_cast<void *>(_CFRuntimeCreateInstance(NULL, typeID,
+ void *p = const_cast<void *>(_CFRuntimeCreateInstance(gTypes().allocator, typeID,
size + kAlignedRuntimeSize - sizeof(CFRuntimeBase), NULL));
if (p == NULL)
throw std::bad_alloc();
<plist version="0.9">
<array>
<string>/Applications/Mail.app</string>
+ <string>/Applications/System Preferences.app</string>
+ <string>/Applications/iCal.app</string>
<string>/Applications/iChat.app</string>
+ <string>/Applications/iMovie.app</string>
+ <string>/Applications/iPhoto.app</string>
<string>/Applications/iSync.app</string>
- <string>/Applications/System Preferences.app</string>
- <string>/System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app</string>
+ <string>/Applications/iTunes.app</string>
+ <string>/System/Library/CoreServices/Finder.app</string>
+ <string>/System/Library/CoreServices/MirrorAgent.app</string>
<string>/System/Library/CoreServices/SyncServer.app</string>
+ <string>/System/Library/PrivateFrameworks/InstantMessage.framework/iChatAgent.app</string>
</array>
</plist>
UInt32 moved,
OSStatus stat)
{
- sslLogRecordIo("===%s: req %4lu moved %4lu status %ld\n",
+ sslLogRecordIo("===%s: req %4lu moved %4lu status %ld",
op, req, moved, stat);
}
#else
SSLRecord rec;
UInt32 dataLen, processed;
+ sslLogRecordIo("SSLWrite top");
if((ctx == NULL) || (bytesWritten == NULL)) {
return paramErr;
}
UInt32 bufSize, remaining, count;
SSLRecord rec;
+ sslLogRecordIo("SSLRead top");
if((ctx == NULL) || (processed == NULL)) {
return paramErr;
}
bufSize = dataLength;
*processed = 0; /* Initialize in case we return with errSSLWouldBlock */
+readRetry:
/* first handle cases in which we know we're finished */
switch(ctx->state) {
case SSL_HdskStateGracefulClose:
err = noErr;
exit:
+ /* test for renegotiate: loop until something happens */
+ if((err == noErr) && (*processed == 0)) {
+ sslLogNegotiateDebug("SSLRead recursion");
+ goto readRetry;
+ }
/* shut down on serious errors */
switch(err) {
case noErr:
{
OSStatus err = noErr;
+ sslHdskStateDebug("SSLClose");
if(ctx == NULL) {
return paramErr;
}
+++ /dev/null
-michael.pbxuser
-perry.pbxuser
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\"";
LIBRARY_STYLE = STATIC;
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DVDADER_RULES";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
};
01FA8039FFF2B54C11CD283A = {
children = (
+ B6F3F06205E5C8DD003E48D8,
014259A8001645E911CD296C,
01FA804DFFF2B54C11CD283A,
01FA804EFFF2B54C11CD283A,
01FA8900FFF2BC5611CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/derived_src\"";
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DDatabase=XDatabase";
- OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient";
+ OTHER_LDFLAGS = "-twolevel_namespace -lSecurityAgentClient -lbsm";
OTHER_REZFLAGS = "";
PRODUCT_NAME = SecurityServer;
REZ_EXECUTABLE = YES;
40ACEF4D0462F6EC0035B857,
40ACEF510462F6FF0035B857,
C2C11915047187E800CA2E77,
+ B6F3F06605E5C926003E48D8,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
40ACEF4C0462F6EC0035B857,
40ACEF500462F6FF0035B857,
C2C11914047187E800CA2E77,
+ B6F3F06505E5C926003E48D8,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
01FA890AFFF2BCA811CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
F5DDE3AE00B3358F01CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(BUILT_PRODUCTS_DIR)/derived_src\"";
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/include\"";
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
325EAA2800D6B08805CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
3290382100D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
3290382700D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
3290382D00D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
3290383300D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 164.1;
+ CURRENT_PROJECT_VERSION = 176;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_LDFLAGS = "-bundle -undefined error";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.2</string>
+ <string>2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>164.1</string>
+ <string>176</string>
</dict>
</plist>
";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 164.1;
+ DYLIB_CURRENT_VERSION = 176;
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
OTHER_CFLAGS = "";
//9D2
//9D3
//9D4
+//B60
+//B61
+//B62
+//B63
+//B64
+ B6F3F06205E5C8DD003E48D8 = {
+ children = (
+ B6F3F06305E5C926003E48D8,
+ B6F3F06405E5C926003E48D8,
+ );
+ isa = PBXGroup;
+ name = "Common Criteria";
+ refType = 4;
+ };
+ B6F3F06305E5C926003E48D8 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = ccaudit.cpp;
+ refType = 4;
+ };
+ B6F3F06405E5C926003E48D8 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ path = ccaudit.h;
+ refType = 4;
+ };
+ B6F3F06505E5C926003E48D8 = {
+ fileRef = B6F3F06305E5C926003E48D8;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ B6F3F06605E5C926003E48D8 = {
+ fileRef = B6F3F06405E5C926003E48D8;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+//B60
+//B61
+//B62
+//B63
+//B64
//BD0
//BD1
//BD2
namespace Authorization {
-
//
// Errors to be thrown
//
#include <sys/stat.h>
#include <sys/types.h>
-
class AuthorizationToken;
using Authorization::AuthorizationDBPlist;
#include <grp.h>
#include <unistd.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+#include "ccaudit.h"
//
// Rule class
CFStringRef RuleImpl::kRuleDelegateID = CFSTR(kAuthorizationRightRule);
CFStringRef RuleImpl::kRuleMechanismsID = CFSTR(kAuthorizationRuleClassMechanisms);
+
string
RuleImpl::Attribute::getString(CFDictionaryRef config, CFStringRef key, bool required = false, char *defaultValue = NULL)
{
AuthItemSet context = auth.infoSet();
AuthItemSet hints = environment;
+ CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
+
AuthorizationResult result = kAuthorizationResultAllow;
vector<string>::const_iterator currentMechanism = mEvalDef.begin();
Credential newCredential(username, password, true); // create a new shared credential
if (newCredential->isValid())
+ {
Syslog::info("authinternal authenticated user %s (uid %lu) for right %s.", newCredential->username().c_str(), newCredential->uid(), inRight->name());
+ auditrec.submit(AUE_ssauthint, CommonCriteria::errNone, inRight->name());
+ }
else
+ {
// we can't be sure that the user actually exists so inhibit logging of uid
Syslog::error("authinternal failed to authenticate user %s for right %s.", newCredential->username().c_str(), inRight->name());
-
+
+ auditrec.submit(AUE_ssauthint, CommonCriteria::errInvalidCredential, inRight->name());
+ }
+
if (newCredential->isValid())
{
outCredentials.clear(); // only keep last one
// fetch context and construct a credential to be tested
AuthItemSet inContext = auth.infoSet();
CredentialSet newCredentials = makeCredentials(inContext);
+ // clear context after extracting credentials
+ auth.clearInfoSet();
for (CredentialSet::const_iterator it = newCredentials.begin(); it != newCredentials.end(); ++it)
{
const Credential& newCredential = *it;
+ CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
// @@@ we log the uid a process was running under when it created the authref, which is misleading in the case of loginwindow
if (newCredential->isValid())
+ {
Syslog::info("uid %lu succeeded authenticating as user %s (uid %lu) for right %s.", auth.creatorUid(), newCredential->username().c_str(), newCredential->uid(), inRight->name());
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name());
+ }
else
+ {
// we can't be sure that the user actually exists so inhibit logging of uid
Syslog::error("uid %lu failed to authenticate as user %s for right %s.", auth.creatorUid(), newCredential->username().c_str(), inRight->name());
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name());
+ }
if (!newCredential->isValid())
{
{
// whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent
credentials.erase(newCredential); credentials.insert(newCredential);
+ // use valid credential to set context info
+ auth.setCredentialInfo(newCredential);
secdebug("SSevalMech", "added valid credential for user %s", newCredential->username().c_str());
status = errAuthorizationSuccess;
break;
}
else
+ {
reason = SecurityAgent::userNotInGroup; //unacceptableUser; // userNotInGroup
+ // don't audit: we denied on the basis of something
+ // other than a bad user or password
+ }
}
if (status == errAuthorizationSuccess)
else
if ((status == errAuthorizationCanceled) ||
(status == errAuthorizationInternal))
- break;
+ {
+ auth.clearInfoSet();
+ break;
+ }
}
// If we fell out of the loop because of too many tries, notify user
AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
evaluateMechanism(inRight, environmentToClient, auth, credentials);
+ auth.clearInfoSet();
}
Process &cltProc = Server::active().connection().process;
Credential newCredential;
// @@@ Keep the default reason the same, so the agent only gets userNotInGroup or invalidPassphrase
SecurityAgent::Reason reason = SecurityAgent::userNotInGroup;
+
+ CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
+
// @@@ Hardcoded 3 tries to avoid infinite loops.
for (uint32_t tryCount = 0; tryCount < mTries; ++tryCount)
{
// Now we have successfully obtained a credential we need to make sure it authorizes the requested right
if (!newCredential->isValid())
+ {
reason = SecurityAgent::invalidPassphrase;
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, inRight->name());
+ }
else {
status = evaluateCredentialForRight(inRight, inRule, environmentToClient, now, newCredential, true);
if (status == errAuthorizationSuccess)
// add credential to authinfo
auth.setCredentialInfo(newCredential);
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, inRight->name());
return errAuthorizationSuccess;
}
else if (status != errAuthorizationDenied)
+ {
+ if (status == errAuthorizationCanceled)
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errUserCanceled, inRight->name());
+ // else don't audit--error not due to bad
+ // username or password
return status;
+ }
}
reason = SecurityAgent::userNotInGroup;
}
query.cancel(SecurityAgent::tooManyTries);
+
+ auditrec.submit(AUE_ssauthorize, CommonCriteria::errTooManyTries, inRight->name());
return errAuthorizationDenied;
}
map<string,string> localizedPrompts() const { return mLocalizedPrompts; }
-
// parsed attributes
private:
enum Type
<key>rule</key>
<string>appserver-admin</string>
</dict>
+ <key>com.apple.desktopservices</key>
+ <dict>
+ <key>class</key>
+ <string>user</string>
+ <key>comment</key>
+ <string>authorize privileged file operations from the finder</string>
+ <key>group</key>
+ <string>admin</string>
+ <key>mechanisms</key>
+ <array>
+ <string>builtin:authenticate</string>
+ </array>
+ <key>shared</key>
+ <false/>
+ <key>timeout</key>
+ <integer>0</integer>
+ </dict>
<key>com.apple.appserver.privilege.user</key>
<dict>
<key>class</key>
//
// Create an authorization token.
//
-AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken)
+AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken)
: session(ssn), mBaseCreds(base), mTransferCount(INT_MAX),
- mCreatorUid(securityToken.val[0]),
+ mCreatorUid(auditToken.val[1]),
+ mCreatorGid(auditToken.val[2]),
mCreatorCode(Server::connection().process.clientCode()),
- mCreatorPid(Server::connection().process.pid())
+ mCreatorPid(Server::connection().process.pid()),
+ mCreatorAuditToken(auditToken)
{
// generate our (random) handle
Server::active().random(mHandle);
setInfoSet(dstInfoSet);
}
+void
+AuthorizationToken::clearInfoSet()
+{
+ AuthItemSet dstInfoSet;
+ secdebug("SSauth", "Authorization %p clearing context", this);
+ setInfoSet(dstInfoSet);
+}
+
class AuthorizationToken {
public:
- AuthorizationToken(Session &ssn, const CredentialSet &base, const security_token_t &securityToken);
+ AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken);
~AuthorizationToken();
Session &session;
bool mayInternalize(Process &proc, bool countIt = true);
uid_t creatorUid() const { return mCreatorUid; }
+ uid_t creatorGid() const { return mCreatorGid; }
CodeSigning::OSXCode *creatorCode() const { return mCreatorCode; }
pid_t creatorPid() const { return mCreatorPid; }
+ audit_token_t creatorAuditToken() const {return mCreatorAuditToken; }
+
AuthItemSet infoSet(AuthorizationString tag = NULL);
void setInfoSet(AuthItemSet &newInfoSet);
void setCredentialInfo(const Credential &inCred);
+ void clearInfoSet();
public:
static AuthorizationToken &find(const AuthorizationBlob &blob);
ProcessSet mUsingProcesses; // set of process objects using this token
uid_t mCreatorUid; // Uid of proccess that created this authorization
+ gid_t mCreatorGid; // Gid of proccess that created this authorization
RefPointer<OSXCode> mCreatorCode; // code id of creator
pid_t mCreatorPid; // Pid of processs that created this authorization
+ audit_token_t mCreatorAuditToken; // Audit token of the process that created this authorization
+
AuthItemSet mInfoSet; // Side band info gathered from evaluations in this session
private:
#include "notifications.h"
#include "ucsp.h"
#include <mach/mach_error.h>
+#include <bsm/audit.h>
+#include <bsm/audit_kevents.h>
+#include <bsm/audit_record.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/libbsm.h>
+#include "ccaudit.h"
using namespace MachPlusPlus;
-
//
// Construct the server object
//
mAuthority(authority),
mCodeSignatures(signatures)
{
+
+ initAudit();
+
// engage the subsidiary port handler for sleep notifications
add(sleepWatcher);
}
{
MachServer::run(0x10000,
MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) |
- MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER));
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT));
}
// Everything at and below that level is constructed. This is straight-forward except
// in the case of session re-initialization (see below).
//
+// audit_token_t.val[1] is the EUID, audit_token_t.val[2] is the EGID.
+//
void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort,
- const security_token_t &securityToken, const ClientSetupInfo *info, const char *identity)
+ const audit_token_t &auditToken,
+ const ClientSetupInfo *info, const char *identity)
{
// first, make or find the process based on task port
StLock<Mutex> _(lock);
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
assert(info && identity);
proc = new Process(servicePort, taskPort, info, identity,
- securityToken.val[0], securityToken.val[1]);
+ auditToken.val[1], auditToken.val[2]);
notifyIfDead(taskPort);
}
Session::lockAllDatabases(true);
}
+void Server::initAudit(void)
+{
+ secdebug("SS", "initializing Common Criteria auditing");
+ mAudit.auditId(geteuid());
+ // Set the class mask so only the audit records we submit are written.
+ mAudit.eventMask().set(AUE_NULL, AUE_NULL);
+ mAudit.terminalId().set();
+ // XXX If we use SS session IDs instead, get the RootSession ID
+ mAudit.sessionId(getpid());
+ mAudit.registerSession();
+}
//
// Return the primary Cryptographic Service Provider.
#include "xdatabase.h"
#include "authority.h"
#include <map>
+#include "ccaudit.h"
#define EQUIVALENCEDBPATH "/var/db/CodeEquivalenceDatabase"
connectNewThread
};
void setupConnection(ConnectLevel type, Port servicePort, Port replyPort, Port taskPort,
- const security_token_t &securityToken,
- const ClientSetupInfo *info = NULL, const char *executablePath = NULL);
+ const audit_token_t &auditToken,
+ const ClientSetupInfo *info = NULL, const char *executablePath = NULL);
void endConnection(Port replyPort);
void systemWillSleep();
};
SleepWatcher sleepWatcher;
-
+
+ void initAudit(void);
+
private:
Mutex lock; // master lock
Authority &mAuthority;
CodeSignatures &mCodeSignatures;
+
+ // Per-process audit initialization.
+ CommonCriteria::AuditSession mAudit;
};
#endif //_H_SERVER
const AuthItemSet &environment,
AuthorizationFlags flags,
AuthorizationBlob &newHandle,
- const security_token_t &securityToken)
+ const audit_token_t &auditToken)
{
// invoke the authorization computation engine
CredentialSet resultCreds;
// this will acquire mLock, so we delay acquiring it
- auto_ptr<AuthorizationToken> auth(new AuthorizationToken(*this, resultCreds, securityToken));
+ auto_ptr<AuthorizationToken> auth(new AuthorizationToken(*this, resultCreds, auditToken));
// Make a copy of the mSessionCreds
CredentialSet sessionCreds;
const CredentialSet &authCredentials() const { return mSessionCreds; }
OSStatus authCreate(const AuthItemSet &rights, const AuthItemSet &environment,
- AuthorizationFlags flags, AuthorizationBlob &newHandle, const security_token_t &securityToken);
+ AuthorizationFlags flags, AuthorizationBlob &newHandle, const audit_token_t &auditToken);
void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags);
OSStatus authGetRights(const AuthorizationBlob &auth,
const AuthItemSet &requestedRights, const AuthItemSet &environment,
//
// Bracket Macros
//
-#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, security_token_t securityToken, \
+#define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, audit_token_t auditToken, \
CSSM_RETURN *rcode
#define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize
{
BEGIN_IPCN
Server::active().setupConnection(Server::connectNewProcess, servicePort, replyPort,
- taskPort, securityToken, &info, identity);
+ taskPort, auditToken, &info, identity);
END_IPCN(CSSM)
return KERN_SUCCESS;
}
try {
Session *session = new DynamicSession(TaskPort(taskPort).bootstrap());
Server::active().setupConnection(Server::connectNewSession, session->servicePort(), replyPort,
- taskPort, securityToken, &info, identity);
+ taskPort, auditToken, &info, identity);
*newServicePort = session->servicePort();
} catch (const MachPlusPlus::Error &err) {
switch (err.error) {
{
BEGIN_IPCN
Server::active().setupConnection(Server::connectNewThread, servicePort, replyPort,
- taskPort, securityToken);
+ taskPort, auditToken);
END_IPCN(CSSM)
return KERN_SUCCESS;
}
Authorization::AuthItemSet rights(inRights), environment(inEnvironment);
*rcode = connection.process.session.authCreate(rights, environment,
- flags, *authorization, securityToken);
+ flags, *authorization, auditToken);
END_IPC(CSSM)
}
//
#define UCSP_PORTS requestport sport: mach_port_t; \
replyport rport: mach_port_make_send_t; \
- serversectoken sourceSecurity: security_token_t; \
+ serveraudittoken sourceAudit: audit_token_t; \
out rcode: CSSM_RETURN
#define IN_CONTEXT in context: Context; in contextBase: BasePointer; in attrs: ContextAttributes
#define IN_BLOB(name,type) in name: type##Blob; in name##Base: type##Ptr
+++ /dev/null
-cdsa_pluginlib?Data
+++ /dev/null
-cdsa_utilities?Data
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
+ * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
+ * specific language governing rights and limitations under the License.
+ */
+
+
+#include <strings.h> // bcopy()
+#include <unistd.h> // gethostname()
+#include <netdb.h> // gethostbyname()
+#include <sys/types.h> // inet_addr()
+#include <sys/socket.h> // inet_addr()
+#include <netinet/in.h> // inet_addr()
+#include <arpa/inet.h> // inet_addr()
+#include <errno.h>
+#include "utilities.h"
+#include <Security/logging.h>
+#include <bsm/libbsm.h>
+#include "ccaudit.h"
+
+namespace Security
+{
+namespace CommonCriteria
+{
+
+void TerminalId::set(void)
+{
+ if (audit_set_terminal_id(&mTid) != kAUNoErr)
+ {
+ // If we start seeing the syslog too often, change to secdebug()
+ Syslog::warning("setting terminal ID info failed; using defaults");
+ mTid.port = 0;
+ mTid.machine = 0;
+ }
+}
+
+void AuditSession::registerSession(void)
+{
+ auditinfo_t auinfo;
+
+ auinfo.ai_auid = mAuditId;
+ auinfo.ai_asid = mSessionId;
+ bcopy(&mTerminalId.get(), &(auinfo.ai_termid), sizeof(auinfo.ai_termid));
+ bcopy(&mEventMask.get(), &(auinfo.ai_mask), sizeof(auinfo.ai_mask));
+
+ if (setaudit(&auinfo) != 0)
+ {
+ if (errno == ENOTSUP)
+ {
+ Syslog::notice("Attempted to initialize auditing, but this kernel that does not support auditing");
+ return;
+ }
+ Syslog::notice("Could not initialize auditing; continuing");
+ }
+}
+
+void AuditRecord::submit(const short event_code, const int returnCode,
+ const char *msg)
+{
+ // If we're not auditing, do nothing
+ if (au_get_state() == AUC_NOAUDIT)
+ return;
+
+ // XXX make this a secdebug, then enable it
+ // Syslog::notice("Submitting authorization audit record");
+
+ int ret = kAUNoErr;
+
+ // XXX/gh 3574731: Fix BSM SPI so the const_cast<>s aren't necessary
+ if (returnCode == 0)
+ {
+ token_t *tok = NULL;
+
+ if (msg)
+ tok = au_to_text(const_cast<char *>(msg));
+ ret = audit_write_success(event_code, const_cast<token_t *>(tok),
+ mAuditId, mEUid, mEGid, mRUid, mRGid,
+ mPid, mSessionId,
+ const_cast<au_tid_t *>(&(mTerminalId.get())));
+ }
+ else
+ {
+ ret = audit_write_failure(event_code, const_cast<char *>(msg),
+ returnCode, mAuditId, mEUid, mEGid,
+ mRUid, mRGid, mPid, mSessionId,
+ const_cast<au_tid_t *>(&(mTerminalId.get())));
+ }
+ if (ret != kAUNoErr)
+ MacOSError::throwMe(ret);
+}
+
+
+} // end namespace CommonCriteria
+} // end namespace Security
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
+ * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
+ * specific language governing rights and limitations under the License.
+ */
+
+
+#ifndef _H_CCAUDIT
+#define _H_CCAUDIT
+
+#include <Security/utility_config.h>
+#include <bsm/audit.h>
+
+namespace Security
+{
+
+namespace CommonCriteria
+{
+
+// for Tiger, this should be incorporated into Security's OSStatus range
+enum ExternalErrors
+{
+ errNone = 0,
+ errInvalidCredential = 1111, // try to make easier to find in log
+ errUserCanceled,
+ errTooManyTries,
+ errEndOfExternalErrors // sentry/placeholder
+};
+
+class AuditMask
+{
+ public:
+ AuditMask() { }
+ AuditMask(const AuditMask &am) { set(am.get()); }
+ AuditMask(const au_mask_t &am) { set(am); }
+ ~AuditMask() { }
+
+ void set(const au_mask_t &am) { set(am.am_success, am.am_failure); }
+ void set(unsigned int s, unsigned int f) { mMask.am_success = s; mMask.am_failure = f; }
+ const au_mask_t &get(void) const { return mMask; }
+
+ private:
+ au_mask_t mMask;
+};
+
+// For the most part, we won't have a machine ID to initialize the
+// au_tid_t's machine field. There's no machine ID in the audit token,
+// for example, since MIG is localhost-only.
+class TerminalId
+{
+ public:
+ TerminalId() { }
+ TerminalId(const TerminalId &t) { set(t.get()); }
+ TerminalId(const au_tid_t &tid) { set(tid); }
+ TerminalId(dev_t p, u_int32_t m) { port(p); machine(m); }
+ ~TerminalId() { }
+
+ void set(void); // set using localhost
+ void set(const au_tid_t &tid) { port(tid.port); machine(tid.machine); }
+ void port(dev_t p) { mTid.port = p; }
+ void machine(u_int32_t m) { mTid.machine = m; }
+ const au_tid_t &get(void) const { return mTid; }
+
+ private:
+ au_tid_t mTid;
+};
+
+// audit session state for the current process; only used by Server
+class AuditSession
+{
+ public:
+ AuditSession() { }
+ AuditSession(au_id_t auid, AuditMask &mask, au_asid_t sid,
+ TerminalId &tid)
+ : mAuditId(auid), mEventMask(mask), mTerminalId(tid),
+ mSessionId(sid) { }
+ ~AuditSession() { }
+
+ // set audit info for this process in kernel
+ void registerSession(void);
+
+ void auditId(au_id_t auid) { mAuditId = auid; }
+ void eventMask(AuditMask &mask) { mEventMask = mask; }
+ void terminalId(TerminalId &tid) { mTerminalId = tid; }
+ void sessionId(au_asid_t sid) { mSessionId = sid; }
+
+ au_id_t auditId(void) { return mAuditId; }
+ AuditMask &eventMask(void) { return mEventMask; }
+ TerminalId &terminalId(void) { return mTerminalId; }
+ au_asid_t sessionId(void) { return mSessionId; }
+
+ private:
+ au_id_t mAuditId;
+ AuditMask mEventMask;
+ TerminalId mTerminalId;
+ au_asid_t mSessionId;
+};
+
+//
+// For submitting audit records. Not general-purpose: no ability to
+// submit arbitrary BSM tokens, for example. However, the SecurityServer
+// has only limited auditing requirements under Common Criteria.
+//
+class AuditRecord
+{
+ public:
+ AuditRecord(const audit_token_t &auditToken)
+ : mAuditId(auditToken.val[0]),
+ mRUid(auditToken.val[3]),
+ mRGid(auditToken.val[4]),
+ mEUid(auditToken.val[1]),
+ mEGid(auditToken.val[2]),
+ mPid(auditToken.val[5]),
+ mSessionId(auditToken.val[6]),
+ mTerminalId(auditToken.val[7], 0) { }
+ ~AuditRecord() { }
+
+ // returnCode == 0 --> success; nonzero returnCode --> failure
+ void submit(const short event_code, const int returnCode,
+ const char *msg = NULL);
+
+ private:
+ au_id_t mAuditId;
+ uid_t mRUid;
+ gid_t mRGid;
+ uid_t mEUid;
+ gid_t mEGid;
+ pid_t mPid;
+ au_asid_t mSessionId;
+ TerminalId mTerminalId;
+};
+
+} // end namespace CommonCriteria
+
+} // end namespace Security
+
+#endif // _H_CCAUDIT
const _Tp *_M_finish;
};
-
} // end namespace Security
+++ /dev/null
-PBUserInfo
-mds?Data
unsigned long fPID;
unsigned long fPort;
unsigned long fIPAddress;
+ mach_msg_audit_trailer_t fTail;
sObject obj[ 10 ];
char data[ 1 ];
} sComData;
unsigned long fPort;
sObject obj[ 10 ];
char fData[ kIPCMsgLen ];
- mach_msg_security_trailer_t fTail;
+ mach_msg_audit_trailer_t fTail; // this is the largest trailer struct
+ // we have the bucket large enough to receive it
} sIPCMsg;
typedef enum {
msg->obj[0].length = curr;
msg->fHeader.msgh_bits = MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND );
- msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_security_trailer_t );
+ msg->fHeader.msgh_size = sizeof( sIPCMsg ) - sizeof( mach_msg_audit_trailer_t );
msg->fHeader.msgh_id = kCheckUserNameAndPassword;
msg->fHeader.msgh_remote_port = serverPort;
msg->fHeader.msgh_local_port = replyPort;
// get reply
memset( msg, 0, kIPCMsgLen );
- result = mach_msg( (mach_msg_header_t *)msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT,
+ result = mach_msg( (mach_msg_header_t *)msg,
+ MACH_RCV_MSG | MACH_RCV_TIMEOUT |
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0),
0, kIPCMsgSize, replyPort, 300 * 1000, MACH_PORT_NULL );
if ( result != MACH_MSG_SUCCESS ) {
SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library
KEYCHAINS_DIR=$(SYSTEM_LIBRARY_DIR)/Keychains
-X509KEYCHAINS=X509Anchors X509Certificates
+ANCHORS_DIR=$(KEYCHAINS_DIR)/Anchors
+CERTIFICATES_DIR=$(KEYCHAINS_DIR)/Certificates
#
# world-writable directory we need to create for CRL cache
# Install
#
install:
- if [ ! -d $(KEYCHAINS_DIR) ]; then \
- mkdir -p $(KEYCHAINS_DIR); \
- chown root.admin $(KEYCHAINS_DIR); \
- chmod 755 $(KEYCHAINS_DIR); \
- fi
- cd $(KEYCHAINS_SRC); cp $(X509KEYCHAINS) $(KEYCHAINS_DIR)
- cd $(KEYCHAINS_DIR); \
- chown root.admin $(X509KEYCHAINS); \
- chmod 664 $(X509KEYCHAINS); \
- ls -l $(X509KEYCHAINS)
+ for d in "$(KEYCHAINS_DIR)" "$(ANCHORS_DIR)" "$(CERTIFICATES_DIR)"; do \
+ if [ ! -d "$${d}" ]; then \
+ mkdir -p "$${d}"; \
+ chown root:admin "$${d}"; \
+ chmod 755 "$${d}"; \
+ fi; \
+ done; \
+ find "$(KEYCHAINS_SRC)/roots" -maxdepth 1 -a -type f -exec cp {} "$(ANCHORS_DIR)" \; ; \
+ find "$(KEYCHAINS_SRC)/certs" -maxdepth 1 -a -type f -exec cp {} "$(CERTIFICATES_DIR)" \; ; \
+ chown root:admin "$(ANCHORS_DIR)/"*; \
+ chmod 664 "$(ANCHORS_DIR)/"*; \
+ chown root:admin "$(CERTIFICATES_DIR)/"*; \
+ chmod 664 "$(CERTIFICATES_DIR)/"*; \
if [ ! -d $(CRL_CACHE_DIR) ]; then \
mkdir -p $(CRL_CACHE_DIR); \
- chown root.wheel $(CRL_CACHE_DIR); \
+ chown root:wheel $(CRL_CACHE_DIR); \
chmod 777 $(CRL_CACHE_DIR); \
fi
+++ /dev/null
-#! /bin/csh -f
-#
-# Build a keychain out of roots or certs.
-#
-set prog=$0
-if ( $#argv != 2 ) then
- echo usage: ${prog:t} dbfile certsdir
- echo dbfile must NOT exist.
- exit(1)
-endif
-#
-# Our job is to cook up a list of files in certsdir, not including
-# the CVS directory.
-#
-set cwd=`pwd`
-set dbfile=$cwd/$argv[1]
-set certsdir=$argv[2]
-if ( -e $dbfile ) then
- echo I insist that you delete $argv[1] manually.
- exit(1)
-endif
-#
-set cmd="./makecerts $dbfile $certsdir/[a-zABD-Z0-9]* $certsdir/C[a-zA-UW-Z0-9]*"
-$cmd || exit(1)
+++ /dev/null
-#!/usr/bin/perl
-#
-# Use to gather certificates into specified keychain.
-#
-$numFiles = $#ARGV;
-if($numFiles < 1) {
- print "usage: makecerts keychainfile cert...\n";
- die;
-}
-$dbname = $ARGV[0];
-
-my $count = 0;
-my $created;
-foreach $argnum (1 .. $numFiles) {
- $thisCert = $ARGV[$argnum];
- my @cmd = ("certtool", "i", $thisCert, "k=$dbname", "d");
- do { push @cmd, "c"; $created = 1; } unless $created;
- print "$thisCert ";
- die if system @cmd;
- $count++;
-}
-
-print "$count certificates placed into $dbname\n";
-exit 0;
+++ /dev/null
-#!/usr/bin/perl
-#
-#
-#
-use strict;
-
-my $dbname = "X509Anchors";
-
-my $count = 0;
-my $created;
-for my $file (@ARGV) {
- my @cmd = ("certtool", "i", $file, "k=$dbname", "d");
- do { push @cmd, "c"; $created = 1; } unless $created;
- print "$file ";
- die if system @cmd;
- $count++;
-}
-
-print "$count certificates placed into $dbname\n";
-exit 0;
--- /dev/null
+#!/bin/sh
+
+# Create keychains if not there already
+if [ ! -f "$targetdisk/System/Library/Keychains/X509Anchors" ]; then
+ "$targetdisk/usr/bin/security" create-keychain -p X509Anchors "$targetdisk/System/Library/Keychains/X509Anchors"
+fi
+if [ ! -f "$targetdisk/System/Library/Keychains/X509Certificates" ]; then
+ "$targetdisk/usr/bin/security" create-keychain -p X509Certificates "$targetdisk/System/Library/Keychains/X509Certificates"
+fi
+
+# Add all anchors
+cd "$targetdisk/System/Library/Keychains/Anchors/"
+"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Anchors" *
+
+# Add all intermediates
+cd "$targetdisk/System/Library/Keychains/Certificates/"
+"$targetdisk/usr/bin/security" add-certificate -k "$targetdisk/System/Library/Keychains/X509Certificates" *
+
+# we might want to delete the raw certificate files, in the interest of cruft cleanup
+#rm -rf "$targetdisk/System/Library/Keychains/Anchors"
+#rm -rf "$targetdisk/System/Library/Keychains/Certificates"