2 * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
25 * AuthorizationMechEval.cpp
30 #include "AuthorizationMechEval.h"
32 namespace Authorization
{
34 AgentMechanismRef::AgentMechanismRef(uid_t clientUID
, const Session
&session
) :
35 RefPointer
<QueryInvokeMechanism
>(new QueryInvokeMechanism(clientUID
, session
)) {}
37 AgentMechanismRef::AgentMechanismRef() :
38 RefPointer
<QueryInvokeMechanism
>(new QueryInvokeMechanism()) {}
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
)
48 AgentMechanismEvaluator::run(const AuthValueVector
&inArguments
, const AuthItemSet
&inHints
, const AuthItemSet
&inContext
)
50 // add process specifics to context?
52 vector
<std::string
>::const_iterator currentMechanism
= mMechanisms
.begin();
54 AuthorizationResult result
= kAuthorizationResultAllow
;
56 AuthItemSet hints
= inHints
;
57 AuthItemSet context
= inContext
;
59 while ( (result
== kAuthorizationResultAllow
) &&
60 (currentMechanism
!= mMechanisms
.end()) ) // iterate mechanisms
62 ClientMap::iterator iter
= mClients
.find(*currentMechanism
);
63 if (iter
== mClients
.end())
65 string::size_type extPlugin
= currentMechanism
->find(':');
66 if (extPlugin
!= string::npos
)
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());
73 AgentMechanismRef
client(mClientUid
, mSession
);
74 client
->initialize(pluginIn
, mechanismIn
);
75 // XXX/cs client->inferHints(Server::process());
76 mClients
[*currentMechanism
] = client
;
78 else if (*currentMechanism
== "authinternal")
80 secdebug("AuthEvalMech", "performing authentication");
81 result
= authinternal(context
);
83 else if (*currentMechanism
== "push_hints_to_context")
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...
92 else if (*currentMechanism
== "switch_to_user")
94 AgentMechanismRef
client(mClientUid
, mSession
);
99 return errAuthorizationInternal
;
102 iter
= mClients
.find(*currentMechanism
);
104 if (iter
!= mClients
.end())
108 iter
->second
->run(inArguments
, hints
, context
, &result
);
109 secdebug("AuthEvalMech", "evaluate(%s) succeeded with result: %lu.", (iter
->first
).c_str(), result
);
112 secdebug("AuthEvalMech", "exception from mech eval or client death");
113 result
= kAuthorizationResultUndefined
;
117 // we own outHints and outContext
120 case kAuthorizationResultAllow
:
121 secdebug("AuthEvalMech", "result allow");
124 case kAuthorizationResultDeny
:
125 secdebug("AuthEvalMech", "result deny");
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
134 break; // abort evaluation
138 if ((result
== kAuthorizationResultUserCanceled
) ||
139 (result
== kAuthorizationResultAllow
))
145 // convert AuthorizationResult to OSStatus
148 case kAuthorizationResultDeny
:
149 return errAuthorizationDenied
;
150 case kAuthorizationResultUserCanceled
:
151 return errAuthorizationCanceled
;
152 case kAuthorizationResultAllow
:
153 return errAuthorizationSuccess
;
155 return errAuthorizationInternal
;
159 AuthorizationResult
AgentMechanismEvaluator::authinternal(AuthItemSet
&context
)
161 secdebug("AuthEvalMech", "evaluate authinternal");
163 AuthItemSet::iterator found
= find_if(context
.begin(), context
.end(), FindAuthItemByRightName(kAuthorizationEnvironmentUsername
) );
164 if (found
== context
.end())
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())
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
175 if (newCredential
->isValid())
177 Syslog::info("authinternal authenticated user %s (uid %lu).", newCredential
->username().c_str(), newCredential
->uid());
178 return kAuthorizationResultAllow
;
181 Syslog::error("authinternal failed to authenticate user %s.", newCredential
->username().c_str());
185 return kAuthorizationResultDeny
;
190 AgentMechanismEvaluator::commonHints(const AuthorizationToken &auth)
196 } /* namespace Authorization */