OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """A bare-bones test server for testing cloud policy support. | 5 """A bare-bones test server for testing cloud policy support. |
6 | 6 |
7 This implements a simple cloud policy test server that can be used to test | 7 This implements a simple cloud policy test server that can be used to test |
8 chrome's device management service client. The policy information is read from | 8 chrome's device management service client. The policy information is read from |
9 the file named device_management in the server's data directory. It contains | 9 the file named device_management in the server's data directory. It contains |
10 enforced and recommended policies for the device and user scope, and a list | 10 enforced and recommended policies for the device and user scope, and a list |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
436 """ | 436 """ |
437 token_info, error = self.CheckToken() | 437 token_info, error = self.CheckToken() |
438 if not token_info: | 438 if not token_info: |
439 return error | 439 return error |
440 | 440 |
441 key_update_request = msg.device_state_key_update_request | 441 key_update_request = msg.device_state_key_update_request |
442 if len(key_update_request.server_backed_state_key) > 0: | 442 if len(key_update_request.server_backed_state_key) > 0: |
443 self.server.UpdateStateKeys(token_info['device_token'], | 443 self.server.UpdateStateKeys(token_info['device_token'], |
444 key_update_request.server_backed_state_key) | 444 key_update_request.server_backed_state_key) |
445 | 445 |
446 # If this is a publicaccount request then get the username now and use it | |
bartfab (slow)
2014/06/20 09:17:25
Nit 1: s/publicaccount/|publicaccount|/
Nit 2: s/u
Joao da Silva
2014/06/20 11:48:46
Done.
| |
447 # in every PolicyFetchResponse produced. This is required to validate | |
448 # policy for extensions in public accounts. | |
bartfab (slow)
2014/06/20 09:17:25
1: Nit: s/accounts/sessions/
2: Do we use the |pub
Joao da Silva
2014/06/20 11:48:46
Done.
| |
449 username = self.server.GetPolicies().get('policy_user', None) | |
bartfab (slow)
2014/06/20 09:17:25
1: Why is this needed? The code is prepared to han
Joao da Silva
2014/06/20 11:48:46
Done.
| |
450 for request in msg.policy_request.request: | |
451 if request.policy_type == 'google/chromeos/publicaccount': | |
452 username = request.settings_entity_id | |
bartfab (slow)
2014/06/20 09:17:25
What happens if we get requests for multiple publi
Joao da Silva
2014/06/20 11:48:46
Then this doesn't work :-) The current client impl
| |
453 | |
446 response = dm.DeviceManagementResponse() | 454 response = dm.DeviceManagementResponse() |
447 for request in msg.policy_request.request: | 455 for request in msg.policy_request.request: |
448 if (request.policy_type in | 456 if (request.policy_type in |
449 ('google/android/user', | 457 ('google/android/user', |
450 'google/chromeos/device', | 458 'google/chromeos/device', |
451 'google/chromeos/publicaccount', | 459 'google/chromeos/publicaccount', |
452 'google/chromeos/user', | 460 'google/chromeos/user', |
453 'google/chrome/user', | 461 'google/chrome/user', |
454 'google/ios/user')): | 462 'google/ios/user')): |
455 fetch_response = response.policy_response.response.add() | 463 fetch_response = response.policy_response.response.add() |
456 self.ProcessCloudPolicy(request, token_info, fetch_response) | 464 self.ProcessCloudPolicy(request, token_info, fetch_response) |
457 elif request.policy_type == 'google/chrome/extension': | 465 elif request.policy_type == 'google/chrome/extension': |
458 self.ProcessCloudPolicyForExtensions( | 466 self.ProcessCloudPolicyForExtensions( |
459 request, response.policy_response, token_info) | 467 request, response.policy_response, token_info, username) |
460 else: | 468 else: |
461 fetch_response.error_code = 400 | 469 fetch_response.error_code = 400 |
462 fetch_response.error_message = 'Invalid policy_type' | 470 fetch_response.error_message = 'Invalid policy_type' |
463 | 471 |
464 return (200, response) | 472 return (200, response) |
465 | 473 |
466 def ProcessAutoEnrollment(self, msg): | 474 def ProcessAutoEnrollment(self, msg): |
467 """Handles an auto-enrollment check request. | 475 """Handles an auto-enrollment check request. |
468 | 476 |
469 The reply depends on the value of the modulus: | 477 The reply depends on the value of the modulus: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 else: | 629 else: |
622 continue | 630 continue |
623 | 631 |
624 # Create protobuf message for this policy. | 632 # Create protobuf message for this policy. |
625 policy_message = eval('cp.' + field.message_type.name + '()') | 633 policy_message = eval('cp.' + field.message_type.name + '()') |
626 policy_message.policy_options.mode = mode | 634 policy_message.policy_options.mode = mode |
627 field_descriptor = policy_message.DESCRIPTOR.fields_by_name['value'] | 635 field_descriptor = policy_message.DESCRIPTOR.fields_by_name['value'] |
628 self.SetProtobufMessageField(policy_message, field_descriptor, value) | 636 self.SetProtobufMessageField(policy_message, field_descriptor, value) |
629 settings.__getattribute__(field.name).CopyFrom(policy_message) | 637 settings.__getattribute__(field.name).CopyFrom(policy_message) |
630 | 638 |
631 def ProcessCloudPolicyForExtensions(self, request, response, token_info): | 639 def ProcessCloudPolicyForExtensions(self, request, response, token_info, |
640 username): | |
632 """Handles a request for policy for extensions. | 641 """Handles a request for policy for extensions. |
633 | 642 |
634 A request for policy for extensions is slightly different from the other | 643 A request for policy for extensions is slightly different from the other |
635 cloud policy requests, because it can trigger 0, one or many | 644 cloud policy requests, because it can trigger 0, one or many |
636 PolicyFetchResponse messages in the response. | 645 PolicyFetchResponse messages in the response. |
637 | 646 |
638 Args: | 647 Args: |
639 request: The PolicyFetchRequest that triggered this handler. | 648 request: The PolicyFetchRequest that triggered this handler. |
640 response: The DevicePolicyResponse message for the response. Multiple | 649 response: The DevicePolicyResponse message for the response. Multiple |
641 PolicyFetchResponses will be appended to this message. | 650 PolicyFetchResponses will be appended to this message. |
642 token_info: The token extracted from the request. | 651 token_info: The token extracted from the request. |
652 username: The username for the response. | |
bartfab (slow)
2014/06/20 09:17:25
Nit: Add "May be None."
Joao da Silva
2014/06/20 11:48:46
Done.
| |
643 """ | 653 """ |
644 # Send one PolicyFetchResponse for each extension that has | 654 # Send one PolicyFetchResponse for each extension that has |
645 # configuration data at the server. | 655 # configuration data at the server. |
646 ids = self.server.ListMatchingComponents('google/chrome/extension') | 656 ids = self.server.ListMatchingComponents('google/chrome/extension') |
647 for settings_entity_id in ids: | 657 for settings_entity_id in ids: |
648 # Reuse the extension policy request, to trigger the same signature | 658 # Reuse the extension policy request, to trigger the same signature |
649 # type in the response. | 659 # type in the response. |
650 request.settings_entity_id = settings_entity_id | 660 request.settings_entity_id = settings_entity_id |
651 fetch_response = response.response.add() | 661 fetch_response = response.response.add() |
652 self.ProcessCloudPolicy(request, token_info, fetch_response) | 662 self.ProcessCloudPolicy(request, token_info, fetch_response, username) |
653 # Don't do key rotations for these messages. | 663 # Don't do key rotations for these messages. |
654 fetch_response.ClearField('new_public_key') | 664 fetch_response.ClearField('new_public_key') |
655 fetch_response.ClearField('new_public_key_signature') | 665 fetch_response.ClearField('new_public_key_signature') |
656 fetch_response.ClearField('new_public_key_verification_signature') | 666 fetch_response.ClearField('new_public_key_verification_signature') |
657 | 667 |
658 def ProcessCloudPolicy(self, msg, token_info, response): | 668 def ProcessCloudPolicy(self, msg, token_info, response, username=None): |
659 """Handles a cloud policy request. (New protocol for policy requests.) | 669 """Handles a cloud policy request. (New protocol for policy requests.) |
660 | 670 |
661 Encodes the policy into protobuf representation, signs it and constructs | 671 Encodes the policy into protobuf representation, signs it and constructs |
662 the response. | 672 the response. |
663 | 673 |
664 Args: | 674 Args: |
665 msg: The CloudPolicyRequest message received from the client. | 675 msg: The CloudPolicyRequest message received from the client. |
666 token_info: The token extracted from the request. | 676 token_info: The token extracted from the request. |
667 response: A PolicyFetchResponse message that should be filled with the | 677 response: A PolicyFetchResponse message that should be filled with the |
668 response data. | 678 response data. |
679 username: The username for the response. May be None. | |
669 """ | 680 """ |
670 | 681 |
671 if msg.machine_id: | 682 if msg.machine_id: |
672 self.server.UpdateMachineId(token_info['device_token'], msg.machine_id) | 683 self.server.UpdateMachineId(token_info['device_token'], msg.machine_id) |
673 | 684 |
674 # Response is only given if the scope is specified in the config file. | 685 # Response is only given if the scope is specified in the config file. |
675 # Normally 'google/chromeos/device', 'google/chromeos/user' and | 686 # Normally 'google/chromeos/device', 'google/chromeos/user' and |
676 # 'google/chromeos/publicaccount' should be accepted. | 687 # 'google/chromeos/publicaccount' should be accepted. |
677 policy = self.server.GetPolicies() | 688 policy = self.server.GetPolicies() |
678 policy_value = '' | 689 policy_value = '' |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
739 if invalidation_source is not None: | 750 if invalidation_source is not None: |
740 policy_data.invalidation_source = invalidation_source | 751 policy_data.invalidation_source = invalidation_source |
741 # Since invalidation_name is type bytes in the proto, the Unicode name | 752 # Since invalidation_name is type bytes in the proto, the Unicode name |
742 # provided needs to be encoded as ASCII to set the correct byte pattern. | 753 # provided needs to be encoded as ASCII to set the correct byte pattern. |
743 invalidation_name = policy.get('invalidation_name') | 754 invalidation_name = policy.get('invalidation_name') |
744 if invalidation_name is not None: | 755 if invalidation_name is not None: |
745 policy_data.invalidation_name = invalidation_name.encode('ascii') | 756 policy_data.invalidation_name = invalidation_name.encode('ascii') |
746 | 757 |
747 if signing_key: | 758 if signing_key: |
748 policy_data.public_key_version = current_key_index + 1 | 759 policy_data.public_key_version = current_key_index + 1 |
749 if msg.policy_type == 'google/chromeos/publicaccount': | 760 |
761 if username: | |
762 policy_data.username = username | |
bartfab (slow)
2014/06/20 09:17:25
Why can we not extract the username from |msg| her
Joao da Silva
2014/06/20 11:48:46
Because the |msg| here is one of the repeated Poli
| |
763 elif msg.policy_type == 'google/chromeos/publicaccount': | |
750 policy_data.username = msg.settings_entity_id | 764 policy_data.username = msg.settings_entity_id |
751 else: | 765 else: |
752 # For regular user/device policy, there is no way for the testserver to | 766 # For regular user/device policy, there is no way for the testserver to |
753 # know the user name belonging to the GAIA auth token we received (short | 767 # know the user name belonging to the GAIA auth token we received (short |
754 # of actually talking to GAIA). To address this, we read the username from | 768 # of actually talking to GAIA). To address this, we read the username from |
755 # the policy configuration dictionary, or use a default. | 769 # the policy configuration dictionary, or use a default. |
756 policy_data.username = policy.get('policy_user', 'user@example.com') | 770 policy_data.username = policy.get('policy_user', 'user@example.com') |
757 policy_data.device_id = token_info['device_id'] | 771 policy_data.device_id = token_info['device_id'] |
758 signed_data = policy_data.SerializeToString() | 772 signed_data = policy_data.SerializeToString() |
759 | 773 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
953 dm.DeviceRegisterRequest.BROWSER: [ | 967 dm.DeviceRegisterRequest.BROWSER: [ |
954 'google/chrome/user', | 968 'google/chrome/user', |
955 'google/chrome/extension' | 969 'google/chrome/extension' |
956 ], | 970 ], |
957 dm.DeviceRegisterRequest.USER: [ | 971 dm.DeviceRegisterRequest.USER: [ |
958 'google/chromeos/user', | 972 'google/chromeos/user', |
959 'google/chrome/extension' | 973 'google/chrome/extension' |
960 ], | 974 ], |
961 dm.DeviceRegisterRequest.DEVICE: [ | 975 dm.DeviceRegisterRequest.DEVICE: [ |
962 'google/chromeos/device', | 976 'google/chromeos/device', |
963 'google/chromeos/publicaccount' | 977 'google/chromeos/publicaccount', |
978 'google/chrome/extension' | |
964 ], | 979 ], |
965 dm.DeviceRegisterRequest.ANDROID_BROWSER: [ | 980 dm.DeviceRegisterRequest.ANDROID_BROWSER: [ |
966 'google/android/user' | 981 'google/android/user' |
967 ], | 982 ], |
968 dm.DeviceRegisterRequest.IOS_BROWSER: [ | 983 dm.DeviceRegisterRequest.IOS_BROWSER: [ |
969 'google/ios/user' | 984 'google/ios/user' |
970 ], | 985 ], |
971 dm.DeviceRegisterRequest.TT: ['google/chromeos/user', | 986 dm.DeviceRegisterRequest.TT: ['google/chromeos/user', |
972 'google/chrome/user'], | 987 'google/chrome/user'], |
973 } | 988 } |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1225 if (self.options.log_to_console): | 1240 if (self.options.log_to_console): |
1226 logger.addHandler(logging.StreamHandler()) | 1241 logger.addHandler(logging.StreamHandler()) |
1227 if (self.options.log_file): | 1242 if (self.options.log_file): |
1228 logger.addHandler(logging.FileHandler(self.options.log_file)) | 1243 logger.addHandler(logging.FileHandler(self.options.log_file)) |
1229 | 1244 |
1230 testserver_base.TestServerRunner.run_server(self) | 1245 testserver_base.TestServerRunner.run_server(self) |
1231 | 1246 |
1232 | 1247 |
1233 if __name__ == '__main__': | 1248 if __name__ == '__main__': |
1234 sys.exit(PolicyServerRunner().main()) | 1249 sys.exit(PolicyServerRunner().main()) |
OLD | NEW |