Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions data/css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ text-shadow: 1px 1px 0 var(--bcol),
padding-bottom: 75px;
}

.wf-locker .failure {
animation-name: shake;
animation-duration:0.5s;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}

.wf-locker.sized-480 {
font-size:6px;
}
Expand Down Expand Up @@ -292,3 +300,25 @@ text-shadow: 1px 1px 0 var(--bcol),
padding-right: 0rem;
}
}

@keyframes shake {
0% {
transform: translateX(0px);
}
20% {
transform: translateX(20px);
}
40% {
transform: translateX(-20px);
}
60% {
transform: translateX(20px);
}
80% {
transform: translateX(-20px);
}
100% {
transform: translateX(0px);
}
}

4 changes: 2 additions & 2 deletions data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ install_data(join_paths('icons', '256x256', 'wayfire.png'), install_dir: join_pa
install_data(join_paths('icons', '512x512', 'wayfire.png'), install_dir: join_paths(get_option('prefix'), 'share', 'icons', 'hicolor', '512x512', 'apps'))
install_data(join_paths('icons', 'scalable', 'wayfire.svg'), install_dir: join_paths(get_option('prefix'), 'share', 'icons', 'hicolor', 'scalable', 'apps'))

install_data('wf-locker-password', install_dir:'/etc/pam.d/')
install_data('wf-locker', install_dir:'/etc/pam.d/')

subdir('css')
subdir('css')
2 changes: 2 additions & 0 deletions data/wf-locker
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
auth required pam_unix.so nodelay unlock_time=60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auth required pam_unix.so nodelay unlock_time=60
auth required pam_unix.so nodelay deny=3 unlock_time=10

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my testing we never trigger the unlock lockout because we missed the deny=3

But we do the lockout in our own software

account required pam_unix.so nodelay unlock_time=60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
account required pam_unix.so nodelay unlock_time=60
account required pam_unix.so nodelay deny=3 unlock_time=10

1 change: 0 additions & 1 deletion data/wf-locker-password

This file was deleted.

2 changes: 2 additions & 0 deletions src/locker/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ class WayfireLockerPlugin
virtual void deinit() = 0; /* Called after lockscreen unlocked. */
virtual void lockout_changed(bool lockout)
{} /* Called when too many failed logins have occured */
virtual void failure()
{}
virtual ~WayfireLockerPlugin() = default;
};
9 changes: 9 additions & 0 deletions src/locker/plugin/fingerprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ void WayfireLockerFingerprintPlugin::start_fingerprint_scanning()
{
std::cout << "No match" << std::endl;
show();
failure();
update("Invalid fingerprint", "dialog-error-symbolic", "bad");
stop_fingerprint_scanning();
WayfireLockerApp::get().recieved_bad_auth();
Expand Down Expand Up @@ -411,6 +412,14 @@ void WayfireLockerFingerprintPlugin::update(std::string label, std::string image
}
}

void WayfireLockerFingerprintPlugin::failure()
{
for (auto & it : widgets)
{
it.second->failure();
}
}

void WayfireLockerFingerprintPlugin::hide()
{
show_state = false;
Expand Down
1 change: 1 addition & 0 deletions src/locker/plugin/fingerprint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class WayfireLockerFingerprintPlugin : public WayfireLockerPlugin
void init() override;
void deinit() override;
void lockout_changed(bool lockout) override;
void failure() override;
void hide();
void show();
void color(std::string color);
Expand Down
81 changes: 62 additions & 19 deletions src/locker/plugin/password.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ WayfireLockerPasswordPluginWidget::~WayfireLockerPasswordPluginWidget()
{
entry_submitted.disconnect();
}

for (auto signal : replies_signals)
{
signal.disconnect();
}
}

void WayfireLockerPasswordPlugin::update_labels(std::string text)
void WayfireLockerPasswordPlugin::add_reply(std::string text)
{
for (auto& it : widgets)
{
it.second->label.set_label(text);
it.second->add_reply(text);
}

label_contents = text;
}

void WayfireLockerPasswordPlugin::blank_passwords()
Expand All @@ -45,9 +48,23 @@ void WayfireLockerPasswordPlugin::blank_passwords()
}
}

void WayfireLockerPasswordPluginWidget::lockout_changed(bool lockout)
{
if (lockout)
{
entry.set_text("");
entry.set_sensitive(false);
entry.set_placeholder_text("Too many attempts");
} else
{
entry.set_sensitive(true);
entry.set_placeholder_text("Password");
}
}

void WayfireLockerPasswordPlugin::add_output(int id, std::shared_ptr<WayfireLockerGrid> grid)
{
widgets.emplace(id, new WayfireLockerPasswordPluginWidget(label_contents));
widgets.emplace(id, new WayfireLockerPasswordPluginWidget());

/* Share string to every other entry */
auto widget = widgets[id];
Expand Down Expand Up @@ -84,21 +101,33 @@ void WayfireLockerPasswordPlugin::add_output(int id, std::shared_ptr<WayfireLock
});
}

WayfireLockerPasswordPluginWidget::WayfireLockerPasswordPluginWidget(std::string label_contents) :
WayfireLockerPasswordPluginWidget::WayfireLockerPasswordPluginWidget() :
WayfireLockerTimedRevealer("locker/password_always")
{
set_child(box);
box.add_css_class("password");
box.append(entry);
box.append(label);
box.append(replies);
box.set_orientation(Gtk::Orientation::VERTICAL);
label.add_css_class("password-reply");
replies.add_css_class("password-reply");
replies.set_orientation(Gtk::Orientation::VERTICAL);
entry.add_css_class("password-entry");
entry.set_placeholder_text("Password");
label.set_label(label_contents);
entry.set_visibility(false);
}

void WayfireLockerPasswordPluginWidget::add_reply(std::string message)
{
std::shared_ptr<Gtk::Label> new_label = std::make_shared<Gtk::Label>(message);
replies.append(*new_label);

replies_signals.push_back(Glib::signal_timeout().connect_seconds([this, new_label] ()
{
replies.remove(*new_label);
return G_SOURCE_REMOVE;
}, 15));
}

void WayfireLockerPasswordPlugin::remove_output(int id, std::shared_ptr<WayfireLockerGrid> grid)
{
grid->remove(*widgets[id]);
Expand All @@ -113,8 +142,6 @@ WayfireLockerPasswordPlugin::WayfireLockerPasswordPlugin() :
int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_response **resp,
void *appdata_ptr)
{
std::cout << "PAM convo step ... " << std::endl;

WayfireLockerPasswordPlugin *pass_plugin = (WayfireLockerPasswordPlugin*)appdata_ptr;
*resp = (struct pam_response*)calloc(num_mesg, sizeof(struct pam_response));
if (*resp == NULL)
Expand All @@ -125,18 +152,19 @@ int pam_conversation(int num_mesg, const struct pam_message **mesg, struct pam_r

for (int count = 0; count < num_mesg; count++)
{
std::cout << "PAM msg : " << mesg[count]->msg << std::endl;
std::string message = mesg[count]->msg;

resp[count]->resp_retcode = 0;
/* Echo OFF prompt should be user password. */
if (mesg[count]->msg_style == PAM_PROMPT_ECHO_OFF)
{
resp[count]->resp = strdup(pass_plugin->submitted_password.c_str());
} else if (mesg[count]->msg_style == PAM_ERROR_MSG)
{
pass_plugin->update_labels(mesg[count]->msg);
pass_plugin->add_reply(message);
} else if (mesg[count]->msg_style == PAM_TEXT_INFO)
{
pass_plugin->update_labels(mesg[count]->msg);
pass_plugin->add_reply(message);
}
}

Expand All @@ -158,12 +186,11 @@ void WayfireLockerPasswordPlugin::submit_user_password(std::string password)
int retval;
/* Start the password-based conversation */
std::cout << "PAM start ... " << std::endl;
retval = pam_start("wf-locker-password", username, &local_conversation, &local_auth_handle);
retval = pam_start("wf-locker", username, &local_conversation, &local_auth_handle);
if (retval != PAM_SUCCESS)
{
/* We don't expect to be here. No graceful way out of this. */
std::cout << "PAM start returned " << retval << std::endl;
update_labels("pam_start failure");
add_reply("pam_start failure");
exit(retval);
}

Expand All @@ -175,8 +202,7 @@ void WayfireLockerPasswordPlugin::submit_user_password(std::string password)
{
if (retval == PAM_AUTH_ERR)
{
std::cout << "Authentication failure." << std::endl;
update_labels("Authentication failure.");
failure();
}
} else
{
Expand All @@ -191,6 +217,23 @@ void WayfireLockerPasswordPlugin::submit_user_password(std::string password)
}
}

void WayfireLockerPasswordPlugin::lockout_changed(bool lockout)
{
for (auto & it : widgets)
{
it.second->lockout_changed(lockout);
}
}

void WayfireLockerPasswordPlugin::failure()
{
WayfireLockerApp::get().recieved_bad_auth();
for (auto & it : widgets)
{
it.second->failure();
}
}

void WayfireLockerPasswordPlugin::init()
{}

Expand Down
13 changes: 9 additions & 4 deletions src/locker/plugin/password.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ class WayfireLockerPasswordPluginWidget : public WayfireLockerTimedRevealer
~WayfireLockerPasswordPluginWidget();
Gtk::Box box;
Gtk::Entry entry;
Gtk::Label label;
WayfireLockerPasswordPluginWidget(std::string label_contents);
Gtk::Box replies;
WayfireLockerPasswordPluginWidget();

sigc::connection entry_updated, entry_submitted;
std::vector<sigc::connection> replies_signals;

void add_reply(std::string message);
void lockout_changed(bool lockout);
};

class WayfireLockerPasswordPlugin : public WayfireLockerPlugin
Expand All @@ -35,11 +39,12 @@ class WayfireLockerPasswordPlugin : public WayfireLockerPlugin
void submit_user_password(std::string password);
void blank_passwords();
void update_passwords(std::string password);
void lockout_changed(bool lockout) override;
void failure() override;

sigc::connection timeout;
void update_labels(std::string text);
void add_reply(std::string text);

std::unordered_map<int, std::shared_ptr<WayfireLockerPasswordPluginWidget>> widgets;
std::string label_contents = "";
std::string submitted_password = "";
};
23 changes: 23 additions & 0 deletions src/locker/timedrevealer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
WayfireLockerTimedRevealer::WayfireLockerTimedRevealer(std::string always_option) :
always_show(WfOption<bool>{always_option})
{
set_overflow(Gtk::Overflow::VISIBLE);
if ((hide_timeout > 0) && !always_show)
{
set_reveal_child(false);
Expand Down Expand Up @@ -84,6 +85,11 @@ WayfireLockerTimedRevealer::~WayfireLockerTimedRevealer()
{
signal.disconnect();
}

if (signal_failure)
{
signal_failure.disconnect();
}
}

void WayfireLockerTimedRevealer::activity()
Expand All @@ -107,3 +113,20 @@ void WayfireLockerTimedRevealer::activity()
},
hide_timeout * 1000);
}

void WayfireLockerTimedRevealer::failure()
{
if (signal_failure)
{
signal_failure.disconnect();
}

remove_css_class("failure");

Glib::signal_idle().connect(
[this] ()
{
add_css_class("failure");
return G_SOURCE_REMOVE;
});
}
2 changes: 2 additions & 0 deletions src/locker/timedrevealer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class WayfireLockerTimedRevealer : public Gtk::Revealer
{
private:
sigc::connection signal;
sigc::connection signal_failure;

public:
WayfireLockerTimedRevealer(std::string always_option);
Expand All @@ -17,4 +18,5 @@ class WayfireLockerTimedRevealer : public Gtk::Revealer
WfOption<double> hide_animation_duration{"locker/hide_anim_dur"};

virtual void activity(); /* Allow plugins to have their own logic if more intricate */
void failure();
};