diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-05 20:30:08 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-05 20:30:08 +0000 |
commit | 8fd673a1f1baf1aac390b2b635e4636ed357886c (patch) | |
tree | f11293e8233516105841209377249a5f595c58a0 | |
parent | 42e35e532b9d29fa6ef6b8dc9a0f78dd5586e85f (diff) | |
download | chromium_src-8fd673a1f1baf1aac390b2b635e4636ed357886c.zip chromium_src-8fd673a1f1baf1aac390b2b635e4636ed357886c.tar.gz chromium_src-8fd673a1f1baf1aac390b2b635e4636ed357886c.tar.bz2 |
Added auto-enrollment request support to the device_management_backend.
Also extended the testserver's device_management.py handler to serve these
requests.
BUG=chromium-os:23063
TEST=unit_tests and browser_tests all pass
Review URL: http://codereview.chromium.org/8741014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113009 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 190 insertions, 2 deletions
diff --git a/chrome/browser/policy/device_management_backend.h b/chrome/browser/policy/device_management_backend.h index 9e8ec63..a832373 100644 --- a/chrome/browser/policy/device_management_backend.h +++ b/chrome/browser/policy/device_management_backend.h @@ -99,6 +99,21 @@ class DeviceManagementBackend : base::NonThreadSafe { DISALLOW_COPY_AND_ASSIGN(DevicePolicyResponseDelegate); }; + class DeviceAutoEnrollmentResponseDelegate { + public: + virtual ~DeviceAutoEnrollmentResponseDelegate() {} + + virtual void HandleAutoEnrollmentResponse( + const em::DeviceAutoEnrollmentResponse& response) = 0; + virtual void OnError(ErrorCode code) = 0; + + protected: + DeviceAutoEnrollmentResponseDelegate() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceAutoEnrollmentResponseDelegate); + }; + virtual ~DeviceManagementBackend() {} virtual void ProcessRegisterRequest( @@ -121,6 +136,11 @@ class DeviceManagementBackend : base::NonThreadSafe { const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* delegate) = 0; + virtual void ProcessAutoEnrollmentRequest( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate) = 0; + protected: DeviceManagementBackend() {} diff --git a/chrome/browser/policy/device_management_backend_impl.cc b/chrome/browser/policy/device_management_backend_impl.cc index 5143b21..42b92cb 100644 --- a/chrome/browser/policy/device_management_backend_impl.cc +++ b/chrome/browser/policy/device_management_backend_impl.cc @@ -37,6 +37,8 @@ const char DeviceManagementBackendImpl::kParamUserAffiliation[] = // String constants for the device and app type we report to the server. const char DeviceManagementBackendImpl::kValueAppType[] = "Chrome"; const char DeviceManagementBackendImpl::kValueDeviceType[] = "2"; +const char DeviceManagementBackendImpl::kValueRequestAutoEnrollment[] = + "enterprise_check"; const char DeviceManagementBackendImpl::kValueRequestPolicy[] = "policy"; const char DeviceManagementBackendImpl::kValueRequestRegister[] = "register"; const char DeviceManagementBackendImpl::kValueRequestUnregister[] = @@ -457,6 +459,43 @@ class DeviceManagementPolicyJob : public DeviceManagementJobBase { DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob); }; +// Handles auto enrollment request jobs. These are used to determine if a new +// ChromiumOS device should automatically enter the enterprise enrollment screen +// during the OOBE flow. +class DeviceManagementAutoEnrollmentJob : public DeviceManagementJobBase { + public: + DeviceManagementAutoEnrollmentJob( + DeviceManagementBackendImpl* backend_impl, + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceManagementBackend::DeviceAutoEnrollmentResponseDelegate* delegate) + : DeviceManagementJobBase( + backend_impl, + DeviceManagementBackendImpl::kValueRequestAutoEnrollment, + device_id), + delegate_(delegate) { + em::DeviceManagementRequest request_wrapper; + request_wrapper.mutable_auto_enrollment_request()->CopyFrom(request); + SetPayload(request_wrapper); + } + virtual ~DeviceManagementAutoEnrollmentJob() {} + + private: + // DeviceManagementJobBase overrides. + virtual void OnError(DeviceManagementBackend::ErrorCode error) OVERRIDE { + delegate_->OnError(error); + } + virtual void OnResponse( + const em::DeviceManagementResponse& response) OVERRIDE { + delegate_->HandleAutoEnrollmentResponse( + response.auto_enrollment_response()); + } + + DeviceManagementBackend::DeviceAutoEnrollmentResponseDelegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(DeviceManagementAutoEnrollmentJob); +}; + DeviceManagementBackendImpl::DeviceManagementBackendImpl( DeviceManagementService* service) : service_(service) { @@ -571,6 +610,14 @@ void DeviceManagementBackendImpl::ProcessPolicyRequest( request, delegate)); } +void DeviceManagementBackendImpl::ProcessAutoEnrollmentRequest( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate) { + AddJob(new DeviceManagementAutoEnrollmentJob(this, device_id, request, + delegate)); +} + // static const char* DeviceManagementBackendImpl::UserAffiliationToString( CloudPolicyDataStore::UserAffiliation affiliation) { diff --git a/chrome/browser/policy/device_management_backend_impl.h b/chrome/browser/policy/device_management_backend_impl.h index ff4f3ff..2848882 100644 --- a/chrome/browser/policy/device_management_backend_impl.h +++ b/chrome/browser/policy/device_management_backend_impl.h @@ -40,6 +40,7 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend { // String constants for the device and app type we report to the server. static const char kValueAppType[]; static const char kValueDeviceType[]; + static const char kValueRequestAutoEnrollment[]; static const char kValueRequestPolicy[]; static const char kValueRequestRegister[]; static const char kValueRequestUnregister[]; @@ -76,6 +77,10 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend { CloudPolicyDataStore::UserAffiliation affiliation, const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* response_delegate) OVERRIDE; + virtual void ProcessAutoEnrollmentRequest( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate) OVERRIDE; // Converts a user affiliation to the appropriate query parameter value. static const char* UserAffiliationToString( diff --git a/chrome/browser/policy/device_management_backend_mock.cc b/chrome/browser/policy/device_management_backend_mock.cc index b8dcf5f..e5d1661 100644 --- a/chrome/browser/policy/device_management_backend_mock.cc +++ b/chrome/browser/policy/device_management_backend_mock.cc @@ -18,4 +18,10 @@ DevicePolicyResponseDelegateMock::DevicePolicyResponseDelegateMock() {} DevicePolicyResponseDelegateMock::~DevicePolicyResponseDelegateMock() {} +DeviceAutoEnrollmentResponseDelegateMock:: + DeviceAutoEnrollmentResponseDelegateMock() {} + +DeviceAutoEnrollmentResponseDelegateMock:: + ~DeviceAutoEnrollmentResponseDelegateMock() {} + } // namespace policy diff --git a/chrome/browser/policy/device_management_backend_mock.h b/chrome/browser/policy/device_management_backend_mock.h index a3dbcd6..62b0c2d 100644 --- a/chrome/browser/policy/device_management_backend_mock.h +++ b/chrome/browser/policy/device_management_backend_mock.h @@ -44,6 +44,17 @@ class DevicePolicyResponseDelegateMock MOCK_METHOD1(OnError, void(DeviceManagementBackend::ErrorCode error)); }; +class DeviceAutoEnrollmentResponseDelegateMock + : public DeviceManagementBackend::DeviceAutoEnrollmentResponseDelegate { + public: + DeviceAutoEnrollmentResponseDelegateMock(); + virtual ~DeviceAutoEnrollmentResponseDelegateMock(); + + MOCK_METHOD1(HandleAutoEnrollmentResponse, + void(const em::DeviceAutoEnrollmentResponse&)); + MOCK_METHOD1(OnError, void(DeviceManagementBackend::ErrorCode error)); +}; + } // namespace policy #endif // CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_BACKEND_MOCK_H_ diff --git a/chrome/browser/policy/device_management_service_browsertest.cc b/chrome/browser/policy/device_management_service_browsertest.cc index 14e3415..b0f1d59 100644 --- a/chrome/browser/policy/device_management_service_browsertest.cc +++ b/chrome/browser/policy/device_management_service_browsertest.cc @@ -6,8 +6,6 @@ #include "chrome/browser/policy/device_management_backend_mock.h" #include "chrome/browser/policy/device_management_service.h" #include "chrome/browser/policy/proto/device_management_constants.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/common/url_fetcher.h" #include "net/test/test_server.h" @@ -39,6 +37,9 @@ const char kServiceResponsePolicy[] = // Successful unregister response. const char kServiceResponseUnregister[] = "\x08\x00\x22\x00"; +// Auto-enrollment response with no modulus and no hashes. +const char kServiceResponseAutoEnrollment[] = "\x42\x00"; + #define PROTO_STRING(name) (std::string(name, arraysize(name) - 1)) @@ -138,6 +139,20 @@ IN_PROC_BROWSER_TEST_F(DeviceManagementServiceIntegrationTest, MessageLoop::current()->Run(); } + + { + CannedResponseInterceptor interceptor( + GURL(kServiceUrl), PROTO_STRING(kServiceResponseAutoEnrollment)); + DeviceAutoEnrollmentResponseDelegateMock delegate; + EXPECT_CALL(delegate, HandleAutoEnrollmentResponse(_)) + .WillOnce(InvokeWithoutArgs(QuitMessageLoop)); + em::DeviceAutoEnrollmentRequest request; + request.set_remainder(0); + request.set_modulus(1); + backend->ProcessAutoEnrollmentRequest("testid", request, &delegate); + + MessageLoop::current()->Run(); + } } IN_PROC_BROWSER_TEST_F(DeviceManagementServiceIntegrationTest, @@ -189,6 +204,18 @@ IN_PROC_BROWSER_TEST_F(DeviceManagementServiceIntegrationTest, MessageLoop::current()->Run(); } + + { + DeviceAutoEnrollmentResponseDelegateMock delegate; + EXPECT_CALL(delegate, HandleAutoEnrollmentResponse(_)) + .WillOnce(InvokeWithoutArgs(QuitMessageLoop)); + em::DeviceAutoEnrollmentRequest request; + request.set_modulus(1); + request.set_remainder(0); + backend->ProcessAutoEnrollmentRequest("testid", request, &delegate); + + MessageLoop::current()->Run(); + } } } // namespace policy diff --git a/chrome/browser/policy/device_management_service_unittest.cc b/chrome/browser/policy/device_management_service_unittest.cc index 00bc701..9af4a0a 100644 --- a/chrome/browser/policy/device_management_service_unittest.cc +++ b/chrome/browser/policy/device_management_service_unittest.cc @@ -165,6 +165,23 @@ TEST_P(DeviceManagementServiceFailedRequestTest, PolicyRequest) { fetcher->delegate()->OnURLFetchComplete(fetcher); } +TEST_P(DeviceManagementServiceFailedRequestTest, AutoEnrollmentRequest) { + DeviceAutoEnrollmentResponseDelegateMock mock; + EXPECT_CALL(mock, OnError(GetParam().expected_error_)); + em::DeviceAutoEnrollmentRequest request; + request.set_modulus(1); + request.set_remainder(0); + backend_->ProcessAutoEnrollmentRequest(kDeviceId, request, &mock); + TestURLFetcher* fetcher = factory_.GetFetcherByID(0); + ASSERT_TRUE(fetcher); + + fetcher->set_url(GURL(kServiceUrl)); + fetcher->set_status(GetParam().request_status_); + fetcher->set_response_code(GetParam().http_status_); + fetcher->SetResponseString(GetParam().response_); + fetcher->delegate()->OnURLFetchComplete(fetcher); +} + INSTANTIATE_TEST_CASE_P( DeviceManagementServiceFailedRequestTestInstance, DeviceManagementServiceFailedRequestTest, diff --git a/chrome/browser/policy/mock_device_management_backend.h b/chrome/browser/policy/mock_device_management_backend.h index 4e4a7c2..de517cd 100644 --- a/chrome/browser/policy/mock_device_management_backend.h +++ b/chrome/browser/policy/mock_device_management_backend.h @@ -49,6 +49,11 @@ class MockDeviceManagementBackend : public DeviceManagementBackend { const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* delegate)); + MOCK_METHOD3(ProcessAutoEnrollmentRequest, void( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate)); + private: DISALLOW_COPY_AND_ASSIGN(MockDeviceManagementBackend); }; diff --git a/chrome/browser/policy/mock_device_management_service.cc b/chrome/browser/policy/mock_device_management_service.cc index 6bf0fab..555c65e 100644 --- a/chrome/browser/policy/mock_device_management_service.cc +++ b/chrome/browser/policy/mock_device_management_service.cc @@ -41,6 +41,13 @@ void ProxyDeviceManagementBackend::ProcessPolicyRequest( affiliation, request, delegate); } +void ProxyDeviceManagementBackend::ProcessAutoEnrollmentRequest( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate) { + backend_->ProcessAutoEnrollmentRequest(device_id, request, delegate); +} + MockDeviceManagementService::MockDeviceManagementService() : DeviceManagementService("") {} diff --git a/chrome/browser/policy/mock_device_management_service.h b/chrome/browser/policy/mock_device_management_service.h index ce29980..786908d 100644 --- a/chrome/browser/policy/mock_device_management_service.h +++ b/chrome/browser/policy/mock_device_management_service.h @@ -42,6 +42,10 @@ class ProxyDeviceManagementBackend : public DeviceManagementBackend { CloudPolicyDataStore::UserAffiliation affiliation, const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* delegate) OVERRIDE; + virtual void ProcessAutoEnrollmentRequest( + const std::string& device_id, + const em::DeviceAutoEnrollmentRequest& request, + DeviceAutoEnrollmentResponseDelegate* delegate) OVERRIDE; private: DeviceManagementBackend* backend_; // weak diff --git a/net/tools/testserver/device_management.py b/net/tools/testserver/device_management.py index bbcc4f0..231669c 100644 --- a/net/tools/testserver/device_management.py +++ b/net/tools/testserver/device_management.py @@ -44,6 +44,7 @@ Example: """ import cgi +import hashlib import logging import os import random @@ -71,6 +72,9 @@ import chrome_device_policy_pb2 as dp # ASN.1 object identifier for PKCS#1/RSA. PKCS1_RSA_OID = '\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01' +# SHA256 sum of "0". +SHA256_0 = hashlib.sha256('0').digest() + class RequestHandler(object): """Decodes and handles device management requests from clients. @@ -144,6 +148,8 @@ class RequestHandler(object): return self.ProcessUnregister(rmsg.unregister_request) elif request_type == 'policy' or request_type == 'ping': return self.ProcessPolicy(rmsg.policy_request, request_type) + elif request_type == 'enterprise_check': + return self.ProcessAutoEnrollment(rmsg.auto_enrollment_request) else: return (400, 'Invalid request parameter') @@ -254,6 +260,39 @@ class RequestHandler(object): else: return (400, 'Invalid policy_type') + def ProcessAutoEnrollment(self, msg): + """Handles an auto-enrollment check request. + + The reply depends on the value of the modulus: + 1: replies with no new modulus and the sha256 hash of "0" + 2: replies with a new modulus, 4. + 4: replies with a new modulus, 2. + 8: fails with error 400. + anything else: replies with no new modulus and an empty list of hashes + + These allow the client to pick the testing scenario its wants to simulate. + + Args: + msg: The DeviceAutoEnrollmentRequest message received from the client. + + Returns: + A tuple of HTTP status code and response data to send to the client. + """ + auto_enrollment_response = dm.DeviceAutoEnrollmentResponse() + + if msg.modulus == 1: + auto_enrollment_response.hashes.append(SHA256_0) + elif msg.modulus == 2: + auto_enrollment_response.modulus = 4 + elif msg.modulus == 4: + auto_enrollment_response.modulus = 2 + elif msg.modulus == 8: + return (400, 'Server error') + + response = dm.DeviceManagementResponse() + response.auto_enrollment_response.CopyFrom(auto_enrollment_response) + return (200, response.SerializeToString()) + def SetProtobufMessageField(self, group_message, field, field_value): '''Sets a field in a protobuf message. |