#include <fcntl.h>
#include "authhost.h"
#include "server.h"
+#include <security_utilities/logging.h>
+#include <security_utilities/debugging.h>
+#include <security_agent_client/sa_request.h>
+#include <security_agent_client/utils.h>
+#include <bsm/audit.h>
+#include <bootstrap_priv.h>
#include <grp.h>
#include <pwd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <syslog.h>
+#include <pthread.h>
+static pthread_once_t agent_cred_init = PTHREAD_ONCE_INIT;
+static gid_t agent_gid = 92;
+static uid_t agent_uid = 92;
+void initialize_agent_creds()
+{
+ struct passwd *agentUser = getpwnam("securityagent");
+ if (agentUser)
+ {
+ agent_uid = agentUser->pw_uid;
+ agent_gid = agentUser->pw_gid;
+ endpwent();
+ }
+}
+
AuthHostInstance::AuthHostInstance(Session &session, AuthHostType host) :
mHostType(host)
{
secdebug("authhost", "authhost born (%p)", this);
referent(session);
session.addReference(*this);
+ if (host == securityAgent)
+ pthread_once(&agent_cred_init, initialize_agent_creds);
}
AuthHostInstance::~AuthHostInstance()
{
secdebug("authhost", "authhost died (%p)", this);
-
- // clean up
- servicePort ().destroy ();
}
Session &AuthHostInstance::session() const
return referent<Session>();
}
+bool AuthHostInstance::inDarkWake()
+{
+ return session().server().inDarkWake();
+}
+
void
AuthHostInstance::childAction()
{
+ // switch to desired session
+ CommonCriteria::AuditInfo &audit = this->session().auditInfo();
+ audit.get(audit.sessionId());
+ audit.set();
+ //this->session().auditInfo().set();
+
// Setup the environment for the SecurityAgent
unsetenv("USER");
unsetenv("LOGNAME");
const char *path = getenv("SECURITYAGENT");
if (!path)
path = "/System/Library/CoreServices/SecurityAgent.app";
+ secdebug("adhoc", "hostType = %d", mHostType);
if ((mHostType == userAuthHost) || (mHostType == privilegedAuthHost))
{
snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/Resources/authorizationhost", path);
-
secdebug("AuthHostInstance", "execl(%s)", agentExecutable);
execl(agentExecutable, agentExecutable, NULL);
}
{
snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/MacOS/SecurityAgent", path);
- struct group *agentGroup = getgrnam("securityagent");
- gid_t agentGID = static_cast<gid_t>(-2);
- if (agentGroup)
- {
- agentGID = agentGroup->gr_gid;
- endgrent();
- }
+ pid_t pid = getpid();
+ if ((pid <= 0) ||
+ sysctlbyname("vfs.generic.noremotehang", NULL, NULL, &pid, sizeof(pid)))
+ syslog(LOG_ERR, "Failed to set vfs.generic.noremotehang for pid(%d)", pid);
- struct passwd *agentUser = getpwnam("securityagent");
- uid_t agentUID = static_cast<uid_t>(-2);
- if (agentUser)
- {
- agentUID = agentUser->pw_uid;
- endpwent();
- }
+ setgroups(1, &agent_gid);
+ setgid(agent_gid);
+ setuid(agent_uid);
- setuid(agentUID);
- setgid(agentGID);
-
- CFRef<CFDataRef> userPrefs(session().copyUserPrefs());
-
- FILE *mbox = tmpfile();
-
- if (userPrefs && mbox)
- {
- if (fwrite(CFDataGetBytePtr(userPrefs), CFDataGetLength(userPrefs), 1, mbox) != 1)
- fclose(mbox);
- else
- {
- char mboxFdString[20];
- fflush(mbox);
- if ((int)sizeof(mboxFdString) > snprintf(mboxFdString, sizeof(mboxFdString), "%d", fileno(mbox)))
- setenv("SECURITYAGENT_USERPREFS_FD", mboxFdString, 1);
- }
- }
-
- secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agentUID, agentGID);
+ secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agent_uid, agent_gid);
execl(agentExecutable, agentExecutable, NULL);
}
secdebug("AuthHostInstance", "execl failed, errno=%d", errno);
// Unconditional suicide follows.
- // See comments below on why we can't use abort()
-#if 1
_exit(1);
-#else
- // NOTE: OS X abort() is implemented as kill(getuid()), which fails
- // for a setuid-root process that has setuid'd. Go back to root to die...
- setuid(0);
- abort();
-#endif
}
-Port
-AuthHostInstance::activate()
+// @@@ these definitions and the logic in lookup() should move into
+// libsecurity_agent
+#define SECURITYAGENT_BOOTSTRAP_NAME_BASE "com.apple.SecurityAgent"
+#define AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE "com.apple.authorizationhost"
+
+mach_port_t
+AuthHostInstance::lookup(SessionId jobId)
+{
+ StLock<Mutex> _(*this);
+
+ mach_port_t pluginhostPort = MACH_PORT_NULL;
+ kern_return_t result;
+ const char *serviceName;
+ /* PR-7483709 const */ uuid_t instanceId = UUID_INITIALIZER_FROM_SESSIONID(jobId);
+ uuid_string_t s;
+
+ if ((mHostType == securityAgent)) {
+ if (!(session().attributes() & sessionHasGraphicAccess))
+ CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+ if (inDarkWake())
+ CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE);
+ }
+
+ if (mHostType == securityAgent)
+ serviceName = SECURITYAGENT_BOOTSTRAP_NAME_BASE;
+ else
+ serviceName = AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE;
+
+ secdebug("AuthHostInstance", "looking up %s instance %s", serviceName,
+ uuid_to_string(instanceId, s)); // XXX/gh debugging
+ if ((result = bootstrap_look_up3(bootstrap_port, serviceName,
+ &pluginhostPort, 0, instanceId, BOOTSTRAP_SPECIFIC_INSTANCE)) != KERN_SUCCESS) {
+
+ Syslog::error("error %d looking up %s instance %s", result, serviceName,
+ uuid_to_string(instanceId, s));
+ } else
+ secdebug("AuthHostInstance", "port = %x", (unsigned int)pluginhostPort);
+
+ return pluginhostPort;
+}
+
+Port AuthHostInstance::activate()
{
StLock<Mutex> _(*this);
if (state() != alive)
{
- if (!(session().attributes() & sessionHasGraphicAccess))
+ if ((mHostType == securityAgent)) {
+ if (!(session().attributes() & sessionHasGraphicAccess))
CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
-
- Security::MachPlusPlus::StBootstrap bootSaver(session().bootstrapPort());
+ if (inDarkWake())
+ CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE);
+ }
fork();
switch (ServerChild::state()) {