Merge ~azzar1/unity:fix-1733557-cosmic into unity:cosmic

Proposed by Andrea Azzarone on 2019-02-18
Status: Merged
Approved by: Marco Trevisan (TreviƱo) on 2019-02-18
Approved revision: 492d5c6cfc37824eccea3064bc9cc8e423861bf7
Merged at revision: 9fdcef5e17273ede5c55dd5f5dabe2a01567d393
Proposed branch: ~azzar1/unity:fix-1733557-cosmic
Merge into: unity:cosmic
Diff against target: 108 lines (+32/-3)
4 files modified
lockscreen/LockScreenController.cpp (+2/-0)
lockscreen/UserAuthenticator.h (+1/-0)
lockscreen/UserAuthenticatorPam.cpp (+27/-3)
lockscreen/UserAuthenticatorPam.h (+2/-0)
Reviewer Review Type Date Requested Status
Unity Team 2019-02-18 Pending
Review via email: mp+363309@code.launchpad.net

Commit message

lockscreen: cancel authentication if externally unlocked

The lockscreen can be externellay unlocked. This happens e.g. when
you unlock the session from LightDM or from the CLI. We need to
cancel the authentication in order to ensure that the next one does
not fail.

Fixes: https://bugs.launchpad.net/unity/+bug/1733557

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 8f6e7bc..907a130 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -536,6 +536,8 @@ void Controller::OnUnlockRequested()
536536
537 HideBlankWindow();537 HideBlankWindow();
538 HideShields();538 HideShields();
539
540 user_authenticator_->AuthenticateCancel();
539}541}
540542
541void Controller::HideShields()543void Controller::HideShields()
diff --git a/lockscreen/UserAuthenticator.h b/lockscreen/UserAuthenticator.h
index e30ce2f..60e8684 100644
--- a/lockscreen/UserAuthenticator.h
+++ b/lockscreen/UserAuthenticator.h
@@ -43,6 +43,7 @@ public:
4343
44 // Authenticate the user in a background thread.44 // Authenticate the user in a background thread.
45 virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;45 virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
46 virtual void AuthenticateCancel() = 0;
4647
47 sigc::signal<void> start_failed;48 sigc::signal<void> start_failed;
48 sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;49 sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
diff --git a/lockscreen/UserAuthenticatorPam.cpp b/lockscreen/UserAuthenticatorPam.cpp
index 463d8f9..d1d6c27 100644
--- a/lockscreen/UserAuthenticatorPam.cpp
+++ b/lockscreen/UserAuthenticatorPam.cpp
@@ -50,6 +50,7 @@ bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
50 }50 }
5151
52 first_prompt_ = true;52 first_prompt_ = true;
53 cancelled_ = false;
53 username_ = username;54 username_ = username;
54 authenticate_cb_ = authenticate_cb;55 authenticate_cb_ = authenticate_cb;
5556
@@ -64,6 +65,18 @@ bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
64 return !error;65 return !error;
65}66}
6667
68void UserAuthenticatorPam::AuthenticateCancel()
69{
70 if (!pam_handle_)
71 {
72 LOG_DEBUG(logger) << "Unable to cancel authentication because none has been started";
73 return;
74 }
75
76 LOG_DEBUG(logger) << "Cancelling the authentication";
77 cancelled_ = true;
78}
79
67gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)80gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)
68{81{
69 auto self = static_cast<UserAuthenticatorPam*>(data);82 auto self = static_cast<UserAuthenticatorPam*>(data);
@@ -92,7 +105,10 @@ gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)
92105
93 pam_end(self->pam_handle_, self->status_);106 pam_end(self->pam_handle_, self->status_);
94 self->pam_handle_ = nullptr;107 self->pam_handle_ = nullptr;
95 self->source_manager_.AddTimeout(0, [self] { self->authenticate_cb_(self->status_ == PAM_SUCCESS); return false; });108
109 if (!self->cancelled_)
110 self->source_manager_.AddTimeout(0, [self] { self->authenticate_cb_(self->status_ == PAM_SUCCESS); return false; });
111
96 return nullptr;112 return nullptr;
97}113}
98114
@@ -188,9 +204,17 @@ int UserAuthenticatorPam::ConversationFunction(int num_msg,
188 auto future = promise->get_future();204 auto future = promise->get_future();
189 pam_response* resp_item = &tmp_response[i++];205 pam_response* resp_item = &tmp_response[i++];
190 resp_item->resp_retcode = 0;206 resp_item->resp_retcode = 0;
191 resp_item->resp = strdup(future.get().c_str());207 resp_item->resp = nullptr;
208
209 std::future_status status;
210 do
211 {
212 status = future.wait_for(std::chrono::seconds(1));
213 if (status == std::future_status::ready)
214 resp_item->resp = strdup(future.get().c_str());
215 } while (status != std::future_status::ready && !user_auth->cancelled_);
192216
193 if (!resp_item->resp)217 if (!resp_item->resp || user_auth->cancelled_)
194 {218 {
195 raise_error = true;219 raise_error = true;
196 break;220 break;
diff --git a/lockscreen/UserAuthenticatorPam.h b/lockscreen/UserAuthenticatorPam.h
index 82273cd..4043cd4 100644
--- a/lockscreen/UserAuthenticatorPam.h
+++ b/lockscreen/UserAuthenticatorPam.h
@@ -39,6 +39,7 @@ class UserAuthenticatorPam : public UserAuthenticator
39public:39public:
40 UserAuthenticatorPam() = default;40 UserAuthenticatorPam() = default;
41 bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;41 bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
42 void AuthenticateCancel() override;
4243
43private:44private:
44 UserAuthenticatorPam(UserAuthenticatorPam const&) = delete;45 UserAuthenticatorPam(UserAuthenticatorPam const&) = delete;
@@ -57,6 +58,7 @@ private:
5758
58 int status_ = 0;59 int status_ = 0;
59 bool first_prompt_ = true;60 bool first_prompt_ = true;
61 bool cancelled_ = false;
60 pam_handle* pam_handle_ = nullptr;62 pam_handle* pam_handle_ = nullptr;
61 glib::SourceManager source_manager_;63 glib::SourceManager source_manager_;
62};64};

Subscribers

People subscribed via source and target branches