1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 165a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 17cddd2d09878704128d35ddfeec862109b7d7fdc9Alex Deymo#include "shill/crypto_util_proxy.h" 18cddd2d09878704128d35ddfeec862109b7d7fdc9Alex Deymo 195a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <algorithm> 205a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <string> 215a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <vector> 225a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 235a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <base/callback.h> 245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <gtest/gtest.h> 255a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/callbacks.h" 275a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/mock_crypto_util_proxy.h" 285a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/mock_event_dispatcher.h" 295a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/mock_file_io.h" 30304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal#include "shill/mock_process_manager.h" 315a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 325a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing base::Bind; 335a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing std::min; 345a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing std::string; 355a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing std::vector; 36304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawalusing testing::AnyOf; 375a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::DoAll; 385a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::InSequence; 395a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::Invoke; 405a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::Mock; 415a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::NotNull; 425a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::Return; 435a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::StrEq; 44b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wileyusing testing::WithoutArgs; 455a3f23a122566b53e230b1132c0241411016386aChristopher Wileyusing testing::_; 465a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 475a3f23a122566b53e230b1132c0241411016386aChristopher Wileynamespace shill { 485a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 495a3f23a122566b53e230b1132c0241411016386aChristopher Wileynamespace { 50be0849f4474f6e97496550187bc4256bf0a91d2bBen Chan 51be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestBSSID[] = "00:11:22:33:44:55"; 52be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestCertificate[] = "testcertgoeshere"; 53be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestData[] = "thisisthetestdata"; 54be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestDestinationUDN[] = "TEST1234-5678-ABCD"; 55be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestNonce[] = "abort abort abort"; 56be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestPublicKey[] = "YWJvcnQgYWJvcnQgYWJvcnQK"; 57be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestSerializedCommandMessage[] = 58be0849f4474f6e97496550187bc4256bf0a91d2bBen Chan "Since we're not testing protocol buffer seriallization, and no data " 59be0849f4474f6e97496550187bc4256bf0a91d2bBen Chan "actually makes it to a shim, we're safe to write whatever we want here."; 60be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst char kTestSerializedCommandResponse[] = 61be0849f4474f6e97496550187bc4256bf0a91d2bBen Chan "Similarly, we never ask a protocol buffer to deserialize this string."; 6213d581fa047118d065f41eb1d0da203cf0a49b07mukesh agrawalconst char kTestSignedData[] = "Ynl0ZXMgYnl0ZXMgYnl0ZXMK"; 63be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst int kTestStdinFd = 9111; 64be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst int kTestStdoutFd = 9119; 65be0849f4474f6e97496550187bc4256bf0a91d2bBen Chanconst pid_t kTestShimPid = 989898; 66be0849f4474f6e97496550187bc4256bf0a91d2bBen Chan 675a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} // namespace 685a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 695a3f23a122566b53e230b1132c0241411016386aChristopher WileyMATCHER_P(ErrorIsOfType, error_type, "") { 705a3f23a122566b53e230b1132c0241411016386aChristopher Wiley if (error_type != arg.type()) { 715a3f23a122566b53e230b1132c0241411016386aChristopher Wiley return false; 725a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 735a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 745a3f23a122566b53e230b1132c0241411016386aChristopher Wiley return true; 758a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko} 765a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 775a3f23a122566b53e230b1132c0241411016386aChristopher Wileyclass CryptoUtilProxyTest : public testing::Test { 785a3f23a122566b53e230b1132c0241411016386aChristopher Wiley public: 795a3f23a122566b53e230b1132c0241411016386aChristopher Wiley CryptoUtilProxyTest() 8013d581fa047118d065f41eb1d0da203cf0a49b07mukesh agrawal : crypto_util_proxy_(&dispatcher_) { 815a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(78); 825a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(69); 835a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(80); 845a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(84); 855a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(85); 865a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(78); 875a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_.push_back(69); 885a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 895a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 905a3f23a122566b53e230b1132c0241411016386aChristopher Wiley virtual void SetUp() { 91304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal crypto_util_proxy_.process_manager_ = &process_manager_; 925a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.file_io_ = &file_io_; 935a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 945a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 955a3f23a122566b53e230b1132c0241411016386aChristopher Wiley virtual void TearDown() { 96304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // Note that |crypto_util_proxy_| needs its process manager reference in 975a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // order not to segfault when it tries to kill any outstanding shims on 985a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // shutdown. Thus we don't clear out those fields here, and we make sure 995a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // to declare the proxy after mocks it consumes. 1005a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 1015a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 102304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // TODO(quiche): Consider refactoring 103304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // HandleStartInMinijailWithPipes, HandleStopProcess, and 104304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // HandleUpdateExitCallback into a FakeProcessManager. b/24210150 105304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal pid_t HandleStartInMinijailWithPipes( 106304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const tracked_objects::Location& /* spawn_source */, 107304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const base::FilePath& /* program */, 108304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal vector<string> /* program_args */, 109304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const std::string& /* run_as_user */, 110304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const std::string& /* run_as_group */, 111304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal uint64_t /* capabilities_mask */, 112304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const base::Callback<void(int)>& exit_callback, 113304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal int* stdin, 114304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal int* stdout, 115304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal int* /* stderr */) { 116304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal exit_callback_ = exit_callback; 1175a3f23a122566b53e230b1132c0241411016386aChristopher Wiley *stdin = kTestStdinFd; 1185a3f23a122566b53e230b1132c0241411016386aChristopher Wiley *stdout = kTestStdoutFd; 119304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal return kTestShimPid; 1205a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 1215a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1223b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart void StartAndCheckShim(const std::string& command, 1233b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart const std::string& shim_stdin) { 1245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley InSequence seq; 1255a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Delegate the start call to the real implementation just for this test. 1265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, StartShimForCommand(_, _, _)) 1275a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Invoke(&crypto_util_proxy_, 1285a3f23a122566b53e230b1132c0241411016386aChristopher Wiley &MockCryptoUtilProxy::RealStartShimForCommand)); 1295a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // All shims should be spawned in a Minijail. 130304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal EXPECT_CALL( 131304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal process_manager_, 132304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal StartProcessInMinijailWithPipes( 133304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal _, // caller location 134304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal base::FilePath(CryptoUtilProxy::kCryptoUtilShimPath), 135304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal AnyOf( 136304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal vector<string>{CryptoUtilProxy::kCommandVerify}, 137304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal vector<string>{CryptoUtilProxy::kCommandEncrypt}), 138304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal "shill-crypto", 139304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal "shill-crypto", 140304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal 0, // no capabilities required 141304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal _, // exit_callback 142304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal NotNull(), // stdin 143304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal NotNull(), // stdout 144304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal nullptr)) // stderr 145304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal .WillOnce(Invoke(this, 146304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal &CryptoUtilProxyTest::HandleStartInMinijailWithPipes)); 1475a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // We should always schedule a shim timeout callback. 1485a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)); 1495a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // We don't allow file I/O to block. 1505a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(file_io_, 1515a3f23a122566b53e230b1132c0241411016386aChristopher Wiley SetFdNonBlocking(kTestStdinFd)) 1525a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Return(0)); 1535a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(file_io_, 1545a3f23a122566b53e230b1132c0241411016386aChristopher Wiley SetFdNonBlocking(kTestStdoutFd)) 1555a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Return(0)); 1565a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // We instead do file I/O through async callbacks registered with the event 1575a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // dispatcher. 1585a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(dispatcher_, CreateInputHandler(_, _, _)).Times(1); 1595a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(dispatcher_, CreateReadyHandler(_, _, _)).Times(1); 1605a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // The shim is left in flight, not killed. 161304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal EXPECT_CALL(process_manager_, StopProcess(_)).Times(0); 1625a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.StartShimForCommand( 1635a3f23a122566b53e230b1132c0241411016386aChristopher Wiley command, shim_stdin, 1645a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Bind(&MockCryptoUtilProxy::TestResultHandlerCallback, 1655a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.base::SupportsWeakPtr<MockCryptoUtilProxy>:: 1665a3f23a122566b53e230b1132c0241411016386aChristopher Wiley AsWeakPtr())); 1675a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_EQ(shim_stdin, crypto_util_proxy_.input_buffer_); 1685a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_TRUE(crypto_util_proxy_.output_buffer_.empty()); 1695a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_EQ(crypto_util_proxy_.shim_pid_, kTestShimPid); 1705a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Mock::VerifyAndClearExpectations(&crypto_util_proxy_); 1715a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Mock::VerifyAndClearExpectations(&dispatcher_); 172304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal Mock::VerifyAndClearExpectations(&process_manager_); 1735a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 1745a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1753b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart void ExpectCleanup(const Error& expected_result) { 17667e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley if (crypto_util_proxy_.shim_stdin_ > -1) { 17767e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley EXPECT_CALL(file_io_, 17867e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley Close(crypto_util_proxy_.shim_stdin_)).Times(1); 17967e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley } 18067e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley if (crypto_util_proxy_.shim_stdout_ > -1) { 18167e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley EXPECT_CALL(file_io_, 18267e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley Close(crypto_util_proxy_.shim_stdout_)).Times(1); 18367e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley } 1845a3f23a122566b53e230b1132c0241411016386aChristopher Wiley if (crypto_util_proxy_.shim_pid_) { 185304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal EXPECT_CALL(process_manager_, UpdateExitCallback(_, _)) 1865a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .Times(1) 1875a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Invoke(this, 188304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal &CryptoUtilProxyTest::HandleUpdateExitCallback)); 189304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal EXPECT_CALL(process_manager_, StopProcess(crypto_util_proxy_.shim_pid_)) 190304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal .Times(1) 191304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal .WillOnce(Invoke(this, 192304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal &CryptoUtilProxyTest::HandleStopProcess)); 1935a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 1945a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 1955a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 196b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley void AssertShimDead() { 197b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley EXPECT_FALSE(crypto_util_proxy_.shim_pid_); 198b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley } 199b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley 200304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal bool HandleUpdateExitCallback(pid_t /*pid*/, 201304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const base::Callback<void(int)>& new_callback) { 202304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal exit_callback_ = new_callback; 203304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal return true; 204304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal } 205304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal 206304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal bool HandleStopProcess(pid_t /*pid*/) { 207304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal const int kExitStatus = -1; 208304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // NB: in the real world, this ordering is not guaranteed. That 209304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal // is, StopProcess() might return before executing the callback. 210304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal exit_callback_.Run(kExitStatus); 211304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal return true; 2125a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 2135a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 2143b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart void StopAndCheckShim(const Error& error) { 21567e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(error); 21667e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley crypto_util_proxy_.CleanupShim(error); 217304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal crypto_util_proxy_.OnShimDeath(-1); 2185a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_EQ(crypto_util_proxy_.shim_pid_, 0); 219304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal Mock::VerifyAndClearExpectations(&process_manager_); 2205a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 2215a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 2225a3f23a122566b53e230b1132c0241411016386aChristopher Wiley protected: 223304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal MockProcessManager process_manager_; 2245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley MockEventDispatcher dispatcher_; 2255a3f23a122566b53e230b1132c0241411016386aChristopher Wiley MockFileIO file_io_; 2265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley MockCryptoUtilProxy crypto_util_proxy_; 2275a3f23a122566b53e230b1132c0241411016386aChristopher Wiley std::vector<uint8_t> test_ssid_; 228304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal base::Callback<void(int)> exit_callback_; 2295a3f23a122566b53e230b1132c0241411016386aChristopher Wiley}; 2305a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 2315a3f23a122566b53e230b1132c0241411016386aChristopher WileyTEST_F(CryptoUtilProxyTest, BasicAPIUsage) { 2325a3f23a122566b53e230b1132c0241411016386aChristopher Wiley { 2335a3f23a122566b53e230b1132c0241411016386aChristopher Wiley InSequence seq; 2345a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Delegate the API call to the real implementation for this test. 2355a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, 2365a3f23a122566b53e230b1132c0241411016386aChristopher Wiley VerifyDestination(_, _, _, _, _, _, _, _, _)) 2375a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Invoke(&crypto_util_proxy_, 2385a3f23a122566b53e230b1132c0241411016386aChristopher Wiley &MockCryptoUtilProxy::RealVerifyDestination)); 2395a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // API calls are just thin wrappers that write up a message to a shim, then 2405a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // send it via StartShimForCommand. Expect that a shim will be started in 2415a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // response to the API being called. 2425a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, 2435a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartShimForCommand(CryptoUtilProxy::kCommandVerify, _, _)) 2445a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Return(true)); 2455a3f23a122566b53e230b1132c0241411016386aChristopher Wiley ResultBoolCallback result_callback = 2465a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Bind(&MockCryptoUtilProxy::TestResultBoolCallback, 2475a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_. 2485a3f23a122566b53e230b1132c0241411016386aChristopher Wiley base::SupportsWeakPtr<MockCryptoUtilProxy>::AsWeakPtr()); 2495a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Error error; 2505a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_TRUE(crypto_util_proxy_.VerifyDestination(kTestCertificate, 2515a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestPublicKey, 2525a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestNonce, 2535a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSignedData, 2545a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestDestinationUDN, 2555a3f23a122566b53e230b1132c0241411016386aChristopher Wiley test_ssid_, 2565a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestBSSID, 2575a3f23a122566b53e230b1132c0241411016386aChristopher Wiley result_callback, 2585a3f23a122566b53e230b1132c0241411016386aChristopher Wiley &error)); 2595a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_TRUE(error.IsSuccess()); 2605a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 2615a3f23a122566b53e230b1132c0241411016386aChristopher Wiley { 2625a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // And very similarly... 2635a3f23a122566b53e230b1132c0241411016386aChristopher Wiley InSequence seq; 2645a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, EncryptData(_, _, _, _)) 2655a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Invoke(&crypto_util_proxy_, 2665a3f23a122566b53e230b1132c0241411016386aChristopher Wiley &MockCryptoUtilProxy::RealEncryptData)); 2675a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, 2685a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartShimForCommand(CryptoUtilProxy::kCommandEncrypt, _, _)) 2695a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .WillOnce(Return(true)); 2705a3f23a122566b53e230b1132c0241411016386aChristopher Wiley ResultStringCallback result_callback = 2715a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Bind(&MockCryptoUtilProxy::TestResultStringCallback, 2725a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_. 2735a3f23a122566b53e230b1132c0241411016386aChristopher Wiley base::SupportsWeakPtr<MockCryptoUtilProxy>::AsWeakPtr()); 2745a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Error error; 2755a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Normally, we couldn't have these two operations run successfully without 2765a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // finishing the first one, since only one shim can be in flight at a time. 2775a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // However, this works because we didn't actually start a shim, we just 2785a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // trapped the call in our mock. 2795a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_TRUE(crypto_util_proxy_.EncryptData(kTestPublicKey, kTestData, 2805a3f23a122566b53e230b1132c0241411016386aChristopher Wiley result_callback, &error)); 2815a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_TRUE(error.IsSuccess()); 2825a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 2835a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} 2845a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 285b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher WileyTEST_F(CryptoUtilProxyTest, ShimCleanedBeforeCallback) { 286b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley // Some operations, like VerifyAndEncryptData in the manager, chain two 287b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley // shim operations together. Make sure that we don't call back with results 288b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley // before the shim state is clean. 289b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley { 290b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 291b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley kTestSerializedCommandMessage); 29267e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley Error e(Error::kOperationFailed); 29367e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(e); 294b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley EXPECT_CALL(crypto_util_proxy_, 295b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley TestResultHandlerCallback( 296b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley StrEq(""), ErrorIsOfType(Error::kOperationFailed))) 297b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley .Times(1) 298b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley .WillOnce(WithoutArgs(Invoke(this, 299b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley &CryptoUtilProxyTest::AssertShimDead))); 300b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley crypto_util_proxy_.HandleShimError(e); 301b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley } 302b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley { 303b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 304b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley kTestSerializedCommandMessage); 305b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley EXPECT_CALL(crypto_util_proxy_, 306b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley TestResultHandlerCallback( 307b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley StrEq(""), ErrorIsOfType(Error::kSuccess))) 308b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley .Times(1) 309b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley .WillOnce(WithoutArgs(Invoke(this, 310b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley &CryptoUtilProxyTest::AssertShimDead))); 31167e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(Error(Error::kSuccess)); 312b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley InputData data; 313cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan data.buf = nullptr; 314b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley data.len = 0; 315b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley crypto_util_proxy_.HandleShimOutput(&data); 316b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley } 317b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley} 318b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley 3195a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// Verify that even when we have errors, we'll call the result handler. 3205a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// Ultimately, this is supposed to make sure that we always return something to 3215a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// our callers over DBus. 3225a3f23a122566b53e230b1132c0241411016386aChristopher WileyTEST_F(CryptoUtilProxyTest, FailuresReturnValues) { 3235a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 3245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandMessage); 3255a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, TestResultHandlerCallback( 3265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StrEq(""), ErrorIsOfType(Error::kOperationFailed))).Times(1); 3275a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Error e(Error::kOperationFailed); 32867e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(e); 3295a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.HandleShimError(e); 3305a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} 3315a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 3325a3f23a122566b53e230b1132c0241411016386aChristopher WileyTEST_F(CryptoUtilProxyTest, TimeoutsTriggerFailure) { 3335a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 3345a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandMessage); 3355a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(crypto_util_proxy_, TestResultHandlerCallback( 3365a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StrEq(""), ErrorIsOfType(Error::kOperationTimeout))).Times(1); 33767e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(Error(Error::kOperationTimeout)); 3385a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // This timeout is scheduled by StartShimForCommand. 3395a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.HandleShimTimeout(); 3405a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} 3415a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 3425a3f23a122566b53e230b1132c0241411016386aChristopher WileyTEST_F(CryptoUtilProxyTest, OnlyOneInstanceInFlightAtATime) { 3435a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 3445a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandMessage); 3455a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Can't start things twice. 3465a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_FALSE(crypto_util_proxy_.RealStartShimForCommand( 3475a3f23a122566b53e230b1132c0241411016386aChristopher Wiley CryptoUtilProxy::kCommandEncrypt, kTestSerializedCommandMessage, 3485a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Bind(&MockCryptoUtilProxy::TestResultHandlerCallback, 3495a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_. 3505a3f23a122566b53e230b1132c0241411016386aChristopher Wiley base::SupportsWeakPtr<MockCryptoUtilProxy>::AsWeakPtr()))); 3515a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // But if some error (or completion) caused us to clean up the shim... 35267e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley StopAndCheckShim(Error(Error::kSuccess)); 3535a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Then we could start the shim again. 3545a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 3555a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandMessage); 3565a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Clean up after ourselves. 35767e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley StopAndCheckShim(Error(Error::kOperationFailed)); 3585a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} 3595a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 3605a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// This test walks the CryptoUtilProxy through the life time of a shim by 3615a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// simulating the API call, file I/O operations, and the final handler on shim 3625a3f23a122566b53e230b1132c0241411016386aChristopher Wiley// completion. 3635a3f23a122566b53e230b1132c0241411016386aChristopher WileyTEST_F(CryptoUtilProxyTest, ShimLifeTime) { 3645a3f23a122566b53e230b1132c0241411016386aChristopher Wiley const int kBytesAtATime = 10; 3655a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StartAndCheckShim(CryptoUtilProxy::kCommandEncrypt, 3665a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandMessage); 3675a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Emulate the operating system pulling bytes through the pipe, and the event 3685a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // loop notifying us that the file descriptor is ready. 3695a3f23a122566b53e230b1132c0241411016386aChristopher Wiley int bytes_left = strlen(kTestSerializedCommandMessage); 3705a3f23a122566b53e230b1132c0241411016386aChristopher Wiley while (bytes_left > 0) { 3715a3f23a122566b53e230b1132c0241411016386aChristopher Wiley int bytes_written = min(kBytesAtATime, bytes_left); 3725a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(file_io_, Write(kTestStdinFd, _, bytes_left)) 3735a3f23a122566b53e230b1132c0241411016386aChristopher Wiley .Times(1).WillOnce(Return(bytes_written)); 3745a3f23a122566b53e230b1132c0241411016386aChristopher Wiley bytes_left -= bytes_written; 3755a3f23a122566b53e230b1132c0241411016386aChristopher Wiley if (bytes_left < 1) { 3765a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL(file_io_, Close(kTestStdinFd)); 3775a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 3785a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.HandleShimStdinReady(crypto_util_proxy_.shim_stdin_); 3795a3f23a122566b53e230b1132c0241411016386aChristopher Wiley Mock::VerifyAndClearExpectations(&crypto_util_proxy_); 3805a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 3815a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 3825a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // At this point, the shim goes off and does terribly complex crypto stuff, 3835a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // before responding with a string of bytes over stdout. Emulate the shim 3845a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // and the event loop to push those bytes back. 3855a3f23a122566b53e230b1132c0241411016386aChristopher Wiley const int response_length = bytes_left = 3865a3f23a122566b53e230b1132c0241411016386aChristopher Wiley strlen(kTestSerializedCommandResponse); 3875a3f23a122566b53e230b1132c0241411016386aChristopher Wiley InputData data; 3885a3f23a122566b53e230b1132c0241411016386aChristopher Wiley while (bytes_left > 0) { 3895a3f23a122566b53e230b1132c0241411016386aChristopher Wiley int bytes_written = min(kBytesAtATime, bytes_left); 3905a3f23a122566b53e230b1132c0241411016386aChristopher Wiley data.len = bytes_written; 3913b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart data.buf = reinterpret_cast<unsigned char*>(const_cast<char*>( 3925a3f23a122566b53e230b1132c0241411016386aChristopher Wiley kTestSerializedCommandResponse + response_length - bytes_left)); 3935a3f23a122566b53e230b1132c0241411016386aChristopher Wiley bytes_left -= bytes_written; 3945a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.HandleShimOutput(&data); 3955a3f23a122566b53e230b1132c0241411016386aChristopher Wiley } 3965a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Write 0 bytes in to signify the end of the stream. This should in turn 3975a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // cause our callback to be called. 3985a3f23a122566b53e230b1132c0241411016386aChristopher Wiley data.len = 0; 399cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan data.buf = nullptr; 4005a3f23a122566b53e230b1132c0241411016386aChristopher Wiley EXPECT_CALL( 4015a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_, 4025a3f23a122566b53e230b1132c0241411016386aChristopher Wiley TestResultHandlerCallback(string(kTestSerializedCommandResponse), 4035a3f23a122566b53e230b1132c0241411016386aChristopher Wiley ErrorIsOfType(Error::kSuccess))).Times(1); 40467e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley ExpectCleanup(Error(Error::kSuccess)); 4055a3f23a122566b53e230b1132c0241411016386aChristopher Wiley crypto_util_proxy_.HandleShimOutput(&data); 4065a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} 4075a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 4085a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} // namespace shill 409