33
|
1 #include "includes.h" |
|
2 #include "session.h" |
|
3 #include "auth.h" |
|
4 #include "dbutil.h" |
|
5 #include "buffer.h" |
|
6 #include "ssh.h" |
|
7 #include "packet.h" |
|
8 #include "runopts.h" |
|
9 |
|
10 void cli_authinitialise() { |
|
11 |
|
12 memset(&ses.authstate, 0, sizeof(ses.authstate)); |
|
13 } |
|
14 |
|
15 |
|
16 void cli_get_user() { |
|
17 |
|
18 uid_t uid; |
|
19 struct passwd *pw; |
|
20 |
|
21 TRACE(("enter cli_get_user")); |
|
22 if (cli_opts.username != NULL) { |
|
23 ses.authstate.username = cli_opts.username; |
|
24 } else { |
|
25 uid = getuid(); |
|
26 |
|
27 pw = getpwuid(uid); |
|
28 if (pw == NULL || pw->pw_name == NULL) { |
|
29 dropbear_exit("Couldn't find username for current user"); |
|
30 } |
|
31 |
|
32 ses.authstate.username = m_strdup(pw->pw_name); |
|
33 } |
|
34 TRACE(("leave cli_get_user: %s", cli_ses.username)); |
|
35 } |
|
36 |
|
37 /* Send a "none" auth request to get available methods */ |
|
38 void cli_auth_getmethods() { |
|
39 |
|
40 TRACE(("enter cli_auth_getmethods")); |
|
41 |
|
42 CHECKCLEARTOWRITE(); |
|
43 |
|
44 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); |
|
45 buf_putstring(ses.writepayload, ses.authstate.username, |
|
46 strlen(ses.authstate.username)); |
|
47 buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, |
|
48 SSH_SERVICE_CONNECTION_LEN); |
|
49 buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ |
|
50 |
|
51 encrypt_packet(); |
|
52 cli_ses.state = USERAUTH_METHODS_SENT; |
|
53 TRACE(("leave cli_auth_getmethods")); |
|
54 |
|
55 } |
|
56 |
|
57 void recv_msg_userauth_failure() { |
|
58 |
|
59 unsigned char * methods = NULL; |
|
60 unsigned char * tok = NULL; |
|
61 unsigned int methlen = 0; |
|
62 unsigned int partial = 0; |
|
63 unsigned int i = 0; |
|
64 |
|
65 TRACE(("<- MSG_USERAUTH_FAILURE")); |
|
66 TRACE(("enter recv_msg_userauth_failure")); |
|
67 |
|
68 methods = buf_getstring(ses.payload, &methlen); |
|
69 |
|
70 partial = buf_getbyte(ses.payload); |
|
71 |
|
72 if (partial) { |
|
73 dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required"); |
|
74 } else { |
|
75 ses.authstate.failcount++; |
|
76 } |
|
77 |
|
78 TRACE(("Methods (len %d): '%s'", methlen, methods)); |
|
79 |
|
80 ses.authstate.authdone=0; |
|
81 ses.authstate.authtypes=0; |
|
82 |
|
83 /* Split with nulls rather than commas */ |
|
84 for (i = 0; i < methlen; i++) { |
|
85 if (methods[i] == ',') { |
|
86 methods[i] = '\0'; |
|
87 } |
|
88 } |
|
89 |
|
90 tok = methods; /* tok stores the next method we'll compare */ |
|
91 for (i = 0; i <= methlen; i++) { |
|
92 if (methods[i] == '\0') { |
|
93 TRACE(("auth method '%s'\n", tok)); |
|
94 #ifdef DROPBEAR_PUBKEY_AUTH |
|
95 if (strncmp(AUTH_METHOD_PUBKEY, tok, |
|
96 AUTH_METHOD_PUBKEY_LEN) == 0) { |
|
97 ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; |
|
98 } |
|
99 #endif |
|
100 #ifdef DROPBEAR_PASSWORD_AUTH |
|
101 if (strncmp(AUTH_METHOD_PASSWORD, tok, |
|
102 AUTH_METHOD_PASSWORD_LEN) == 0) { |
|
103 ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; |
|
104 } |
|
105 #endif |
|
106 tok = &methods[i]; /* Must make sure we don't use it after |
|
107 the last loop, since it'll point |
|
108 to something undefined */ |
|
109 } |
|
110 } |
|
111 |
|
112 cli_ses.state = USERAUTH_FAIL_RCVD; |
|
113 |
|
114 TRACE(("leave recv_msg_userauth_failure")); |
|
115 } |
|
116 |
|
117 void recv_msg_userauth_success() { |
|
118 TRACE(("received msg_userauth_success")); |
|
119 ses.authstate.authdone = 1; |
|
120 } |
|
121 |
|
122 void cli_auth_try() { |
|
123 |
|
124 TRACE(("enter cli_auth_try")); |
|
125 int finished = 0; |
|
126 |
|
127 CHECKCLEARTOWRITE(); |
|
128 |
|
129 /* XXX We hardcode that we try a pubkey first */ |
|
130 #ifdef DROPBEAR_PUBKEY_AUTH |
|
131 if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { |
|
132 finished = cli_auth_pubkey(); |
|
133 } |
|
134 #endif |
|
135 |
|
136 #ifdef DROPBEAR_PASSWORD_AUTH |
|
137 if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { |
|
138 finished = cli_auth_password(); |
|
139 } |
|
140 #endif |
|
141 |
|
142 if (!finished) { |
|
143 dropbear_exit("No auth methods could be used."); |
|
144 } |
|
145 |
|
146 cli_ses.state = USERAUTH_REQ_SENT; |
|
147 TRACE(("leave cli_auth_try")); |
|
148 } |