#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <security/pam_appl.h>
+
+static int pamconv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr)
+{
+ char *pass = malloc(strlen(appdata_ptr)+1);
+ strcpy(pass, appdata_ptr);
+
+ int i;
-static int pam_conv_func(int num_msg, const struct pam_message **msg,
- struct pam_response **resp, void *appdata_ptr) {
- *resp = (struct pam_response *)malloc(num_msg * sizeof(struct pam_response));
- for (int i = 0; i < num_msg; i++) {
- resp[i]->resp = strdup((char *)appdata_ptr);
- resp[i]->resp_retcode = 0;
+ *resp = calloc(num_msg, sizeof(struct pam_response));
+
+ for (i = 0; i < num_msg; ++i)
+ {
+ /* Ignore all PAM messages except prompting for hidden input */
+ if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
+ continue;
+
+ /* Assume PAM is only prompting for the password as hidden input */
+ resp[i]->resp = pass;
}
+
return PAM_SUCCESS;
}
-uint8_t pam(uint8_t* username, uint8_t* password)
+bool checkAuthentication(const char *user, const char *pass)
{
- struct passwd *p;
- p = getpwuid(geteuid());
- if (p == NULL) return 0;
- if (username == NULL) username = p->pw_name;
+ /* use own PAM conversation function just responding with the
+ password passed here */
+ struct pam_conv conv = { &pamconv, (void *)pass };
- pam_handle_t *pamh = NULL;
- struct pam_conv conv = { pam_conv_func, NULL };
+ pam_handle_t *handle;
+ int authResult;
- conv.appdata_ptr = (void*)password;
+ pam_start("shutterd", user, &conv, &handle);
+ authResult = pam_authenticate(handle,
+ PAM_SILENT|PAM_DISALLOW_NULL_AUTHTOK);
+ pam_end(handle, authResult);
+
+ return (authResult == PAM_SUCCESS);
+}
- int retval = pam_start("login", username, &conv, &pamh);
- if (retval == PAM_SUCCESS)
- retval = pam_authenticate(pamh, 0);
+void main()
+{
+ printf("%i\n", checkAuthentication("home", "jasopoint"));
- if (pamh) pam_end(pamh, retval);
- return retval == PAM_SUCCESS;
}
-#endif
\ No newline at end of file
+#endif
--- /dev/null
+
+uint8_t authenticate(const char *username, const char* password) {
+ struct spwd spw;
+ struct spwd *result;
+ char *buf;
+ size_t bufsize;
+ int s;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1) {
+ bufsize = 16384; // use a default size if sysconf returns indeterminate size
+ }
+
+ buf = malloc(bufsize);
+ if (buf == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ s = getspnam_r(username, &spw, buf, bufsize, &result);
+ if (result == NULL) {
+ if (s == 0) {
+ fprintf(stderr, "User not found\n");
+ } else {
+ perror("getspnam_r");
+ }
+ free(buf);
+ return 0;
+ }
+
+ const char *hashedPassword = crypt(password, spw.sp_pwdp);
+
+ int status = strcmp(hashedPassword, spw.sp_pwdp) == 0;
+ free(buf);
+ return status;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 3) {
+ printf("Usage: %s <username> <password>\n", argv[0]);
+ return 1;
+ }
+
+ if (authenticate(argv[1], argv[2])) {
+ printf("Authenticated!\n");
+ } else {
+ printf("Authentication failed.\n");
+ }
+
+ return 0;
+}