]> git.saurik.com Git - apple/security.git/blob - SecurityServer/cfnotifier.cpp
Security-28.tar.gz
[apple/security.git] / SecurityServer / cfnotifier.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // cfnotifier - quick & dirty code to send keychain lock notification
21 //
22 #include "cfnotifier.h"
23 #include <Security/debugging.h>
24 #include <CoreFoundation/CoreFoundation.h>
25
26 #include "session.h"
27
28 using namespace Security;
29 using namespace Security::MachPlusPlus;
30
31
32 #define notificationName CFSTR("com.apple.securitycore.kcevent")
33 #define eventTypeKey CFSTR("type")
34 #define keychainKey CFSTR("keychain")
35 #define itekey CFSTR("item")
36 #define keyGUID CFSTR("GUID")
37 #define keySubserviceId CFSTR("SubserviceId")
38 #define keySubserviceType CFSTR("SubserviceType")
39 #define keyDbName CFSTR("DbName")
40 #define keyDbLocation CFSTR("DbLocation")
41 #define keyActive CFSTR("Active")
42 #define keyMajorVersion CFSTR("MajorVersion")
43 #define keyMinorVersion CFSTR("MinorVersion")
44 #define defaultDLDbListKey CFSTR("DLDBSearchList")
45 #define defaultDomain CFSTR("com.apple.securitycore")
46
47
48 //
49 // Event codes
50 //
51 enum {
52 lockedEvent = 1, /* a keychain was locked */
53 unlockedEvent = 2, /* a keychain was unlocked */
54 passphraseChangedEvent = 6 /* a keychain password was (possibly) changed */
55 };
56
57
58 //
59 // Local functions
60 //
61 static CFDictionaryRef makeDictionary(const DLDbIdentifier &db);
62
63
64 //
65 // Main methods
66 //
67 void KeychainNotifier::lock(const DLDbIdentifier &db)
68 { notify(db, lockedEvent); }
69
70 void KeychainNotifier::unlock(const DLDbIdentifier &db)
71 { notify(db, unlockedEvent); }
72
73 void KeychainNotifier::passphraseChanged(const DLDbIdentifier &db)
74 { notify(db, passphraseChangedEvent); }
75
76
77 //
78 // Lock and unlock notifications
79 //
80 void KeychainNotifier::notify(const DLDbIdentifier &db, int event)
81 {
82 CFRef<CFMutableDictionaryRef> mutableDict(::CFDictionaryCreateMutable(
83 kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
84 &kCFTypeDictionaryValueCallBacks));
85 if (!mutableDict)
86 throw std::bad_alloc();
87
88 SInt32 theEvent = event;
89 CFRef<CFNumberRef> theEventData(::CFNumberCreate( kCFAllocatorDefault,
90 kCFNumberSInt32Type, &theEvent));
91 if (!theEventData)
92 throw std::bad_alloc();
93 ::CFDictionarySetValue( mutableDict, eventTypeKey, theEventData );
94
95 CFRef<CFDictionaryRef> dict = makeDictionary(db);
96 if (!dict)
97 throw std::bad_alloc();
98 ::CFDictionarySetValue(mutableDict, keychainKey, dict);
99
100 for (Session::Iterator it = Session::begin(); it != Session::end(); it++) {
101 StBootstrap bootSwitch(it->second->bootstrapPort());
102 IFDEBUG(debug("cfnotify", "send event %d for database %s to session %p",
103 event, db.dbName(), it->second));
104 ::CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
105 notificationName, NULL, mutableDict, false);
106 }
107 }
108
109 static CFDictionaryRef makeDictionary(const DLDbIdentifier &db)
110 {
111 CFRef<CFMutableDictionaryRef> aDict(CFDictionaryCreateMutable(kCFAllocatorDefault,0,
112 &kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks));
113 if (!aDict)
114 throw std::bad_alloc();
115
116 // Put SUBSERVICE_UID in dictionary
117 char buffer[Guid::stringRepLength+1];
118 const CssmSubserviceUid& ssuid=db.ssuid();
119 const Guid &theGuid = Guid::overlay(ssuid.Guid);
120 CFRef<CFStringRef> stringGuid(::CFStringCreateWithCString(kCFAllocatorDefault,
121 theGuid.toString(buffer),kCFStringEncodingMacRoman));
122 if (stringGuid)
123 ::CFDictionarySetValue(aDict,keyGUID,stringGuid);
124
125 if (ssuid.SubserviceId!=0)
126 {
127 CFRef<CFNumberRef> subserviceId(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceId));
128 if (subserviceId)
129 ::CFDictionarySetValue(aDict,keySubserviceId,subserviceId);
130 }
131 if (ssuid.SubserviceType!=0)
132 {
133 CFRef<CFNumberRef> subserviceType(CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.SubserviceType));
134 if (subserviceType)
135 ::CFDictionarySetValue(aDict,keySubserviceType,subserviceType);
136 }
137 if (ssuid.Version.Major!=0 && ssuid.Version.Minor!=0)
138 {
139 CFRef<CFNumberRef> majorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Major));
140 if (majorVersion)
141 ::CFDictionarySetValue(aDict,keyMajorVersion,majorVersion);
142 CFRef<CFNumberRef> minorVersion(::CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&ssuid.Version.Minor));
143 if (minorVersion)
144 ::CFDictionarySetValue(aDict,keyMinorVersion,minorVersion);
145 }
146
147 // Put DbName in dictionary
148 const char *dbName=db.dbName();
149 if (dbName)
150 {
151 CFRef<CFStringRef> theDbName(::CFStringCreateWithCString(kCFAllocatorDefault,dbName,kCFStringEncodingMacRoman));
152 ::CFDictionarySetValue(aDict,keyDbName,theDbName);
153 }
154 // Put DbLocation in dictionary
155 const CSSM_NET_ADDRESS *dbLocation=db.dbLocation();
156 if (dbLocation!=NULL && dbLocation->AddressType!=CSSM_ADDR_NONE)
157 {
158 CFRef<CFDataRef> theData(::CFDataCreate(kCFAllocatorDefault,dbLocation->Address.Data,dbLocation->Address.Length));
159 if (theData)
160 ::CFDictionarySetValue(aDict,keyDbLocation,theData);
161 }
162
163 ::CFRetain(aDict);
164 return aDict;
165 }
166