/* http://www.jmf/name/scraps/checkpassword-krb5.c * * * A mish-mash of D.J. Bernstein's "checkpassword" program, * checkpassword-pam, and a krb5 authenticator by Ben Bennett. * * Works like checkpassword, checkpassword-pam, etc * but it queries your default Kerberos KDC for * credentials. * * http://cr.yp.to/checkpwd.html * http://checkpasswd-pam.sourceforge.net/ * http://www.phys.psu.edu/~ben/k5/k5_check.c * * * YMMV... * * Joshua Fritsch * jmf@jmf.name * * gcc -o checkpassword-krb5 -lkrb5 checkpassword-krb5.c * * For use with qmail (most likely for SMTP auth over SSL) * append this to your qmail-smtpd run script: * * \ * /path/to/qmail-smtpd /path/to/checkpassword-krb5 /bin/true 2>&1 * */ #include #include #include #include #define MAXLENGTH 513 #define FILE_DESCRIPTOR 3 static char up[MAXLENGTH]; static int uplen = 0; static char login[MAXLENGTH]; static char password[MAXLENGTH]; int kres; krb5_context kcontext; krb5_principal kprinc=NULL; krb5_get_init_creds_opt opts; krb5_creds creds; main(int argc, char **argv) { FILE* stream_input; int i; int p; int r; if (!argv[1]) { exit(9); } stream_input = fdopen(FILE_DESCRIPTOR, "r"); if (stream_input == NULL) { exit(2); } uplen = fread(up, 1, MAXLENGTH, stream_input); if (uplen == 0) { exit(3); } close(FILE_DESCRIPTOR); i = 0; if (i >= uplen) exit(4); while (up[i]) { if (i >= uplen) exit(4); login[i] = up[i]; i++; } login[i] = '\0'; i++; p = 0; while (up[i]) { if (i >= uplen) exit(4); password[p] = up[i]; i++; p++; } password[p] = '\0'; if (i >= uplen) exit(4); while (up[i++]) if (i >= uplen) exit(4); krb5_init_context(&kcontext); krb5_get_init_creds_opt_init(&opts); krb5_parse_name(kcontext, (char *)&login, &kprinc); kres=krb5_get_init_creds_password( kcontext, &creds, kprinc, password, NULL, NULL, (krb5_deltat)0, NULL, &opts); if(kres){ if(kres==KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN) exit(5); else if(kres==KRB5KRB_AP_ERR_BAD_INTEGRITY) exit(6); else exit(7); } krb5_free_principal(kcontext, kprinc); krb5_free_context(kcontext); execvp(argv[1], NULL); }