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