blob: dbf24f67a52553b5547bfc2a57f817986b7d87be [file] [log] [blame]
Ben Lindstromfd496052000-11-05 07:52:55 +00001#include "includes.h"
Ben Lindstrom46c16222000-12-22 01:43:59 +00002RCSID("$OpenBSD: auth2-skey.c,v 1.2 2000/12/19 23:17:55 markus Exp $");
Ben Lindstromfd496052000-11-05 07:52:55 +00003
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
12void send_userauth_into_request(Authctxt *authctxt, int echo);
13void 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 */
19int
20auth2_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
27void
28send_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
60void
61input_userauth_info_response(int type, int plen, void *ctxt)
62{
63 Authctxt *authctxt = ctxt;
64 int authenticated = 0;
Ben Lindstrom46c16222000-12-22 01:43:59 +000065 u_int nresp, rlen;
Ben Lindstromfd496052000-11-05 07:52:55 +000066 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 */