]> git.saurik.com Git - apple/security.git/blob - authd/session.c
Security-55471.tar.gz
[apple/security.git] / authd / session.c
1 /* Copyright (c) 2012 Apple Inc. All rights reserved. */
2
3 #include "session.h"
4 #include "process.h"
5 #include "debugging.h"
6 #include <dispatch/dispatch.h>
7 #include <CoreFoundation/CoreFoundation.h>
8
9 struct _session_s {
10 __AUTH_BASE_STRUCT_HEADER__;
11
12 CFMutableSetRef credentials;
13 CFMutableSetRef processes;
14 auditinfo_addr_t auditinfo;
15
16 dispatch_queue_t dispatch_queue;
17
18 };
19
20 static void
21 _session_finalize(CFTypeRef value)
22 {
23 session_t session = (session_t)value;
24
25 LOGV("session: %i deallocated %p", session->auditinfo.ai_asid, session);
26
27 // make sure queue is empty
28 dispatch_barrier_sync(session->dispatch_queue, ^{});
29
30 dispatch_release(session->dispatch_queue);
31 CFReleaseSafe(session->credentials);
32 CFReleaseSafe(session->processes);
33 }
34
35 AUTH_TYPE_INSTANCE(session,
36 .init = NULL,
37 .copy = NULL,
38 .finalize = _session_finalize,
39 .equal = NULL,
40 .hash = NULL,
41 .copyFormattingDesc = NULL,
42 .copyDebugDesc = NULL
43 );
44
45 static CFTypeID session_get_type_id() {
46 static CFTypeID type_id = _kCFRuntimeNotATypeID;
47 static dispatch_once_t onceToken;
48
49 dispatch_once(&onceToken, ^{
50 type_id = _CFRuntimeRegisterClass(&_auth_type_session);
51 });
52
53 return type_id;
54 }
55
56 session_t
57 session_create(session_id_t sid)
58 {
59 session_t session = NULL;
60
61 session = (session_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, session_get_type_id(), AUTH_CLASS_SIZE(session), NULL);
62 require(session != NULL, done);
63
64 session->auditinfo.ai_asid = sid;
65
66 if (!session_update(session)) {
67 LOGE("session: failed to get session info");
68 }
69
70 session->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
71 check(session->dispatch_queue != NULL);
72
73 session->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
74 session->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
75
76 LOGV("session: %i created (uid=%i) %p", session->auditinfo.ai_asid, session->auditinfo.ai_auid, session);
77
78 done:
79 return session;
80 }
81
82 bool session_update(session_t session)
83 {
84 return auditon(A_GETSINFO_ADDR, &session->auditinfo, sizeof(session->auditinfo)) == 0;
85 }
86
87 uint64_t session_get_attributes(session_t session)
88 {
89 session_update(session);
90
91 return session->auditinfo.ai_flags;
92 }
93
94 static void _set_attributes(session_t session, uint64_t flags)
95 {
96 session->auditinfo.ai_flags = flags;
97 int32_t rc = setaudit_addr(&session->auditinfo, sizeof(session->auditinfo));
98 if (rc != 0) {
99 LOGV("session: failed to update session info (%d)", rc);
100 }
101 }
102
103 void session_set_attributes(session_t session, uint64_t flags)
104 {
105 session_update(session);
106 _set_attributes(session,session->auditinfo.ai_flags | flags);
107 }
108
109 void session_clear_attributes(session_t session, uint64_t flags)
110 {
111 session_update(session);
112 _set_attributes(session,session->auditinfo.ai_flags & ~flags);
113 }
114
115
116 const void *
117 session_get_key(session_t session)
118 {
119 return &session->auditinfo.ai_asid;
120 }
121
122 session_id_t
123 session_get_id(session_t session)
124 {
125 return session ? session->auditinfo.ai_asid : -1;
126 }
127
128 uid_t
129 session_get_uid(session_t session)
130 {
131 return session ? session->auditinfo.ai_auid : (uid_t)-2;
132 }
133
134 CFIndex
135 session_add_process(session_t session, process_t proc)
136 {
137 __block CFIndex count = 0;
138 dispatch_sync(session->dispatch_queue, ^{
139 CFSetAddValue(session->processes, proc);
140 count = CFSetGetCount(session->processes);
141 });
142 return count;
143 }
144
145 CFIndex
146 session_remove_process(session_t session, process_t proc)
147 {
148 __block CFIndex count = 0;
149 dispatch_sync(session->dispatch_queue, ^{
150 CFSetRemoveValue(session->processes, proc);
151 count = CFSetGetCount(session->processes);
152 });
153 return count;
154 }
155
156 CFIndex
157 session_get_process_count(session_t session)
158 {
159 __block CFIndex count = 0;
160 dispatch_sync(session->dispatch_queue, ^{
161 count = CFSetGetCount(session->processes);
162 });
163 return count;
164 }
165
166 void
167 session_set_credential(session_t session, credential_t cred)
168 {
169 if (!credential_get_valid(cred))
170 return;
171
172 dispatch_sync(session->dispatch_queue, ^{
173 CFSetSetValue(session->credentials, cred);
174 });
175 }
176
177 void
178 session_credentials_purge(session_t session)
179 {
180 session_credentials_iterate(session, ^bool(credential_t cred) {
181 if (!credential_get_valid(cred)) {
182 CFSetRemoveValue(session->credentials, cred);
183 }
184 return true;
185 });
186 }
187
188 bool
189 session_credentials_iterate(session_t session, credential_iterator_t iter)
190 {
191 __block bool result = false;
192
193 dispatch_sync(session->dispatch_queue, ^{
194 CFIndex count = CFSetGetCount(session->credentials);
195 CFTypeRef values[count];
196 CFSetGetValues(session->credentials, values);
197 for (CFIndex i = 0; i < count; i++) {
198 credential_t cred = (credential_t)values[i];
199 result = iter(cred);
200 if (!result) {
201 break;
202 }
203 }
204 });
205
206
207 return result;
208 }