/usr/bin/crlrefresh
/usr/bin/security
/usr/bin/smbutil
+/usr/libexec/airportd
/usr/local/bin/cmsutil
/usr/sbin/configd
/usr/sbin/pppd
CURRENT_PROJECT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = "/usr/local/SecurityPieces/Frameworks /usr/local/SecurityPieces/Components/securityd $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
INSTALL_PATH = /usr/sbin;
- OPT_CPPXFLAGS = "$(OPT_CXFLAGS) -fno-enforce-eh-specs -fno-implement-inlines -fcoalesce-templates";
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
- OPT_INLINEXFLAGS = " -finline-functions --param max-inline-insns-single=150 --param max-inline-insns-auto=150 --param max-inline-insns=300 --param min-inline-insns=90";
+ OPT_INLINEXFLAGS = "-finline-functions";
OPT_LDXFLAGS = "-dead_strip";
OPT_LDXNOPIC = ",_nopic";
OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
- OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
- OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
OTHER_LDFLAGS = "-lbsm";
OPT_LDFLAGS = "";
OPT_LDXFLAGS = "";
OPT_LDXNOPIC = "";
- OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O0 -fno-inline";
- OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
};
isa = PBXBuildStyle;
name = "normal with debug";
//
// The default AclSource denies having an ACL at all
//
+AclSource::~AclSource()
+{ /* virtual */ }
+
SecurityServerAcl &AclSource::acl()
{
CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED);
class AclSource {
protected:
AclSource() { }
+ virtual ~AclSource();
public:
virtual SecurityServerAcl &acl(); // defaults to "no ACL; throw exception"
if (mPassphraseCheck)
{
- create("builtin", "confirm-access-password", NULL);
+ create("builtin", "confirm-access-password", noSecuritySession);
CssmAutoData data(Allocator::standard(Allocator::sensitive));
}
else
{
- create("builtin", "confirm-access", NULL);
+ create("builtin", "confirm-access", noSecuritySession);
setInput(hints, context);
invoke();
}
hints.insert(AuthItemRef(AGENT_HINT_APPLICATION_PATH, AuthValueOverlay(strlen(aclPath), const_cast<char*>(aclPath))));
- create("builtin", "code-identity", NULL);
+ create("builtin", "code-identity", noSecuritySession);
setInput(hints, context);
status = invoke();
hints.insert(mClientHints.begin(), mClientHints.end());
- create("builtin", "unlock-keychain", NULL);
+ create("builtin", "unlock-keychain", noSecuritySession);
do
{
switch (initialReason)
{
case SecurityAgent::newDatabase:
- create("builtin", "new-passphrase", NULL);
+ create("builtin", "new-passphrase", noSecuritySession);
break;
case SecurityAgent::changePassphrase:
- create("builtin", "change-passphrase", NULL);
+ create("builtin", "change-passphrase", noSecuritySession);
break;
default:
assert(false);
// CSSM_ATTRIBUTE_ALERT_TITLE (optional alert panel title)
if (false == verify) { // import
- create("builtin", "generic-unlock", NULL);
+ create("builtin", "generic-unlock", noSecuritySession);
} else { // verify passphrase (export)
// new-passphrase-generic works with the pre-4 June 2004 agent;
// generic-new-passphrase is required for the new agent
- create("builtin", "generic-new-passphrase", NULL);
+ create("builtin", "generic-new-passphrase", noSecuritySession);
}
AuthItem *passwordItem;
hints.insert(mClientHints.begin(), mClientHints.end());
- create("builtin", "generic-unlock-kcblob", NULL);
+ create("builtin", "generic-unlock-kcblob", noSecuritySession);
AuthItem *secretItem;
void CodeSignatures::open(const char *path)
{
mDb.open(path, O_RDWR | O_CREAT, 0644);
- mDb.flush();
+ if (mDb)
+ mDb.flush();
IFDUMPING("equiv", debugDump("reopen"));
}
//
bool CodeSignatures::find(Identity &id, uid_t user)
{
+ if (!mDb)
+ return false;
if (id.mState != Identity::untried)
return id.mState == Identity::valid;
try {
void CodeSignatures::makeLink(Identity &id, const string &ident, bool forUser, uid_t user)
{
+ if (!mDb)
+ UnixError::throwMe(ENOENT);
DbKey key('H', id.getHash(mSigner), forUser, user);
if (!mDb.put(key, StringData(ident)))
UnixError::throwMe();
void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool forSystem)
{
+ if (!mDb)
+ UnixError::throwMe(ENOENT);
AclIdentity code(hash, name);
uid_t user = Server::process().uid();
if (forSystem && user) // only root user can remove forSystem links
return false;
}
+ // don't bother the user if the db is MIA
+ if (!mDb) {
+ secdebug("codesign", "database not open; cannot verify");
+ return false;
+ }
+
// ah well. Establish mediator objects for database signature links
AclIdentity aclIdentity(trustedSignature, comment ? comment->interpretedAs<const char>() : NULL);
return false;
}
}
-
+
// ask the user
QueryCodeCheck query;
query.inferHints(process);
if (!how)
how = "dump";
CssmData key, value;
- if (!mDb.first(key, value)) {
- dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
+ if (!mDb) {
+ dump("CODE EQUIVALENTS DATABASE IS NOT OPEN (%s)", how);
} else {
- dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
- do {
- const char *header = key.interpretedAs<const char>();
- size_t headerLength = strlen(header) + 1;
- dump("%s:", header);
- dumpData(key.at(headerLength), key.length() - headerLength);
- dump(" => ");
- dumpData(value);
- dump("\n");
- } while (mDb.next(key, value));
- dump("END DUMP\n");
+ if (!mDb.first(key, value)) {
+ dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
+ } else {
+ dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
+ do {
+ const char *header = key.interpretedAs<const char>();
+ size_t headerLength = strlen(header) + 1;
+ dump("%s:", header);
+ dumpData(key.at(headerLength), key.length() - headerLength);
+ dump(" => ");
+ dumpData(value);
+ dump("\n");
+ } while (mDb.next(key, value));
+ dump("END DUMP\n");
+ }
}
}
// Throws exceptions if decoding fails.
// Memory returned in privateAclBlob is allocated and becomes owned by caller.
//
-void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob)
+void DatabaseCryptoCore::decodeCore(const DbBlob *blob, void **privateAclBlob)
{
assert(mHaveMaster); // must have master key installed
decryptor.mode(CSSM_ALGMODE_CBCPadIV8);
decryptor.padding(CSSM_PADDING_PKCS1);
decryptor.key(mMasterKey);
- CssmData ivd(blob->iv, sizeof(blob->iv)); decryptor.initVector(ivd);
- CssmData cryptoBlob(blob->cryptoBlob(), blob->cryptoBlobLength());
+ CssmData ivd = CssmData::wrap(blob->iv); decryptor.initVector(ivd);
+ CssmData cryptoBlob = CssmData::wrap(blob->cryptoBlob(), blob->cryptoBlobLength());
CssmData decryptedBlob, remData;
decryptor.decrypt(cryptoBlob, decryptedBlob, remData);
DbBlob::PrivateBlob *privateBlob = decryptedBlob.interpretedAs<DbBlob::PrivateBlob>();
// verify signature on the whole blob
CssmData signChunk[] = {
- CssmData(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)),
- CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+ CssmData::wrap(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)),
+ CssmData::wrap(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
};
CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
#if defined(COMPAT_OSX_10_0)
#endif
VerifyMac verifier(Server::csp(), verifyAlgorithm);
verifier.key(mSigningKey);
- verifier.verify(signChunk, 2, CssmData(blob->blobSignature, sizeof(blob->blobSignature)));
+ verifier.verify(signChunk, 2, CssmData::wrap(blob->blobSignature));
// all checks out; start extracting fields
if (privateAclBlob) {
void setup(const DbBlob *blob, const CssmData &passphrase);
void setup(const DbBlob *blob, CssmClient::Key master);
- void decodeCore(DbBlob *blob, void **privateAclBlob = NULL);
+ void decodeCore(const DbBlob *blob, void **privateAclBlob = NULL);
DbBlob *encodeCore(const DbBlob &blobTemplate,
const CssmData &publicAcl, const CssmData &privateAcl) const;
void importSecrets(const DatabaseCryptoCore &src);
namespace Flippers {
-
-//
-// Automatically generated flippers
-//
-#include "flip_gen.cpp"
-
-
//
// The raw byte reversal flipper
//
}
+//
+// Flip a CSSM_DB_ATTRIBUTE_INFO, also very polymorphic
+//
+void flip(CSSM_DB_ATTRIBUTE_INFO &obj)
+{
+ bool flippedAttributeNameFormat = false;
+ // check and see if obj is in host byte order. If not, flip it now
+ if (obj.AttributeNameFormat > CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER)
+ {
+ flip(obj.AttributeNameFormat);
+ flippedAttributeNameFormat = true;
+ }
+
+ switch (obj.AttributeNameFormat)
+ {
+ case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
+ {
+ flip(obj.Label.AttributeID);
+ }
+ break;
+ }
+
+ flip (obj.AttributeFormat);
+
+ if (!flippedAttributeNameFormat)
+ {
+ flip(obj.AttributeNameFormat);
+ }
+
+}
+
+//
+// Automatically generated flippers
+//
+#include "flip_gen.cpp"
+
+
} // end namespace Flippers
// It's a bad idea to try to flip a const, so flag that
//
template <class T>
-inline void flip(const T &)
-{ tryingToFlipAConstWontWork(); }
+inline void flip(const T &);
//
//
void flip(void *addr, size_t size);
+void flip(CSSM_DB_ATTRIBUTE_INFO &obj);
+inline void flip(CssmDbAttributeInfo &obj) { flip(static_cast<CSSM_DB_ATTRIBUTE_INFO &>(obj)); }
//
// Include automatically generated flipper declarations
CSSM_KEY_SIZE/CssmKeySize *
CSSM_KEYHEADER/CssmKey::Header *
CSSM_KEY/CssmKey KeyHeader
-
+CSSM_QUERY/CssmQuery RecordType Conjunctive NumSelectionPredicates QueryLimits QueryFlags
+CSSM_DB_ATTRIBUTE_DATA/CssmDbAttributeData NumberOfValues
+CSSM_DB_RECORD_ATTRIBUTE_DATA/CssmDbRecordAttributeData DataRecordType SemanticInformation NumberOfAttributes
#
# Authorization structures
blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB);
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
- case blob->version_MacOS_10_0:
+ case DbBlob::version_MacOS_10_0:
break;
#endif
- case blob->version_MacOS_10_1:
+ case DbBlob::version_MacOS_10_1:
break;
default:
CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB);
blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB);
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
- case blob->version_MacOS_10_0:
+ case KeyBlob::version_MacOS_10_0:
break;
#endif
- case blob->version_MacOS_10_1:
+ case KeyBlob::version_MacOS_10_1:
break;
default:
CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB);
#include <security_cdsa_utilities/acl_preauth.h>
#include "acl_keychain.h"
-
//
// Local functions of the main program driver
//
// install MDS and initialize the local CSSM
server.loadCssm();
-
+
// okay, we're ready to roll
Syslog::notice("Entering service");
secdebug("SS", "%s initialized", bootstrapName);
#include "server.h"
#include <securityd_client/ucspNotify.h>
-
Listener::ListenerMap Listener::listeners;
Mutex Listener::setLock;
{
secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
this, domain, event, mPort.port(), process.pid());
-
+
// send mach message (via MIG simpleroutine)
if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mPort,
domain, event, data.data(), data.length(),
static AclSource &aclBearer(AclKind kind, CSSM_HANDLE handle);
// Generic version of handle lookup
- template <class Type>
- static RefPointer<Type> find(CSSM_HANDLE handle, CSSM_RETURN notFoundError)
+ template <class ProcessBearer>
+ static RefPointer<ProcessBearer> find(CSSM_HANDLE handle, CSSM_RETURN notFoundError)
{
- RefPointer<Type> object =
- HandleObject::findRef<Type>(handle, notFoundError);
+ RefPointer<ProcessBearer> object =
+ HandleObject::findRef<ProcessBearer>(handle, notFoundError);
if (object->process() != Server::process())
CssmError::throwMe(notFoundError);
return object;
void Session::mergeCredentials(CredentialSet &creds)
{
secdebug("SSsession", "%p merge creds @%p", this, &creds);
- CredentialSet updatedCredentials = creds;
+ CredentialSet updatedCredentials = creds;
for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++)
if (((*it)->isShared() && (*it)->isValid())) {
CredentialSet::iterator old = mSessionCreds.find(*it);
updatedCredentials.insert(*old);
}
}
- creds.swap(updatedCredentials);
+ creds.swap(updatedCredentials);
}
void kill();
-private:
+protected:
static PortMap<Session> mSessions;
};
class PortMap : public Mutex, public std::map<Port, RefPointer<Node> > {
typedef std::map<Port, RefPointer<Node> > _Map;
public:
- bool contains(mach_port_t port) const { return find(port) != end(); }
+ bool contains(mach_port_t port) const { return this->find(port) != this->end(); }
Node *getOpt(mach_port_t port) const
{
- typename _Map::const_iterator it = find(port);
- return (it == end()) ? NULL : it->second;
+ typename _Map::const_iterator it = this->find(port);
+ return (it == this->end()) ? NULL : it->second;
}
Node *get(mach_port_t port) const
{
- typename _Map::const_iterator it = find(port);
- assert(it != end());
+ typename _Map::const_iterator it = this->find(port);
+ assert(it != this->end());
return it->second;
}
Node *get(mach_port_t port, OSStatus error) const
{
- typename _Map::const_iterator it = find(port);
- if (it == end())
+ typename _Map::const_iterator it = this->find(port);
+ if (it == this->end())
MacOSError::throwMe(error);
return it->second;
}
template <class Node>
void PortMap<Node>::dump()
{
- for (typename _Map::const_iterator it = begin(); it != end(); it++)
+ for (typename _Map::const_iterator it = this->begin(); it != this->end(); it++)
it->second->dump();
}
void Token::notify(NotificationEvent event)
{
NameValueDictionary nvd;
- CssmSubserviceUid ssuid(mGuid, NULL, mSubservice,
- CSSM_SERVICE_DL | CSSM_SERVICE_CSP);
+ CssmSubserviceUid ssuid(mGuid, NULL, h2n (mSubservice),
+ h2n(CSSM_SERVICE_DL | CSSM_SERVICE_CSP));
nvd.Insert(new NameValuePair(SSUID_KEY, CssmData::wrap(ssuid)));
CssmData data;
nvd.Export(data);
}
+//
+// FaultRelay
+//
+FaultRelay::~FaultRelay()
+{ /* virtual */ }
+
+
//
// Debug dump support
//
//
class FaultRelay {
public:
+ virtual ~FaultRelay();
virtual void relayFault(bool async) = 0;
};
DATA_OUT(data), KeyHandle *hKey, SearchHandle *hSearch, RecordHandle *hRecord)
{
BEGIN_IPC
- relocate(query, queryBase, queryLength);
- relocate(inAttributes, inAttributesBase, inAttributesLength);
+ relocate (query, queryBase, queryLength);
+ relocate (inAttributes, inAttributesBase, inAttributesLength);
RefPointer<Database::Search> search;
RefPointer<Database::Record> record;
*hKey = key ? key->handle() : noKey;
// return attributes (assumes relocated flat blob)
- flips(outAttrs, outAttributes, outAttributesBase);
+ flips(outAttrs, outAttributes, outAttributesBase);
+ // flipCssmDbAttributeData(outAttrs, outAttributes, outAttributesBase);
*outAttributesLength = outAttrsLength;
// return data (temporary fix)
if (getData) {
+ if (key) {
+ flip (*outData.interpretedAs<CssmKey>());
+ }
+
*data = outData.data();
*dataLength = outData.length();
}
// return data (temporary fix)
if (getData) {
+ if (key) {
+ flip (*outData.interpretedAs<CssmKey>());
+ }
+
*data = outData.data();
*dataLength = outData.length();
}
// return data (temporary fix)
if (getData) {
+ if (key) {
+ flip (*outData.interpretedAs<CssmKey>());
+ }
+
*data = outData.data();
*dataLength = outData.length();
}
// none at all. use the canonical transient store
return Server::optionalDatabase(noDb);
}
+
+
+
+void fixDbAttributes (CssmDbAttributeData &data)
+{
+ /*
+ NOTE TO FUTURE MAINTAINERS OF THIS CODE:
+
+ This code is called by two different routines; the relocation walker on the input attributes, and flips
+ on the output attributtes. This is bad, because the relocation walker flips the Info data structure,
+ and flips does not. We could fix this in flips, but flips is a template and does different things
+ depending on what its parameters are. As a result, the best place to do this is here.
+ */
+
+ // pull this data out first, so that it is unperverted once the flip occurs
+ unsigned limit = data.size ();
+ unsigned format = data.format ();
+ CssmData* values = data.values ();
+
+ // flip if it is safe to do so
+ if (format > CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX) // is the format screwed up?
+ {
+ flip (data.info ());
+ limit = data.size ();
+ format = data.format ();
+ values = data.values ();
+ }
+
+ unsigned i;
+
+ for (i = 0; i < limit; ++i)
+ {
+ switch (format)
+ {
+ case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
+ Flippers::flip(*(uint32*) values[i].data ());
+ break;
+
+ case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
+ {
+ CssmData& d = values[i];
+ int numValues = d.length() / sizeof (UInt32);
+ int j;
+ UInt32* v = (UInt32*) d.data();
+ for (j = 0; j < numValues; ++j)
+ {
+ Flippers::flip (v[j]);
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+
+void fixDbAttributes (CssmQuery &query)
+{
+ unsigned i;
+ unsigned numItems = query.size ();
+ for (i = 0; i < numItems; ++i)
+ {
+ fixDbAttributes(query.predicates()[i].attribute());
+ }
+}
+
+
+
+void fixDbAttributes (CssmDbRecordAttributeData &data)
+{
+ unsigned i;
+ unsigned numItems = data.size ();
+ for (i = 0; i < numItems; ++i)
+ {
+ fixDbAttributes(data.attributes()[i]);
+ }
+}
};
+//
+// Fix DBAttributes, which have to be processed specially
+//
+void fixDbAttributes (CssmDbAttributeData &data);
+void fixDbAttributes (CssmQuery &query);
+void fixDbAttributes (CssmDbRecordAttributeData &data);
+
+template<class T>
+void fixDbAttributes(T &n) {} // handle the default case
+
+
//
// Process an incoming (IPC) data blob of type T.
// This relocates pointers to fit in the local address space,
CheckingReconstituteWalker relocator(obj, base, size,
Server::process().byteFlipped());
walk(relocator, base);
+
+ // resolve weird type interdependency in DB_ATTRIBUTE_DATA
+ if (Server::process().byteFlipped())
+ fixDbAttributes(*obj);
}
}
}
+void flipCssmDbAttributeData (CssmDbRecordAttributeData *value, CssmDbRecordAttributeData **&addr, CssmDbRecordAttributeData **&base);
+
//
// Take an object at value, flip it, and return appropriately flipped
// addr/base pointers ready to be returned through IPC.
{
*addr = *base = value;
if (flipClient()) {
+ // resolve weird type inter-dependency in DB_ATTRIBUTE_DATA
+ if (value)
+ fixDbAttributes(*value);
FlipWalker w; // collector
walk(w, value); // collect all flippings needed
w.doFlips(); // execute flips (flips value but leaves addr alone)
}
}
-
//
// Take a DATA type RPC argument purportedly representing a Blob of some kind,
// turn it into a Blob, and fail properly if it's not kosher.