| // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Chaps pam module unit tests. These tests exercise the pam module layer and |
| // use a mock for the login manager and pam helper. |
| // |
| |
| #include <security/pam_appl.h> |
| #include <security/pam_modules.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include <chromeos/secure_blob.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "chaps/chaps_utility.h" |
| #include "chaps/isolate_login_client_mock.h" |
| #include "chaps/pam_helper_mock.h" |
| |
| using std::string; |
| using std::vector; |
| using chromeos::SecureBlob; |
| using ::testing::_; |
| using ::testing::DoAll; |
| using ::testing::Eq; |
| using ::testing::Return; |
| using ::testing::SetArgumentPointee; |
| |
| namespace chaps { |
| |
| // Defined in chaps_pam_module.cc. |
| extern void EnableMock(IsolateLoginClient* login_client, PamHelper* pam_helper); |
| extern void DisableMock(); |
| |
| class TestPamModule : public ::testing::Test { |
| protected: |
| virtual void SetUp() { |
| user_ = string("user"); |
| password_old_ = SecureBlob("password_old"); |
| password_new_ = SecureBlob("password_new"); |
| |
| EnableMock(&login_client_mock_, &pam_helper_mock_); |
| |
| EXPECT_CALL(pam_helper_mock_, GetPamUser(_, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<1>(user_), Return(true))); |
| EXPECT_CALL(pam_helper_mock_, GetPamPassword(_, false, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(password_new_), |
| Return(true))); |
| EXPECT_CALL(pam_helper_mock_, GetPamPassword(_, true, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(password_old_), |
| Return(true))); |
| EXPECT_CALL(pam_helper_mock_, SaveUserAndPassword(_, user_, password_new_)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(pam_helper_mock_, |
| RetrieveUserAndPassword(_, _, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<1>(user_), |
| SetArgumentPointee<2>(password_new_), |
| Return(true))); |
| EXPECT_CALL(pam_helper_mock_, PutEnvironmentVariable(_, _, _)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(pam_helper_mock_, GetEnvironmentVariable(_, _, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(string("1")), |
| Return(true))); |
| } |
| void TearDown() { |
| DisableMock(); |
| } |
| string user_; |
| SecureBlob password_old_; |
| SecureBlob password_new_; |
| IsolateLoginClientMock login_client_mock_; |
| PamHelperMock pam_helper_mock_; |
| }; |
| |
| TEST_F(TestPamModule, TestPamAuthenticateSuccess) { |
| EXPECT_CALL(login_client_mock_, LoginUser(user_, password_new_)) |
| .WillOnce(Return(true)); |
| |
| EXPECT_EQ(PAM_SUCCESS, pam_sm_authenticate(NULL, 0, 0, NULL)); |
| EXPECT_EQ(PAM_SUCCESS, pam_sm_open_session(NULL, 0, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamOpenWithoutAuthenticate) { |
| EXPECT_CALL(pam_helper_mock_, RetrieveUserAndPassword(_, _, _)) |
| .WillRepeatedly(Return(false)); |
| |
| EXPECT_EQ(PAM_IGNORE, pam_sm_open_session(NULL, 0, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamOpenWithoutDifferentUser) { |
| EXPECT_CALL(pam_helper_mock_, GetPamUser(_, _)) |
| .WillOnce(DoAll(SetArgumentPointee<1>(user_), Return(true))) |
| .WillRepeatedly(DoAll(SetArgumentPointee<1>(string("user_2")), |
| Return(true))); |
| |
| EXPECT_EQ(PAM_SUCCESS, pam_sm_authenticate(NULL, 0, 0, NULL)); |
| EXPECT_EQ(PAM_IGNORE, pam_sm_open_session(NULL, 0, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamCloseSuccess) { |
| EXPECT_CALL(login_client_mock_, LogoutUser(user_)) |
| .WillOnce(Return(true)); |
| |
| EXPECT_EQ(PAM_SUCCESS, pam_sm_close_session(NULL, 0, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamChangeAuthSuccess) { |
| EXPECT_CALL(login_client_mock_, ChangeUserAuth(user_, password_old_, |
| password_new_)) |
| .WillOnce(Return(true)); |
| |
| EXPECT_EQ(PAM_SUCCESS, pam_sm_chauthtok(NULL, PAM_UPDATE_AUTHTOK, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamChangeAuthPrelimCheck) { |
| EXPECT_EQ(PAM_IGNORE, |
| pam_sm_chauthtok(NULL, PAM_PRELIM_CHECK | PAM_UPDATE_AUTHTOK, 0, NULL)); |
| EXPECT_EQ(PAM_IGNORE, pam_sm_chauthtok(NULL, 0, 0, NULL)); |
| } |
| |
| TEST_F(TestPamModule, TestPamChangeAuthFail) { |
| EXPECT_CALL(pam_helper_mock_, GetPamPassword(_, true, _)) |
| .WillOnce(Return(false)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(password_old_), |
| Return(true))); |
| EXPECT_CALL(pam_helper_mock_, GetPamPassword(_, false, _)) |
| .WillOnce(Return(false)); |
| |
| EXPECT_EQ(PAM_AUTH_ERR, pam_sm_chauthtok(NULL, PAM_UPDATE_AUTHTOK, 0, NULL)); |
| EXPECT_EQ(PAM_AUTH_ERR, pam_sm_chauthtok(NULL, PAM_UPDATE_AUTHTOK, 0, NULL)); |
| } |
| |
| } // namespace chaps |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleMock(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |