diff -U4 -r openssh-4.5p1/auth-skey.c openssh-4.5p1+skey/auth-skey.c --- openssh-4.5p1/auth-skey.c 2006-08-05 10:56:01.000000000 +0100 +++ openssh-4.5p1+skey/auth-skey.c 2007-02-10 11:04:08.000000000 +0000 @@ -27,11 +27,15 @@ #ifdef SKEY #include +#include +#include #include +#define _GNU_SOURCE #include +#include #include #include "xmalloc.h" @@ -40,8 +44,11 @@ #include "auth.h" #include "ssh-gss.h" #include "monitor_wrap.h" +#include "canohost.h" +#include "packet.h" + static void * skey_init_ctx(Authctxt *authctxt) { return authctxt; @@ -73,14 +80,117 @@ int skey_respond(void *ctx, u_int numresponses, char **responses) { Authctxt *authctxt = ctx; + struct skey skey_used; + struct skey skey_next; + char skey_used_prompt[1024]; + char skey_next_prompt[1024]; + int ret; + pid_t bg; + + if (!(authctxt->valid && + numresponses == 1 && + skey_haskey(authctxt->pw->pw_name) == 0)) + return -1; - if (authctxt->valid && - numresponses == 1 && - skey_haskey(authctxt->pw->pw_name) == 0 && - skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1) - return 0; + if (getskeyprompt(&skey_used, authctxt->pw->pw_name, skey_used_prompt) != 0) + skey_used_prompt[0] = 0; + else if (strlen(skey_used_prompt) > 0) + skey_used_prompt[strlen(skey_used_prompt)-1] = 0; + ret = skey_passcheck(authctxt->pw->pw_name, responses[0]); + if (getskeyprompt(&skey_next, authctxt->pw->pw_name, skey_next_prompt) != 0) + skey_next_prompt[0] = 0; + else if (strlen(skey_next_prompt) > 0) + skey_next_prompt[strlen(skey_next_prompt)-1] = 0; + if ((ret != -1) || (responses[0][0] != 0)) + bg = fork(); + else + bg = -1; + if (bg == 0) { + int p[2] = { -1, -1 }; + pid_t sendmail; + pid_t email; + + if ((pipe(p) != 0) + || (dup2(p[0], 0) == -1) + || (dup2(p[1], 1) == -1)) { + if (p[0] != -1) close(p[0]); + if (p[1] != -1) close(p[1]); + close(0); + close(1); + close(2); + _exit(1); + } + close(p[0]); + close(p[1]); + + sendmail = fork(); + if (sendmail == 0) { + close(1); + execl("/usr/sbin/sendmail", "sendmail", authctxt->pw->pw_name, NULL); + close(0); + _exit(1); + } else { + close(0); + close(2); + if (sendmail < 0) { + close(1); + _exit(1); + } + } + + email = fork(); + if (email == 0) { + if (ret != -1) { + dprintf(1, + "Subject: S/Key AUTH %s\n\n" + "S/Key \"%s\" was used to authenticate to %s.\n\n" + "From %s %d\n" + "To %s %d\n\n" + "Next S/Key is \"%s\".\n\n" + "-- \n%s\n", + skey_used_prompt, + skey_used_prompt, + get_local_name(packet_get_connection_in()), + get_remote_ipaddr(), + get_remote_port(), + get_local_ipaddr(packet_get_connection_in()), + get_local_port(), + skey_next_prompt, + get_local_name(packet_get_connection_in())); + } else { + dprintf(1, + "Subject: S/Key FAILED %s\n\n" + "An attempt was made to authenticate to %s using S/Key \"%s\".\n\n" + "From %s %d\n" + "To %s %d\n\n" + "Passphrase: \"%s\"\n\n" + "-- \n%s\n", + skey_used_prompt, + get_local_name(packet_get_connection_in()), + skey_used_prompt, + get_remote_ipaddr(), + get_remote_port(), + get_local_ipaddr(packet_get_connection_in()), + get_local_port(), + responses[0], + get_local_name(packet_get_connection_in())); + } + close(1); + _exit(0); + } else { + close(1); + if (email < 0) { + _exit(1); + } + } + _exit(0); + } else if (bg > 0) { + int status; + waitpid(bg, &status, 0); + } + if (ret != -1) return 0; return -1; } static void diff -U4 -r openssh-4.5p1/monitor.c openssh-4.5p1+skey/monitor.c --- openssh-4.5p1/monitor.c 2006-11-07 12:16:08.000000000 +0000 +++ openssh-4.5p1+skey/monitor.c 2007-02-10 11:02:42.000000000 +0000 @@ -46,8 +46,10 @@ #include #ifdef SKEY #include +#define _GNU_SOURCE +#include #endif #include @@ -818,10 +820,114 @@ response = buffer_get_string(m, NULL); authok = (options.challenge_response_authentication && authctxt->valid && - skey_haskey(authctxt->pw->pw_name) == 0 && - skey_passcheck(authctxt->pw->pw_name, response) != -1); + skey_haskey(authctxt->pw->pw_name) == 0); + + if (authok) { + struct skey skey_used; + struct skey skey_next; + char skey_used_prompt[1024]; + char skey_next_prompt[1024]; + pid_t bg; + + if (getskeyprompt(&skey_used, authctxt->pw->pw_name, skey_used_prompt) != 0) + skey_used_prompt[0] = 0; + else if (strlen(skey_used_prompt) > 0) + skey_used_prompt[strlen(skey_used_prompt)-1] = 0; + authok = (skey_passcheck(authctxt->pw->pw_name, response) != -1); + if (getskeyprompt(&skey_next, authctxt->pw->pw_name, skey_next_prompt) != 0) + skey_next_prompt[0] = 0; + else if (strlen(skey_next_prompt) > 0) + skey_next_prompt[strlen(skey_next_prompt)-1] = 0; + if (authok || (response[0] != 0)) + bg = fork(); + else + bg = -1; + if (bg == 0) { + int p[2] = { -1, -1 }; + pid_t sendmail; + pid_t email; + + if ((pipe(p) != 0) + || (dup2(p[0], 0) == -1) + || (dup2(p[1], 1) == -1)) { + if (p[0] != -1) close(p[0]); + if (p[1] != -1) close(p[1]); + close(0); + close(1); + close(2); + _exit(1); + } + close(p[0]); + close(p[1]); + + sendmail = fork(); + if (sendmail == 0) { + close(1); + execl("/usr/sbin/sendmail", "sendmail", authctxt->pw->pw_name, NULL); + close(0); + _exit(1); + } else { + close(0); + close(2); + if (sendmail < 0) { + close(1); + _exit(1); + } + } + + email = fork(); + if (email == 0) { + if (authok) { + dprintf(1, + "Subject: S/Key AUTH %s\n\n" + "S/Key \"%s\" was used to authenticate to %s.\n\n" + "From %s %d\n" + "To %s %d\n\n" + "Next S/Key is \"%s\".\n\n" + "-- \n%s\n", + skey_used_prompt, + skey_used_prompt, + get_local_name(packet_get_connection_in()), + get_remote_ipaddr(), + get_remote_port(), + get_local_ipaddr(packet_get_connection_in()), + get_local_port(), + skey_next_prompt, + get_local_name(packet_get_connection_in())); + } else { + dprintf(1, + "Subject: S/Key FAILED %s\n\n" + "An attempt was made to authenticate to %s using S/Key \"%s\".\n\n" + "From %s %d\n" + "To %s %d\n\n" + "Passphrase: \"%s\"\n\n" + "-- \n%s\n", + skey_used_prompt, + get_local_name(packet_get_connection_in()), + skey_used_prompt, + get_remote_ipaddr(), + get_remote_port(), + get_local_ipaddr(packet_get_connection_in()), + get_local_port(), + response, + get_local_name(packet_get_connection_in())); + } + close(1); + _exit(0); + } else { + close(1); + if (email < 0) { + _exit(1); + } + } + _exit(0); + } else if (bg > 0) { + int status; + waitpid(bg, &status, 0); + } + } xfree(response); buffer_clear(m);