| #include "includes.h" |
| RCSID("$OpenBSD: auth2-skey.c,v 1.2 2000/12/19 23:17:55 markus Exp $"); |
| |
| #ifdef SKEY |
| #include "ssh.h" |
| #include "ssh2.h" |
| #include "auth.h" |
| #include "packet.h" |
| #include "xmalloc.h" |
| #include "dispatch.h" |
| |
| void send_userauth_into_request(Authctxt *authctxt, int echo); |
| void input_userauth_info_response(int type, int plen, void *ctxt); |
| |
| /* |
| * try skey authentication, always return -1 (= postponed) since we have to |
| * wait for the s/key response. |
| */ |
| int |
| auth2_skey(Authctxt *authctxt) |
| { |
| send_userauth_into_request(authctxt, 0); |
| dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &input_userauth_info_response); |
| return -1; |
| } |
| |
| void |
| send_userauth_into_request(Authctxt *authctxt, int echo) |
| { |
| int retval = -1; |
| struct skey skey; |
| char challenge[SKEY_MAX_CHALLENGE]; |
| char *fake; |
| |
| if (authctxt->user == NULL) |
| fatal("send_userauth_into_request: internal error: no user"); |
| |
| /* get skey challenge */ |
| if (authctxt->valid) |
| retval = skeychallenge(&skey, authctxt->user, challenge); |
| |
| if (retval == -1) { |
| fake = skey_fake_keyinfo(authctxt->user); |
| strlcpy(challenge, fake, sizeof challenge); |
| } |
| /* send our info request */ |
| packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); |
| packet_put_cstring("S/Key Authentication"); /* Name */ |
| packet_put_cstring(challenge); /* Instruction */ |
| packet_put_cstring(""); /* Language */ |
| packet_put_int(1); /* Number of prompts */ |
| packet_put_cstring(echo ? |
| "Response [Echo]: ": "Response: "); /* Prompt */ |
| packet_put_char(echo); /* Echo */ |
| packet_send(); |
| packet_write_wait(); |
| memset(challenge, 'c', sizeof challenge); |
| } |
| |
| void |
| input_userauth_info_response(int type, int plen, void *ctxt) |
| { |
| Authctxt *authctxt = ctxt; |
| int authenticated = 0; |
| u_int nresp, rlen; |
| char *resp, *method; |
| |
| if (authctxt == NULL) |
| fatal("input_userauth_info_response: no authentication context"); |
| |
| if (authctxt->attempt++ >= AUTH_FAIL_MAX) |
| packet_disconnect("too many failed userauth_requests"); |
| |
| nresp = packet_get_int(); |
| if (nresp == 1) { |
| /* we only support s/key and assume s/key for nresp == 1 */ |
| method = "s/key"; |
| resp = packet_get_string(&rlen); |
| packet_done(); |
| if (strlen(resp) == 0) { |
| /* |
| * if we received a null response, resend prompt with |
| * echo enabled |
| */ |
| authenticated = -1; |
| userauth_log(authctxt, authenticated, method); |
| send_userauth_into_request(authctxt, 1); |
| } else { |
| /* verify skey response */ |
| if (authctxt->valid && |
| skey_haskey(authctxt->pw->pw_name) == 0 && |
| skey_passcheck(authctxt->pw->pw_name, resp) != -1) { |
| authenticated = 1; |
| } else { |
| authenticated = 0; |
| } |
| memset(resp, 'r', rlen); |
| /* unregister callback */ |
| dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); |
| userauth_log(authctxt, authenticated, method); |
| userauth_reply(authctxt, authenticated); |
| } |
| xfree(resp); |
| } |
| } |
| |
| #endif /* SKEY */ |