Skip to content

Instantly share code, notes, and snippets.

@dannvix
Created April 2, 2011 11:30
Show Gist options
  • Save dannvix/899414 to your computer and use it in GitHub Desktop.
Save dannvix/899414 to your computer and use it in GitHub Desktop.
Simple Linux PAM module for OTP authentication
#include <security/pam_modules.h>
#include <security/pam_appl.h>
#include <sys/types.h>
#include <gcrypt.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define SERVER_SECRET "MY_SECRET"
void gen_otp (char **otp) {
time_t unixtime;
time(&unixtime);
int otp_time = (int)unixtime - (int)unixtime % 60;
char buffer[1024];
snprintf(buffer, 1024, "%d+%s", otp_time, SERVER_SECRET);
gcry_md_hd_t md_handle = NULL;
gcry_md_open(&md_handle, GCRY_MD_SHA256, GCRY_MD_FLAG_SECURE);
gcry_md_write(md_handle, buffer, strlen(buffer));
const unsigned char *digest = gcry_md_read(md_handle, GCRY_MD_SHA256);
int len = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
*otp = malloc(sizeof(2*len)+8);
int i;
for (i = 0; i < len; i++)
snprintf(*otp+2*i, 3, "%02x", digest[i]);
}
PAM_EXTERN int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv) {
int pam_ret = PAM_AUTH_ERR;
char *password = NULL;
pam_get_authtok(pamh, PAM_AUTHTOK, (const void **) &password), NULL);
password = strdup(password);
char *otp = NULL;
gen_otp(&otp);
return (strncmp(password, otp, 5) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR;
}
PAM_EXTERN int pam_sm_setcred (pam_handle_t *pamh, int flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment