1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import dbus
6from dbus.mainloop.glib import DBusGMainLoop
7
8from autotest_lib.client.bin import test
9from autotest_lib.client.common_lib import error
10from autotest_lib.client.common_lib.cros import policy, session_manager
11from autotest_lib.client.cros import cryptohome, ownership
12
13
14class login_MultiUserPolicy(test.test):
15    """Verifies that storing and retrieving user policy works with
16       multiple profiles signed-in.
17    """
18
19    version = 1
20
21    _user1 = 'user1@somewhere.com'
22    _user2 = 'user2@somewhere.com'
23
24
25    def initialize(self):
26        super(login_MultiUserPolicy, self).initialize()
27        policy.install_protobufs(self.autodir, self.job)
28        self._bus_loop = DBusGMainLoop(set_as_default=True)
29
30        # Clear the user's vault, to make sure the test starts without any
31        # policy or key lingering around. At this stage the session isn't
32        # started and there's no user signed in.
33        ownership.restart_ui_to_clear_ownership_files()
34        cryptohome_proxy = cryptohome.CryptohomeProxy(
35            self._bus_loop, self.autodir, self.job)
36        cryptohome_proxy.ensure_clean_cryptohome_for(self._user1)
37        cryptohome_proxy.ensure_clean_cryptohome_for(self._user2)
38
39
40    def run_once(self):
41        sm = session_manager.connect(self._bus_loop)
42
43        # Start a session for the first user, and verify that no policy exists
44        # for that user yet.
45        sm.StartSession(self._user1, '')
46        policy_blob = sm.RetrievePolicyEx(
47                session_manager.make_user_policy_descriptor(self._user1),
48                byte_arrays=True)
49        if policy_blob:
50            raise error.TestError('session_manager already has user policy!')
51
52        # Now store a policy. This is building a device policy protobuf, but
53        # that's fine as far as the session_manager is concerned; it's the
54        # outer PolicyFetchResponse that contains the public_key.
55        public_key = ownership.known_pubkey()
56        private_key = ownership.known_privkey()
57        policy_data = policy.build_policy_data()
58        policy_response = policy.generate_policy(private_key,
59                                                 public_key,
60                                                 policy_data)
61        try:
62            sm.StorePolicyEx(
63                session_manager.make_user_policy_descriptor(self._user1),
64                dbus.ByteArray(policy_response))
65        except dbus.exceptions.DBusException as e:
66            raise error.TestFail('Call to StorePolicyEx failed', e)
67
68        # Storing policy for the second user fails before his session starts.
69        try:
70            sm.StorePolicyEx(
71                session_manager.make_user_policy_descriptor(self._user2),
72                dbus.ByteArray(policy_response))
73        except dbus.exceptions.DBusException:
74            pass
75        else:
76            raise error.TestFail('Storing policy should fail before the '
77                                 'session is started')
78
79
80        # Now start the second user's session, and verify that he has no
81        # policy stored yet.
82        sm.StartSession(self._user2, '')
83        policy_blob = sm.RetrievePolicyEx(
84                session_manager.make_user_policy_descriptor(self._user2),
85                byte_arrays=True)
86        if policy_blob:
87            raise error.TestError('session_manager already has user policy!')
88
89        # Storing works now.
90        try:
91            sm.StorePolicyEx(
92                session_manager.make_user_policy_descriptor(self._user2),
93                dbus.ByteArray(policy_response))
94        except dbus.exceptions.DBusException as e:
95            raise error.TestFail('Call to StorePolicyEx failed', e)
96
97        # Verify that retrieving policy works too.
98        policy_blob = sm.RetrievePolicyEx(
99                session_manager.make_user_policy_descriptor(self._user2),
100                byte_arrays=True)
101        if not policy_blob:
102            raise error.TestError('Failed to retrieve stored policy')
103