From 01629ac7358ef026127ebe707c4d13e143aa6e31 Mon Sep 17 00:00:00 2001 From: Johannes Findeisen Date: Sat, 10 Aug 2024 06:11:11 +0200 Subject: [PATCH] Added an interactive program too. Wann make this a feature using -i in the main program. --- checkpw_interactive.c | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 checkpw_interactive.c diff --git a/checkpw_interactive.c b/checkpw_interactive.c new file mode 100644 index 0000000..ea5eee1 --- /dev/null +++ b/checkpw_interactive.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include + +// Custom data structure to hold user-entered password +struct pam_credentials { + const char *password; +}; + +// PAM conversation function to supply the password +int pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { + struct pam_response *response = NULL; + struct pam_credentials *credentials = (struct pam_credentials *)appdata_ptr; + int i; + + response = (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg); + if (response == NULL) { + return PAM_CONV_ERR; + } + + for (i = 0; i < num_msg; i++) { + if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON) { + response[i].resp = strdup(credentials->password); + response[i].resp_retcode = 0; + } + } + + *resp = response; + return PAM_SUCCESS; +} + +int authenticate(const char *username, const char *password) { + pam_handle_t *pamh = NULL; + int retval; + struct pam_credentials credentials = { password }; + struct pam_conv conv = { pam_conversation, &credentials }; + + retval = pam_start("login", username, &conv, &pamh); + + if (retval == PAM_SUCCESS) { + retval = pam_authenticate(pamh, 0); // Attempt to authenticate + } + + if (retval == PAM_SUCCESS) { + retval = pam_acct_mgmt(pamh, 0); // Check account validity + } + + if (pam_end(pamh, retval) != PAM_SUCCESS) { + pamh = NULL; + fprintf(stderr, "Failed to release PAM authenticator\n"); + exit(1); + } + + return (retval == PAM_SUCCESS ? 0 : 1); // 0 for success, 1 for failure +} + +int main() { + char username[256]; + char *password; + + // Prompt user for a username + printf("Username: "); + if (fgets(username, sizeof(username), stdin) == NULL) { + fprintf(stderr, "Failed to read username\n"); + exit(1); + } + + // Remove the trailing newline character if it exists + username[strcspn(username, "\n")] = '\0'; + + // Prompt user for a password + password = getpass("Password: "); + + // Authenticate the user + if (authenticate(username, password) == 0) { + printf("Authenticated successfully.\n"); + return 0; + } else { + printf("Authentication failed.\n"); + return 1; + } +} +