]> git.saurik.com Git - apple/securityd.git/blob - src/AuthorizationMechEval.cpp
5f7a7934997f82d30660016aa3ad02b358e1b134
[apple/securityd.git] / src / AuthorizationMechEval.cpp
1 /*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 *
25 * AuthorizationMechEval.cpp
26 * securityd
27 *
28 */
29
30 #include "AuthorizationMechEval.h"
31
32 namespace Authorization {
33
34 AgentMechanismRef::AgentMechanismRef(uid_t clientUID, const Session &session) :
35 RefPointer<QueryInvokeMechanism>(new QueryInvokeMechanism(clientUID, session)) {}
36
37 AgentMechanismRef::AgentMechanismRef() :
38 RefPointer<QueryInvokeMechanism>(new QueryInvokeMechanism()) {}
39
40 // we need the vector<string> of mechanisms
41 AgentMechanismEvaluator::AgentMechanismEvaluator(uid_t uid, const Session& session, const vector<string>& inMechanisms) :
42 mMechanisms(inMechanisms), mClientUid(uid), mSession(session)
43 {
44 //set up environment
45 }
46
47 OSStatus
48 AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemSet &inHints, const AuthItemSet &inContext)
49 {
50 // add process specifics to context?
51
52 vector<std::string>::const_iterator currentMechanism = mMechanisms.begin();
53
54 AuthorizationResult result = kAuthorizationResultAllow;
55
56 AuthItemSet hints = inHints;
57 AuthItemSet context = inContext;
58
59 while ( (result == kAuthorizationResultAllow) &&
60 (currentMechanism != mMechanisms.end()) ) // iterate mechanisms
61 {
62 ClientMap::iterator iter = mClients.find(*currentMechanism);
63 if (iter == mClients.end())
64 {
65 string::size_type extPlugin = currentMechanism->find(':');
66 if (extPlugin != string::npos)
67 {
68 // no whitespace removal
69 string pluginIn(currentMechanism->substr(0, extPlugin));
70 string mechanismIn(currentMechanism->substr(extPlugin + 1));
71 secdebug("AuthEvalMech", "external mech %s:%s", pluginIn.c_str(), mechanismIn.c_str());
72
73 AgentMechanismRef client(mClientUid, mSession);
74 client->initialize(pluginIn, mechanismIn);
75 // XXX/cs client->inferHints(Server::process());
76 mClients[*currentMechanism] = client;
77 }
78 else if (*currentMechanism == "authinternal")
79 {
80 secdebug("AuthEvalMech", "performing authentication");
81 result = authinternal(context);
82 }
83 else if (*currentMechanism == "push_hints_to_context")
84 {
85 secdebug("AuthEvalMech", "evaluate push_hints_to_context");
86 result = kAuthorizationResultAllow; // snarfcredential doesn't block evaluation, ever, it may restart
87 // create out context from input hints, no merge
88 // @@@ global copy template not being invoked...
89 context = hints;
90 }
91 #if 0
92 else if (*currentMechanism == "switch_to_user")
93 {
94 AgentMechanismRef client(mClientUid, mSession);
95 client->terminate();
96 }
97 #endif
98 else
99 return errAuthorizationInternal;
100 }
101
102 iter = mClients.find(*currentMechanism);
103
104 if (iter != mClients.end())
105 {
106 try
107 {
108 iter->second->run(inArguments, hints, context, &result);
109 secdebug("AuthEvalMech", "evaluate(%s) succeeded with result: %lu.", (iter->first).c_str(), result);
110 }
111 catch (...) {
112 secdebug("AuthEvalMech", "exception from mech eval or client death");
113 result = kAuthorizationResultUndefined;
114 }
115 }
116
117 // we own outHints and outContext
118 switch(result)
119 {
120 case kAuthorizationResultAllow:
121 secdebug("AuthEvalMech", "result allow");
122 currentMechanism++;
123 break;
124 case kAuthorizationResultDeny:
125 secdebug("AuthEvalMech", "result deny");
126 break;
127 case kAuthorizationResultUndefined:
128 secdebug("AuthEvalMech", "result undefined");
129 break; // abort evaluation
130 case kAuthorizationResultUserCanceled:
131 secdebug("AuthEvalMech", "result canceled");
132 break; // stop evaluation, return some sideband
133 default:
134 break; // abort evaluation
135 }
136 }
137
138 if ((result == kAuthorizationResultUserCanceled) ||
139 (result == kAuthorizationResultAllow))
140 {
141 mHints = hints;
142 mContext = context;
143 }
144
145 // convert AuthorizationResult to OSStatus
146 switch(result)
147 {
148 case kAuthorizationResultDeny:
149 return errAuthorizationDenied;
150 case kAuthorizationResultUserCanceled:
151 return errAuthorizationCanceled;
152 case kAuthorizationResultAllow:
153 return errAuthorizationSuccess;
154 default:
155 return errAuthorizationInternal;
156 }
157 }
158
159 AuthorizationResult AgentMechanismEvaluator::authinternal(AuthItemSet &context)
160 {
161 secdebug("AuthEvalMech", "evaluate authinternal");
162 do {
163 AuthItemSet::iterator found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentUsername) );
164 if (found == context.end())
165 break;
166 string username(static_cast<const char *>((*found)->value().data), (*found)->value().length);
167 secdebug("AuthEvalMech", "found username");
168 found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentPassword) );
169 if (found == context.end())
170 break;
171 string password(static_cast<const char *>((*found)->value().data), (*found)->value().length);
172 secdebug("AuthEvalMech", "found password");
173 Credential newCredential(username, password, true); // create a new shared credential
174
175 if (newCredential->isValid())
176 {
177 Syslog::info("authinternal authenticated user %s (uid %lu).", newCredential->username().c_str(), newCredential->uid());
178 return kAuthorizationResultAllow;
179 }
180
181 Syslog::error("authinternal failed to authenticate user %s.", newCredential->username().c_str());
182
183 } while (0);
184
185 return kAuthorizationResultDeny;
186 }
187
188 /*
189 AuthItemSet &
190 AgentMechanismEvaluator::commonHints(const AuthorizationToken &auth)
191 {
192
193 }
194 */
195
196 } /* namespace Authorization */