summaryrefslogtreecommitdiffstats
path: root/remoting/host
diff options
context:
space:
mode:
authorlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-20 20:59:19 +0000
committerlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-20 20:59:19 +0000
commit919af5861da3345c7a0758860eb4e0e9b3fbb4eb (patch)
tree2ca2e2a8fc6b0a62d3d7f92c9f35d7a8b08b5197 /remoting/host
parent8a6aaa7c2cf610f4b050b7558156598291120043 (diff)
downloadchromium_src-919af5861da3345c7a0758860eb4e0e9b3fbb4eb.zip
chromium_src-919af5861da3345c7a0758860eb4e0e9b3fbb4eb.tar.gz
chromium_src-919af5861da3345c7a0758860eb4e0e9b3fbb4eb.tar.bz2
Write Mac Me2Me config as root
This makes the json file owned by root, and readable for the user who installed the Me2e host components. Plugin elevates to root before writing the config data. BUG=None TEST=Manual Review URL: http://codereview.chromium.org/10084025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133274 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host')
-rwxr-xr-xremoting/host/installer/mac/PrivilegedHelperTools/org.chromium.chromoting.me2me.sh9
-rwxr-xr-xremoting/host/installer/mac/Scripts/remoting_postflight.sh10
-rwxr-xr-xremoting/host/installer/mac/Scripts/remoting_preflight.sh2
-rw-r--r--remoting/host/json_host_config.cc13
-rw-r--r--remoting/host/json_host_config.h2
-rw-r--r--remoting/host/plugin/daemon_controller_mac.cc68
6 files changed, 67 insertions, 37 deletions
diff --git a/remoting/host/installer/mac/PrivilegedHelperTools/org.chromium.chromoting.me2me.sh b/remoting/host/installer/mac/PrivilegedHelperTools/org.chromium.chromoting.me2me.sh
index eb7029c..a033362 100755
--- a/remoting/host/installer/mac/PrivilegedHelperTools/org.chromium.chromoting.me2me.sh
+++ b/remoting/host/installer/mac/PrivilegedHelperTools/org.chromium.chromoting.me2me.sh
@@ -8,6 +8,7 @@ NAME=org.chromium.chromoting
CONFIG_DIR=/Library/PrivilegedHelperTools
HOST_EXE=$CONFIG_DIR/$NAME.me2me_host
ENABLED_FILE=$CONFIG_DIR/$NAME.me2me_enabled
+CONFIG_FILE=$CONFIG_DIR/$NAME.json
if [ "$1" = "--disable" ]; then
# This script is executed from base::mac::ExecuteWithPrivilegesAndWait(),
@@ -17,9 +18,13 @@ if [ "$1" = "--disable" ]; then
rm -f "$ENABLED_FILE"
elif [ "$1" = "--enable" ]; then
echo $$
+ cat > "$CONFIG_FILE"
touch "$ENABLED_FILE"
+elif [ "$1" = "--save-config" ]; then
+ echo $$
+ cat > "$CONFIG_FILE"
else
exec "$HOST_EXE" \
- --auth-config="$CONFIG_DIR/$NAME.json" \
- --host-config="$CONFIG_DIR/$NAME.json"
+ --auth-config="$CONFIG_FILE" \
+ --host-config="$CONFIG_FILE"
fi
diff --git a/remoting/host/installer/mac/Scripts/remoting_postflight.sh b/remoting/host/installer/mac/Scripts/remoting_postflight.sh
index 2f72af4..ef9b7a8 100755
--- a/remoting/host/installer/mac/Scripts/remoting_postflight.sh
+++ b/remoting/host/installer/mac/Scripts/remoting_postflight.sh
@@ -6,7 +6,7 @@
HELPERTOOLS=/Library/PrivilegedHelperTools
NAME=org.chromium.chromoting
-AUTH_FILE="$HELPERTOOLS/$NAME.json"
+CONFIG_FILE="$HELPERTOOLS/$NAME.json"
PLIST=/Library/LaunchAgents/org.chromium.chromoting.plist
ENABLED_FILE="$HELPERTOOLS/$NAME.me2me_enabled"
ENABLED_FILE_BACKUP="$ENABLED_FILE.backup"
@@ -26,10 +26,10 @@ function onexit {
# Create auth file (with correct owner and permissions) if it doesn't already
# exist.
-if [[ ! -f "$AUTH_FILE" ]]; then
- touch "$AUTH_FILE"
- chown $USER "$AUTH_FILE"
- chmod 600 "$AUTH_FILE"
+if [[ ! -f "$CONFIG_FILE" ]]; then
+ touch "$CONFIG_FILE"
+ chmod 600 "$CONFIG_FILE"
+ chmod +a "$USER:allow:read" "$CONFIG_FILE"
fi
# Load the service.
diff --git a/remoting/host/installer/mac/Scripts/remoting_preflight.sh b/remoting/host/installer/mac/Scripts/remoting_preflight.sh
index 52bf3ea..6d13429 100755
--- a/remoting/host/installer/mac/Scripts/remoting_preflight.sh
+++ b/remoting/host/installer/mac/Scripts/remoting_preflight.sh
@@ -6,7 +6,7 @@
HELPERTOOLS=/Library/PrivilegedHelperTools
NAME=org.chromium.chromoting
-AUTH_FILE="$HELPERTOOLS/$NAME.json"
+CONFIG_FILE="$HELPERTOOLS/$NAME.json"
PLIST=/Library/LaunchAgents/org.chromium.chromoting.plist
ENABLED_FILE="$HELPERTOOLS/$NAME.me2me_enabled"
ENABLED_FILE_BACKUP="$ENABLED_FILE.backup"
diff --git a/remoting/host/json_host_config.cc b/remoting/host/json_host_config.cc
index 6c5c2e8..1f22adf 100644
--- a/remoting/host/json_host_config.cc
+++ b/remoting/host/json_host_config.cc
@@ -45,14 +45,17 @@ bool JsonHostConfig::Read() {
bool JsonHostConfig::Save() {
DCHECK(CalledOnValidThread());
- std::string file_content;
- base::JSONWriter::WriteWithOptions(values_.get(),
- base::JSONWriter::OPTIONS_PRETTY_PRINT,
- &file_content);
+ std::string file_content = GetSerializedData();
// TODO(sergeyu): Move ImportantFileWriter to base and use it here.
- int result = file_util::WriteFile(filename_, file_content.c_str(),
+ int result = file_util::WriteFile(filename_, file_content.data(),
file_content.size());
return result == static_cast<int>(file_content.size());
}
+std::string JsonHostConfig::GetSerializedData() {
+ std::string data;
+ base::JSONWriter::Write(values_.get(), &data);
+ return data;
+}
+
} // namespace remoting
diff --git a/remoting/host/json_host_config.h b/remoting/host/json_host_config.h
index f4db06d..014e148 100644
--- a/remoting/host/json_host_config.h
+++ b/remoting/host/json_host_config.h
@@ -27,6 +27,8 @@ class JsonHostConfig : public InMemoryHostConfig {
// MutableHostConfig interface.
virtual bool Save() OVERRIDE;
+ std::string GetSerializedData();
+
private:
FilePath filename_;
diff --git a/remoting/host/plugin/daemon_controller_mac.cc b/remoting/host/plugin/daemon_controller_mac.cc
index b48d7ec..e6011fd 100644
--- a/remoting/host/plugin/daemon_controller_mac.cc
+++ b/remoting/host/plugin/daemon_controller_mac.cc
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/json/json_writer.h"
@@ -75,7 +76,7 @@ class DaemonControllerMac : public remoting::DaemonController {
int tries_remaining,
const base::TimeDelta& sleep);
- bool RunToolScriptAsRoot(const char* command);
+ bool RunToolScriptAsRoot(const char* command, const std::string& input_data);
bool StopService();
// The API for gaining root privileges is blocking (it prompts the user for
@@ -165,24 +166,12 @@ void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) {
void DaemonControllerMac::DoSetConfigAndStart(
scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& done_callback) {
- // JsonHostConfig doesn't provide a way to save on the current thread, wait
- // for completion, and know whether the save succeeded. Instead, use
- // base::JSONWriter directly.
-
- // TODO(lambroslambrou): Improve the JsonHostConfig interface.
std::string file_content;
base::JSONWriter::Write(config.get(), &file_content);
- if (file_util::WriteFile(FilePath(kHostConfigFile), file_content.c_str(),
- file_content.size()) !=
- static_cast<int>(file_content.size())) {
- LOG(ERROR) << "Failed to write config file: " << kHostConfigFile;
- done_callback.Run(RESULT_FAILED);
- return;
- }
// Creating the trigger file causes launchd to start the service, so the
// extra step performed in DoStop() is not necessary here.
- bool result = RunToolScriptAsRoot("--enable");
+ bool result = RunToolScriptAsRoot("--enable", file_content);
done_callback.Run(result ? RESULT_OK : RESULT_FAILED);
}
@@ -203,7 +192,10 @@ void DaemonControllerMac::DoUpdateConfig(
}
config_file.SetString(*key, value);
}
- bool success = config_file.Save();
+
+ std::string file_content = config_file.GetSerializedData();
+ bool success = RunToolScriptAsRoot("--save-config", file_content);
+
done_callback.Run(success ? RESULT_OK : RESULT_FAILED);
pid_t job_pid = base::mac::PIDForJob(kServiceName);
if (job_pid > 0) {
@@ -212,7 +204,7 @@ void DaemonControllerMac::DoUpdateConfig(
}
void DaemonControllerMac::DoStop(const CompletionCallback& done_callback) {
- if (!RunToolScriptAsRoot("--disable")) {
+ if (!RunToolScriptAsRoot("--disable", "")) {
done_callback.Run(RESULT_FAILED);
return;
}
@@ -253,7 +245,8 @@ void DaemonControllerMac::NotifyWhenStopped(
}
}
-bool DaemonControllerMac::RunToolScriptAsRoot(const char* command) {
+bool DaemonControllerMac::RunToolScriptAsRoot(const char* command,
+ const std::string& input_data) {
// TODO(lambroslambrou): Supply a localized prompt string here.
base::mac::ScopedAuthorizationRef authorization(
base::mac::AuthorizationCreateToRunAsRoot(CFSTR("")));
@@ -270,24 +263,51 @@ bool DaemonControllerMac::RunToolScriptAsRoot(const char* command) {
// TODO(lambroslambrou): Use sandbox-exec to minimize exposure -
// http://crbug.com/120903
const char* arguments[] = { command, NULL };
- int exit_status;
- OSStatus status = base::mac::ExecuteWithPrivilegesAndWait(
+ FILE* pipe = NULL;
+ pid_t pid;
+ OSStatus status = base::mac::ExecuteWithPrivilegesAndGetPID(
authorization.get(),
kStartStopTool,
kAuthorizationFlagDefaults,
arguments,
- NULL,
- &exit_status);
+ &pipe,
+ &pid);
if (status != errAuthorizationSuccess) {
OSSTATUS_LOG(ERROR, status) << "AuthorizationExecuteWithPrivileges";
return false;
}
- if (exit_status != 0) {
- LOG(ERROR) << kStartStopTool << " failed with exit status " << exit_status;
+ if (pid == -1) {
+ LOG(ERROR) << "Failed to get child PID";
return false;
}
- return true;
+ DCHECK(pipe);
+ if (!input_data.empty()) {
+ size_t bytes_written = fwrite(input_data.data(), sizeof(char),
+ input_data.size(), pipe);
+ // According to the fwrite manpage, a partial count is returned only if a
+ // write error has occurred.
+ if (bytes_written != input_data.size()) {
+ LOG(ERROR) << "Failed to write data to child process";
+ }
+ // Need to close, since the child waits for EOF on its stdin.
+ if (fclose(pipe) != 0) {
+ PLOG(ERROR) << "fclose";
+ }
+ }
+
+ int exit_status;
+ pid_t wait_result = HANDLE_EINTR(waitpid(pid, &exit_status, 0));
+ if (wait_result != pid) {
+ PLOG(ERROR) << "waitpid";
+ return false;
+ }
+ if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) {
+ return true;
+ } else {
+ LOG(ERROR) << kStartStopTool << " failed with exit status " << exit_status;
+ return false;
+ }
}
bool DaemonControllerMac::StopService() {