#include #include #include #include #include #include /* */ struct auth_message { enum { AUTH_MSGTYPE_INFO, AUTH_MSGTYPE_ERROR, AUTH_MSGTYPE_PROMPT_NOECHO, AUTH_MSGTYPE_PROMPT_ECHO, } type; const char *msg; }; struct auth_response { char *response; }; static int pam_conversation (int nmsgs, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); typedef struct { GtkWidget *msg; GtkWidget *username; GtkWidget *password; } LoginWidget; static void destroy (GtkWidget *window, gpointer data); int do_authenticate(GtkButton *button, LoginWidget *w_login ); int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *hbox, *vbox, *cancel_btn, *ok_btn; LoginWidget *w_login = (LoginWidget *) g_malloc (sizeof (LoginWidget)); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); w_login->msg = gtk_label_new (""); w_login->username = gtk_entry_new (); w_login->password = gtk_entry_new (); gtk_entry_set_visibility (GTK_ENTRY(w_login->password), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY(w_login->password), '*'); ok_btn = gtk_button_new_with_label ("OK!"); cancel_btn = gtk_button_new_with_label ("Cancel!"); g_signal_connect (G_OBJECT (ok_btn), "clicked", G_CALLBACK (do_authenticate), (gpointer) w_login); vbox = gtk_vbox_new(FALSE, 5); gtk_box_pack_start_defaults (GTK_BOX (vbox), w_login->msg); gtk_box_pack_start_defaults (GTK_BOX (vbox), w_login->username); gtk_box_pack_start_defaults (GTK_BOX (vbox), w_login->password); hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start_defaults (GTK_BOX (hbox), ok_btn); gtk_box_pack_start_defaults (GTK_BOX (hbox), cancel_btn); gtk_box_pack_start_defaults (GTK_BOX (vbox), hbox); gtk_container_add(GTK_CONTAINER (window), vbox); gtk_widget_show_all(window); gtk_main(); } static void destroy (GtkWidget *window, gpointer data) { gtk_main_quit(); } int do_authenticate(GtkButton *button, LoginWidget *w_login ) { const gchar *_username = gtk_entry_get_text(GTK_ENTRY (w_login->username)); char *tty = strdup(":0.0"); pam_handle_t *pamh = NULL; int retval; struct pam_conv conv; conv.conv = &pam_conversation; conv.appdata_ptr = w_login; retval = pam_start("capu", _username, &conv, &pamh); retval = pam_set_item (pamh, PAM_TTY, tty); retval = pam_set_item (pamh, PAM_XDISPLAY, tty); pam_get_item (pamh, PAM_TTY, (const void **)&tty); g_message("TTY: %s",tty); pam_get_item (pamh, PAM_XDISPLAY, (const void **)&tty); g_message("XDISPLAY: %s",tty); if (retval == PAM_SUCCESS) { retval = pam_authenticate(pamh, 0); g_message("Auth"); } if (retval == PAM_SUCCESS) { retval = pam_acct_mgmt(pamh, 0); } if (retval == PAM_SUCCESS) { g_message ("Authenticated"); } else { g_message ("Not Authenticated"); } if (pam_end(pamh, retval) != PAM_SUCCESS ) { pamh = NULL; } gtk_main_quit(); return 0; } static int pam_conversation (int nmsgs, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int i, ret = -1; struct auth_message *messages = 0; struct auth_response *authresp = 0; struct pam_response *pam_responses; LoginWidget *w_login = ( LoginWidget *) appdata_ptr; messages = calloc(nmsgs, sizeof (struct auth_message)); pam_responses = calloc(nmsgs, sizeof (*pam_responses)); const gchar *_password = gtk_entry_get_text(GTK_ENTRY (w_login->password)); for (i=0; imsg; switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: messages[i].type = AUTH_MSGTYPE_PROMPT_NOECHO; pam_responses[i].resp = strdup(_password); g_message("ECHO_OFF"); break; case PAM_PROMPT_ECHO_ON: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO; g_message("ECHO_ON"); fputs(msg[i]->msg, stderr); break; case PAM_ERROR_MSG: messages[i].type = AUTH_MSGTYPE_ERROR; g_message("ERROR_MSG"); break; case PAM_TEXT_INFO: messages[i].type = AUTH_MSGTYPE_INFO; g_message("TEXT_INFO"); break; default: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO; break; } } *resp = pam_responses; ret = 0; return PAM_SUCCESS; }