summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-14 20:54:45 +0000
committerlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-14 20:54:45 +0000
commit0333290378df304cfa2cd7de5ef90e8162e94dd1 (patch)
tree09dfc8562f15d7a508b1264af3d3774e292e6ea3 /remoting
parent0ab582571bc165d4bdf9f1e8b6d2bb2beb2d03a1 (diff)
downloadchromium_src-0333290378df304cfa2cd7de5ef90e8162e94dd1.zip
chromium_src-0333290378df304cfa2cd7de5ef90e8162e94dd1.tar.gz
chromium_src-0333290378df304cfa2cd7de5ef90e8162e94dd1.tar.bz2
Build pref-pane as universal binary on Mac OS X
BUG=125116 TEST=manual Review URL: https://chromiumcodereview.appspot.com/10383204 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142214 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/me2me_preference_pane.mm200
-rw-r--r--remoting/remoting.gyp28
2 files changed, 185 insertions, 43 deletions
diff --git a/remoting/host/me2me_preference_pane.mm b/remoting/host/me2me_preference_pane.mm
index 35b9468..ac33b13 100644
--- a/remoting/host/me2me_preference_pane.mm
+++ b/remoting/host/me2me_preference_pane.mm
@@ -6,23 +6,18 @@
#import <Cocoa/Cocoa.h>
#include <CommonCrypto/CommonHMAC.h>
+#include <errno.h>
#include <launch.h>
#import <PreferencePanes/PreferencePanes.h>
#import <SecurityInterface/SFAuthorizationView.h>
+#include <stdlib.h>
#include <unistd.h>
#include <fstream>
#include "base/eintr_wrapper.h"
-#include "base/logging.h"
-#include "base/mac/authorization_util.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/launchd.h"
-#include "base/mac/mac_logging.h"
#include "base/mac/scoped_launch_data.h"
#include "base/memory/scoped_ptr.h"
-#include "base/stringprintf.h"
-#include "base/sys_string_conversions.h"
#include "remoting/host/host_config.h"
#import "remoting/host/me2me_preference_pane_confirm_pin.h"
#import "remoting/host/me2me_preference_pane_disable.h"
@@ -75,7 +70,7 @@ bool IsPinValid(const std::string& pin, const std::string& host_id,
std::string method = host_secret_hash.substr(0, separator);
if (method != "hmac") {
- LOG(ERROR) << "Authentication method '" << method << "' not supported";
+ NSLog(@"Authentication method '%s' not supported", method.c_str());
return false;
}
@@ -90,7 +85,7 @@ bool IsPinValid(const std::string& pin, const std::string& host_id,
int hash_size = modp_b64_decode(&(hash[0]), hash_base64.data(),
hash_base64_size);
if (hash_size < 0) {
- LOG(ERROR) << "Failed to parse host_secret_hash";
+ NSLog(@"Failed to parse host_secret_hash");
return false;
}
hash.resize(hash_size);
@@ -111,6 +106,139 @@ bool IsPinValid(const std::string& pin, const std::string& host_id,
} // namespace
+// These methods are copied from base/mac, but with the logging changed to use
+// NSLog().
+//
+// TODO(lambroslambrou): Once the "base" target supports building for 64-bit
+// on Mac OS X, remove these implementations and use the ones in base/mac.
+namespace base {
+namespace mac {
+
+// MessageForJob sends a single message to launchd with a simple dictionary
+// mapping |operation| to |job_label|, and returns the result of calling
+// launch_msg to send that message. On failure, returns NULL. The caller
+// assumes ownership of the returned launch_data_t object.
+launch_data_t MessageForJob(const std::string& job_label,
+ const char* operation) {
+ // launch_data_alloc returns something that needs to be freed.
+ ScopedLaunchData message(launch_data_alloc(LAUNCH_DATA_DICTIONARY));
+ if (!message) {
+ NSLog(@"launch_data_alloc");
+ return NULL;
+ }
+
+ // launch_data_new_string returns something that needs to be freed, but
+ // the dictionary will assume ownership when launch_data_dict_insert is
+ // called, so put it in a scoper and .release() it when given to the
+ // dictionary.
+ ScopedLaunchData job_label_launchd(launch_data_new_string(job_label.c_str()));
+ if (!job_label_launchd) {
+ NSLog(@"launch_data_new_string");
+ return NULL;
+ }
+
+ if (!launch_data_dict_insert(message,
+ job_label_launchd.release(),
+ operation)) {
+ return NULL;
+ }
+
+ return launch_msg(message);
+}
+
+pid_t PIDForJob(const std::string& job_label) {
+ ScopedLaunchData response(MessageForJob(job_label, LAUNCH_KEY_GETJOB));
+ if (!response) {
+ return -1;
+ }
+
+ launch_data_type_t response_type = launch_data_get_type(response);
+ if (response_type != LAUNCH_DATA_DICTIONARY) {
+ if (response_type == LAUNCH_DATA_ERRNO) {
+ NSLog(@"PIDForJob: error %d", launch_data_get_errno(response));
+ } else {
+ NSLog(@"PIDForJob: expected dictionary, got %d", response_type);
+ }
+ return -1;
+ }
+
+ launch_data_t pid_data = launch_data_dict_lookup(response,
+ LAUNCH_JOBKEY_PID);
+ if (!pid_data)
+ return 0;
+
+ if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) {
+ NSLog(@"PIDForJob: expected integer");
+ return -1;
+ }
+
+ return launch_data_get_integer(pid_data);
+}
+
+OSStatus ExecuteWithPrivilegesAndGetPID(AuthorizationRef authorization,
+ const char* tool_path,
+ AuthorizationFlags options,
+ const char** arguments,
+ FILE** pipe,
+ pid_t* pid) {
+ // pipe may be NULL, but this function needs one. In that case, use a local
+ // pipe.
+ FILE* local_pipe;
+ FILE** pipe_pointer;
+ if (pipe) {
+ pipe_pointer = pipe;
+ } else {
+ pipe_pointer = &local_pipe;
+ }
+
+ // AuthorizationExecuteWithPrivileges wants |char* const*| for |arguments|,
+ // but it doesn't actually modify the arguments, and that type is kind of
+ // silly and callers probably aren't dealing with that. Put the cast here
+ // to make things a little easier on callers.
+ OSStatus status = AuthorizationExecuteWithPrivileges(authorization,
+ tool_path,
+ options,
+ (char* const*)arguments,
+ pipe_pointer);
+ if (status != errAuthorizationSuccess) {
+ return status;
+ }
+
+ long line_pid = -1;
+ size_t line_length = 0;
+ char* line_c = fgetln(*pipe_pointer, &line_length);
+ if (line_c) {
+ if (line_length > 0 && line_c[line_length - 1] == '\n') {
+ // line_c + line_length is the start of the next line if there is one.
+ // Back up one character.
+ --line_length;
+ }
+ std::string line(line_c, line_length);
+
+ // The version in base/mac used base::StringToInt() here.
+ line_pid = strtol(line.c_str(), NULL, 10);
+ if (line_pid == 0) {
+ NSLog(@"ExecuteWithPrivilegesAndGetPid: funny line: %s", line.c_str());
+ line_pid = -1;
+ }
+ } else {
+ NSLog(@"ExecuteWithPrivilegesAndGetPid: no line");
+ }
+
+ if (!pipe) {
+ fclose(*pipe_pointer);
+ }
+
+ if (pid) {
+ *pid = line_pid;
+ }
+
+ return status;
+}
+
+} // namespace mac
+} // namespace base
+
namespace remoting {
JsonHostConfig::JsonHostConfig(const std::string& filename)
: filename_(filename) {
@@ -215,12 +343,15 @@ std::string JsonHostConfig::GetSerializedData() const {
[self updateAuthorizationStatus];
[self updateUI];
- std::string pin_utf8 = base::SysNSStringToUTF8(pin);
+ std::string pin_utf8 = [pin UTF8String];
std::string host_id, host_secret_hash;
bool result = (config_->GetString(remoting::kHostIdConfigPath, &host_id) &&
config_->GetString(remoting::kHostSecretHashConfigPath,
&host_secret_hash));
- DCHECK(result);
+ if (!result) {
+ [self showError];
+ return;
+ }
if (!IsPinValid(pin_utf8, host_id, host_secret_hash)) {
[self showIncorrectPinMessage];
return;
@@ -239,7 +370,7 @@ std::string JsonHostConfig::GetSerializedData() const {
if (![self runHelperAsRootWithCommand:"--disable"
inputData:""]) {
- LOG(ERROR) << "Failed to run the helper tool";
+ NSLog(@"Failed to run the helper tool");
[self showError];
[self notifyPlugin: kUpdateFailedNotificationName];
return;
@@ -293,7 +424,7 @@ std::string JsonHostConfig::GetSerializedData() const {
- (void)readNewConfig {
std::string file;
if (!GetTemporaryConfigFilePath(&file)) {
- LOG(ERROR) << "Failed to get path of configuration data.";
+ NSLog(@"Failed to get path of configuration data.");
[self showError];
return;
}
@@ -305,13 +436,13 @@ std::string JsonHostConfig::GetSerializedData() const {
if (!new_config_->Read()) {
// Report the error, because the file exists but couldn't be read. The
// case of non-existence is normal and expected.
- LOG(ERROR) << "Error reading configuration data from " << file.c_str();
+ NSLog(@"Error reading configuration data from %s", file.c_str());
[self showError];
return;
}
remove(file.c_str());
if (!IsConfigValid(new_config_.get())) {
- LOG(ERROR) << "Invalid configuration data read.";
+ NSLog(@"Invalid configuration data read.");
[self showError];
return;
}
@@ -352,14 +483,16 @@ std::string JsonHostConfig::GetSerializedData() const {
bool result = config_->GetString(remoting::kXmppLoginConfigPath, &email);
// The config has already been checked by |IsConfigValid|.
- DCHECK(result);
+ if (!result) {
+ [self showError];
+ return;
+ }
}
-
[disable_view_ setEnabled:(is_pane_unlocked_ && is_service_running_ &&
!restart_pending_or_canceled_)];
[confirm_pin_view_ setEnabled:(is_pane_unlocked_ &&
!restart_pending_or_canceled_)];
- [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)];
+ [confirm_pin_view_ setEmail:[NSString stringWithUTF8String:email.c_str()]];
NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable";
[confirm_pin_view_ setButtonText:applyButtonText];
@@ -396,7 +529,7 @@ std::string JsonHostConfig::GetSerializedData() const {
const char* command = is_service_running_ ? "--save-config" : "--enable";
if (![self runHelperAsRootWithCommand:command
inputData:serialized_config]) {
- LOG(ERROR) << "Failed to run the helper tool";
+ NSLog(@"Failed to run the helper tool");
[self showError];
return;
}
@@ -410,7 +543,7 @@ std::string JsonHostConfig::GetSerializedData() const {
if (job_pid > 0) {
kill(job_pid, SIGHUP);
} else {
- LOG(ERROR) << "Failed to obtain PID of service " << kServiceName;
+ NSLog(@"Failed to obtain PID of service " kServiceName);
[self showError];
}
} else {
@@ -427,7 +560,7 @@ std::string JsonHostConfig::GetSerializedData() const {
AuthorizationRef authorization =
[[authorization_view_ authorization] authorizationRef];
if (!authorization) {
- LOG(ERROR) << "Failed to obtain authorizationRef";
+ NSLog(@"Failed to obtain authorizationRef");
return NO;
}
@@ -445,18 +578,19 @@ std::string JsonHostConfig::GetSerializedData() const {
&pipe,
&pid);
if (status != errAuthorizationSuccess) {
- OSSTATUS_LOG(ERROR, status) << "AuthorizationExecuteWithPrivileges";
+ NSLog(@"AuthorizationExecuteWithPrivileges: %s (%d)",
+ GetMacOSStatusErrorString(status), static_cast<int>(status));
return NO;
}
if (pid == -1) {
- LOG(ERROR) << "Failed to get child PID";
+ NSLog(@"Failed to get child PID");
if (pipe)
fclose(pipe);
return NO;
}
if (!pipe) {
- LOG(ERROR) << "Unexpected NULL pipe";
+ NSLog(@"Unexpected NULL pipe");
return NO;
}
@@ -470,7 +604,7 @@ std::string JsonHostConfig::GetSerializedData() const {
// 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";
+ NSLog(@"Failed to write data to child process");
error = YES;
}
}
@@ -480,14 +614,14 @@ std::string JsonHostConfig::GetSerializedData() const {
// waitpid(), since the child reads until EOF on its stdin, so calling
// waitpid() first would result in deadlock.
if (fclose(pipe) != 0) {
- PLOG(ERROR) << "fclose";
+ NSLog(@"fclose failed with error %d", errno);
error = YES;
}
int exit_status;
pid_t wait_result = HANDLE_EINTR(waitpid(pid, &exit_status, 0));
if (wait_result != pid) {
- PLOG(ERROR) << "waitpid";
+ NSLog(@"waitpid failed with error %d", errno);
error = YES;
}
@@ -498,7 +632,7 @@ std::string JsonHostConfig::GetSerializedData() const {
if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) {
return YES;
} else {
- LOG(ERROR) << kHelperTool << " failed with exit status " << exit_status;
+ NSLog(@"%s failed with exit status %d", kHelperTool, exit_status);
return NO;
}
}
@@ -507,7 +641,7 @@ std::string JsonHostConfig::GetSerializedData() const {
base::mac::ScopedLaunchData response(
base::mac::MessageForJob(kServiceName, launch_key));
if (!response) {
- LOG(ERROR) << "Failed to send message to launchd";
+ NSLog(@"Failed to send message to launchd");
[self showError];
return NO;
}
@@ -515,14 +649,14 @@ std::string JsonHostConfig::GetSerializedData() const {
// Expect a response of type LAUNCH_DATA_ERRNO.
launch_data_type_t type = launch_data_get_type(response.get());
if (type != LAUNCH_DATA_ERRNO) {
- LOG(ERROR) << "launchd returned unexpected type: " << type;
+ NSLog(@"launchd returned unexpected type: %d", type);
[self showError];
return NO;
}
int error = launch_data_get_errno(response.get());
if (error) {
- LOG(ERROR) << "launchd returned error: " << error;
+ NSLog(@"launchd returned error: %d", error);
[self showError];
return NO;
}
@@ -556,7 +690,7 @@ std::string JsonHostConfig::GetSerializedData() const {
NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"];
if (disk_version == nil) {
- LOG(ERROR) << "Failed to get installed version information";
+ NSLog(@"Failed to get installed version information");
[self showError];
return;
}
@@ -616,7 +750,7 @@ std::string JsonHostConfig::GetSerializedData() const {
// There's no point in alerting the user here. The same error would
// happen when the pane is eventually restarted, so the user would be
// alerted at that time.
- LOG(ERROR) << "Failed to get path of configuration data.";
+ NSLog(@"Failed to get path of configuration data.");
return;
}
if (access(file.c_str(), F_OK) != 0)
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index d5fa23b..c636c86 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -386,10 +386,6 @@
'type': 'loadable_module',
'mac_bundle': 1,
'product_extension': 'prefPane',
- 'dependencies': [
- 'remoting_base',
- 'remoting_host',
- ],
'defines': [
'JSON_USE_EXCEPTION=0',
],
@@ -397,13 +393,20 @@
'../third_party/jsoncpp/overrides/include/',
'../third_party/jsoncpp/source/include/',
'../third_party/jsoncpp/source/src/lib_json/',
- ],
+ ],
+
+ # These source files are included directly, instead of adding target
+ # dependencies, because the targets are not yet built for 64-bit on
+ # Mac OS X - http://crbug.com/125116.
+ #
+ # TODO(lambroslambrou): Fix this when Chrome supports building for
+ # Mac OS X 64-bit - http://crbug.com/128122.
'sources': [
- # The jsoncpp target is not yet built for Mac OS X 64-bit, so
- # include the files directly, instead of depending on the target.
- '../third_party/jsoncpp/source/src/lib_json/json_reader.cpp',
- '../third_party/jsoncpp/source/src/lib_json/json_writer.cpp',
- '../third_party/modp_b64/modp_b64.cc',
+ '../third_party/jsoncpp/source/src/lib_json/json_reader.cpp',
+ '../third_party/jsoncpp/overrides/src/lib_json/json_value.cpp',
+ '../third_party/jsoncpp/source/src/lib_json/json_writer.cpp',
+ '../third_party/modp_b64/modp_b64.cc',
+ 'host/host_config.cc',
'host/me2me_preference_pane.h',
'host/me2me_preference_pane.mm',
'host/me2me_preference_pane_confirm_pin.h',
@@ -413,10 +416,15 @@
],
'link_settings': {
'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
+ '$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
'$(SDKROOT)/System/Library/Frameworks/PreferencePanes.framework',
+ '$(SDKROOT)/System/Library/Frameworks/Security.framework',
],
},
'xcode_settings': {
+ 'ARCHS': ['i386', 'x86_64'],
+ 'GCC_ENABLE_OBJC_GC': 'supported',
'INFOPLIST_FILE': 'host/me2me_preference_pane-Info.plist',
'INFOPLIST_PREPROCESS': 'YES',
'INFOPLIST_PREPROCESSOR_DEFINITIONS': 'VERSION_FULL="<(version_full)" VERSION_SHORT="<(version_short)" BUNDLE_NAME="<(bundle_name)" BUNDLE_ID="<(bundle_id)" COPYRIGHT_BY="<(copyright_by)" PREF_PANE_ICON_LABEL="<(pref_pane_icon_label)"',