summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chrome_browser_main_mac.mm12
-rw-r--r--chrome/browser/mac/keychain_reauthorize.h25
-rw-r--r--chrome/browser/mac/keychain_reauthorize.mm (renamed from chrome/browser/mac/keychain_reauthorize.cc)28
-rw-r--r--chrome/chrome_browser.gypi2
4 files changed, 66 insertions, 1 deletions
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm
index 7816a2cb..b095e20 100644
--- a/chrome/browser/chrome_browser_main_mac.mm
+++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -17,6 +17,7 @@
#import "chrome/browser/app_controller_mac.h"
#import "chrome/browser/chrome_browser_application_mac.h"
#include "chrome/browser/mac/install_from_dmg.h"
+#include "chrome/browser/mac/keychain_reauthorize.h"
#import "chrome/browser/mac/keystone_glue.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/common/chrome_paths.h"
@@ -135,6 +136,17 @@ void ChromeBrowserMainPartsMac::PreMainMessageLoopStart() {
// |-application:openFiles:|, since we already handle them directly.
[[NSUserDefaults standardUserDefaults]
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
+
+ // Do Keychain reauthorization. This gets two chances to run. If the first
+ // try doesn't complete successfully (crashes or is interrupted for any
+ // reason), there will be a second chance. Once this step completes
+ // successfully, it should never have to run again.
+ NSString* const keychain_reauthorize_pref =
+ @"KeychainReauthorizeInAppMay2012";
+ const int kKeychainReauthorizeMaxTries = 2;
+
+ chrome::browser::mac::KeychainReauthorizeIfNeeded(
+ keychain_reauthorize_pref, kKeychainReauthorizeMaxTries);
}
void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
diff --git a/chrome/browser/mac/keychain_reauthorize.h b/chrome/browser/mac/keychain_reauthorize.h
index 823f47a..8afa695 100644
--- a/chrome/browser/mac/keychain_reauthorize.h
+++ b/chrome/browser/mac/keychain_reauthorize.h
@@ -6,6 +6,12 @@
#define CHROME_BROWSER_MAC_KEYCHAIN_REAUTHORIZE_H_
#pragma once
+#ifdef __OBJC__
+@class NSString;
+#else
+class NSString;
+#endif
+
namespace chrome {
namespace browser {
namespace mac {
@@ -24,6 +30,25 @@ namespace mac {
// decrypt those items), but any application can remove a Keychain item.
void KeychainReauthorize();
+// Calls KeychainReauthorize, but only if it's determined that it's necessary.
+// pref_key is looked up in the system's standard user defaults (preferences)
+// and if its integer value is less than max_tries, KeychainReauthorize is
+// attempted. Before the attempt, the preference is incremented, allowing a
+// finite number of incomplete attempts at performing the KeychainReauthorize
+// operation. When the step completes successfully, the preference is set to
+// max_tries to prevent further attempts, and the preference name with the
+// word "Success" appended is also stored with a boolean value of YES,
+// disambiguating between the cases where the step completed successfully and
+// the step completed unsuccessfully while reaching the maximum number of
+// tries.
+//
+// The system's standard user defaults for the application are used
+// (~/Library/Preferences/com.google.Chrome.plist,
+// com.google.Chrome.canary.plist, etc.) instead of Chrome preferences because
+// Keychain access is tied more closely to the bundle identifier and signed
+// product than it is to any specific profile (--user-data-dir).
+void KeychainReauthorizeIfNeeded(NSString* pref_key, int max_tries);
+
} // namespace mac
} // namespace browser
} // namespace chrome
diff --git a/chrome/browser/mac/keychain_reauthorize.cc b/chrome/browser/mac/keychain_reauthorize.mm
index b7617ac..5b94889 100644
--- a/chrome/browser/mac/keychain_reauthorize.cc
+++ b/chrome/browser/mac/keychain_reauthorize.mm
@@ -4,6 +4,7 @@
#include "chrome/browser/mac/keychain_reauthorize.h"
+#import <Foundation/Foundation.h>
#include <Security/Security.h>
#include <algorithm>
@@ -14,6 +15,7 @@
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
#include "base/stringprintf.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/mac/security_wrappers.h"
@@ -119,6 +121,32 @@ void KeychainReauthorize() {
WriteKCItemsAndReauthorizedAccesses(items_and_reauthorized_accesses);
}
+void KeychainReauthorizeIfNeeded(NSString* pref_key, int max_tries) {
+ NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults];
+ int pref_value = [user_defaults integerForKey:pref_key];
+
+ if (pref_value < max_tries) {
+ if (pref_value > 0) {
+ // Logs the number of previous tries that didn't complete.
+ UMA_HISTOGRAM_COUNTS("OSX.KeychainReauthorizeIfNeeded", pref_value);
+ }
+
+ ++pref_value;
+ [user_defaults setInteger:pref_value forKey:pref_key];
+ [user_defaults synchronize];
+
+ chrome::browser::mac::KeychainReauthorize();
+
+ [user_defaults setInteger:max_tries forKey:pref_key];
+ NSString* success_pref_key = [pref_key stringByAppendingString:@"Success"];
+ [user_defaults setBool:YES forKey:success_pref_key];
+ [user_defaults synchronize];
+
+ // Logs the try number (1, 2) that succeeded.
+ UMA_HISTOGRAM_COUNTS("OSX.KeychainReauthorizeIfNeededSuccess", pref_value);
+ }
+}
+
namespace {
std::vector<std::string> RequirementMatches() {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index b11b279..ec1da5e 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1307,8 +1307,8 @@
'browser/mac/dock.mm',
'browser/mac/install_from_dmg.h',
'browser/mac/install_from_dmg.mm',
- 'browser/mac/keychain_reauthorize.cc',
'browser/mac/keychain_reauthorize.h',
+ 'browser/mac/keychain_reauthorize.mm',
'browser/mac/keystone_glue.h',
'browser/mac/keystone_glue.mm',
'browser/mac/keystone_registration.h',