Ben Lindstrom | fd49605 | 2000-11-05 07:52:55 +0000 | [diff] [blame] | 1 | #include "includes.h" |
Ben Lindstrom | 46c1622 | 2000-12-22 01:43:59 +0000 | [diff] [blame] | 2 | RCSID("$OpenBSD: auth2-skey.c,v 1.2 2000/12/19 23:17:55 markus Exp $"); |
Ben Lindstrom | fd49605 | 2000-11-05 07:52:55 +0000 | [diff] [blame] | 3 | |
| 4 | #ifdef SKEY |
| 5 | #include "ssh.h" |
| 6 | #include "ssh2.h" |
| 7 | #include "auth.h" |
| 8 | #include "packet.h" |
| 9 | #include "xmalloc.h" |
| 10 | #include "dispatch.h" |
| 11 | |
| 12 | void send_userauth_into_request(Authctxt *authctxt, int echo); |
| 13 | void input_userauth_info_response(int type, int plen, void *ctxt); |
| 14 | |
| 15 | /* |
| 16 | * try skey authentication, always return -1 (= postponed) since we have to |
| 17 | * wait for the s/key response. |
| 18 | */ |
| 19 | int |
| 20 | auth2_skey(Authctxt *authctxt) |
| 21 | { |
| 22 | send_userauth_into_request(authctxt, 0); |
| 23 | dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &input_userauth_info_response); |
| 24 | return -1; |
| 25 | } |
| 26 | |
| 27 | void |
| 28 | send_userauth_into_request(Authctxt *authctxt, int echo) |
| 29 | { |
| 30 | int retval = -1; |
| 31 | struct skey skey; |
| 32 | char challenge[SKEY_MAX_CHALLENGE]; |
| 33 | char *fake; |
| 34 | |
| 35 | if (authctxt->user == NULL) |
| 36 | fatal("send_userauth_into_request: internal error: no user"); |
| 37 | |
| 38 | /* get skey challenge */ |
| 39 | if (authctxt->valid) |
| 40 | retval = skeychallenge(&skey, authctxt->user, challenge); |
| 41 | |
| 42 | if (retval == -1) { |
| 43 | fake = skey_fake_keyinfo(authctxt->user); |
| 44 | strlcpy(challenge, fake, sizeof challenge); |
| 45 | } |
| 46 | /* send our info request */ |
| 47 | packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); |
| 48 | packet_put_cstring("S/Key Authentication"); /* Name */ |
| 49 | packet_put_cstring(challenge); /* Instruction */ |
| 50 | packet_put_cstring(""); /* Language */ |
| 51 | packet_put_int(1); /* Number of prompts */ |
| 52 | packet_put_cstring(echo ? |
| 53 | "Response [Echo]: ": "Response: "); /* Prompt */ |
| 54 | packet_put_char(echo); /* Echo */ |
| 55 | packet_send(); |
| 56 | packet_write_wait(); |
| 57 | memset(challenge, 'c', sizeof challenge); |
| 58 | } |
| 59 | |
| 60 | void |
| 61 | input_userauth_info_response(int type, int plen, void *ctxt) |
| 62 | { |
| 63 | Authctxt *authctxt = ctxt; |
| 64 | int authenticated = 0; |
Ben Lindstrom | 46c1622 | 2000-12-22 01:43:59 +0000 | [diff] [blame] | 65 | u_int nresp, rlen; |
Ben Lindstrom | fd49605 | 2000-11-05 07:52:55 +0000 | [diff] [blame] | 66 | char *resp, *method; |
| 67 | |
| 68 | if (authctxt == NULL) |
| 69 | fatal("input_userauth_info_response: no authentication context"); |
| 70 | |
| 71 | if (authctxt->attempt++ >= AUTH_FAIL_MAX) |
| 72 | packet_disconnect("too many failed userauth_requests"); |
| 73 | |
| 74 | nresp = packet_get_int(); |
| 75 | if (nresp == 1) { |
| 76 | /* we only support s/key and assume s/key for nresp == 1 */ |
| 77 | method = "s/key"; |
| 78 | resp = packet_get_string(&rlen); |
| 79 | packet_done(); |
| 80 | if (strlen(resp) == 0) { |
| 81 | /* |
| 82 | * if we received a null response, resend prompt with |
| 83 | * echo enabled |
| 84 | */ |
| 85 | authenticated = -1; |
| 86 | userauth_log(authctxt, authenticated, method); |
| 87 | send_userauth_into_request(authctxt, 1); |
| 88 | } else { |
| 89 | /* verify skey response */ |
| 90 | if (authctxt->valid && |
| 91 | skey_haskey(authctxt->pw->pw_name) == 0 && |
| 92 | skey_passcheck(authctxt->pw->pw_name, resp) != -1) { |
| 93 | authenticated = 1; |
| 94 | } else { |
| 95 | authenticated = 0; |
| 96 | } |
| 97 | memset(resp, 'r', rlen); |
| 98 | /* unregister callback */ |
| 99 | dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); |
| 100 | userauth_log(authctxt, authenticated, method); |
| 101 | userauth_reply(authctxt, authenticated); |
| 102 | } |
| 103 | xfree(resp); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | #endif /* SKEY */ |