38
38
static void authclear();
39
39
static int checkusername(unsigned char *username, unsigned int userlen);
40
static void send_msg_userauth_banner();
42
41
/* initialise the first time for a session, resetting all parameters */
43
42
void svr_authinitialise() {
83
82
/* Send a banner message if specified to the client. The client might
84
83
* ignore this, but possibly serves as a legal "no trespassing" sign */
85
static void send_msg_userauth_banner() {
84
void send_msg_userauth_banner(buffer *banner) {
87
86
TRACE(("enter send_msg_userauth_banner"))
88
if (svr_opts.banner == NULL) {
89
TRACE(("leave send_msg_userauth_banner: banner is NULL"))
93
88
CHECKCLEARTOWRITE();
95
90
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_BANNER);
96
buf_putstring(ses.writepayload, buf_getptr(svr_opts.banner,
97
svr_opts.banner->len), svr_opts.banner->len);
91
buf_putstring(ses.writepayload, buf_getptr(banner, banner->len),
98
93
buf_putstring(ses.writepayload, "en", 2);
101
buf_free(svr_opts.banner);
102
svr_opts.banner = NULL;
104
97
TRACE(("leave send_msg_userauth_banner"))
111
104
unsigned char *username = NULL, *servicename = NULL, *methodname = NULL;
112
105
unsigned int userlen, servicelen, methodlen;
114
108
TRACE(("enter recv_msg_userauth_request"))
122
116
/* send the banner if it exists, it will only exist once */
123
117
if (svr_opts.banner) {
124
send_msg_userauth_banner();
118
send_msg_userauth_banner(svr_opts.banner);
119
buf_free(svr_opts.banner);
120
svr_opts.banner = NULL;
128
123
username = buf_getstring(ses.payload, &userlen);
129
124
servicename = buf_getstring(ses.payload, &servicelen);
130
125
methodname = buf_getstring(ses.payload, &methodlen);
141
136
dropbear_exit("unknown service in auth");
139
/* check username is good before continuing.
140
* the 'incrfail' varies depending on the auth method to
141
* avoid giving away which users exist on the system through
143
if (checkusername(username, userlen) == DROPBEAR_SUCCESS) {
144
147
/* user wants to know what methods are supported */
145
148
if (methodlen == AUTH_METHOD_NONE_LEN &&
146
149
strncmp(methodname, AUTH_METHOD_NONE,
147
150
AUTH_METHOD_NONE_LEN) == 0) {
148
151
TRACE(("recv_msg_userauth_request: 'none' request"))
149
send_msg_userauth_failure(0, 0);
153
&& svr_opts.allowblankpass
154
&& !svr_opts.noauthpass
155
&& !(svr_opts.norootpass && ses.authstate.pw_uid == 0)
156
&& ses.authstate.pw_passwd[0] == '\0')
158
dropbear_log(LOG_NOTICE,
159
"Auth succeeded with blank password for '%s' from %s",
160
ses.authstate.pw_name,
162
send_msg_userauth_success();
167
/* 'none' has no failure delay */
168
send_msg_userauth_failure(0, 0);
153
/* check username is good before continuing */
154
if (checkusername(username, userlen) == DROPBEAR_FAILURE) {
155
/* username is invalid/no shell/etc - send failure */
156
TRACE(("sending checkusername failure"))
157
send_msg_userauth_failure(0, 1);
161
173
#ifdef ENABLE_SVR_PASSWORD_AUTH
162
174
if (!svr_opts.noauthpass &&
163
175
!(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
189
205
if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
190
206
strncmp(methodname, AUTH_METHOD_PUBKEY,
191
207
AUTH_METHOD_PUBKEY_LEN) == 0) {
211
/* pubkey has no failure delay */
212
send_msg_userauth_failure(0, 0);
197
/* nothing matched, we just fail */
218
/* nothing matched, we just fail with a delay */
198
219
send_msg_userauth_failure(0, 1);
208
/* Check that the username exists, has a non-empty password, and has a valid
229
/* Check that the username exists and isn't disallowed (root), and has a valid shell.
210
230
* returns DROPBEAR_SUCCESS on valid username, DROPBEAR_FAILURE on failure */
211
231
static int checkusername(unsigned char *username, unsigned int userlen) {
213
233
char* listshell = NULL;
214
234
char* usershell = NULL;
215
236
TRACE(("enter checkusername"))
216
237
if (userlen > MAX_USERNAME_LEN) {
217
238
return DROPBEAR_FAILURE;
237
258
dropbear_log(LOG_WARNING,
238
259
"Login attempt for nonexistent user from %s",
239
260
svr_ses.addrstring);
240
send_msg_userauth_failure(0, 1);
261
return DROPBEAR_FAILURE;
264
/* check if we are running as non-root, and login user is different from the server */
266
if (uid != 0 && uid != ses.authstate.pw_uid) {
267
TRACE(("running as nonroot, only server uid is allowed"))
268
dropbear_log(LOG_WARNING,
269
"Login attempt with wrong user %s from %s",
270
ses.authstate.pw_name,
241
272
return DROPBEAR_FAILURE;
245
276
if (svr_opts.norootlogin && ses.authstate.pw_uid == 0) {
246
277
TRACE(("leave checkusername: root login disabled"))
247
278
dropbear_log(LOG_WARNING, "root login rejected");
248
send_msg_userauth_failure(0, 1);
249
279
return DROPBEAR_FAILURE;
274
304
TRACE(("no matching shell"))
275
305
dropbear_log(LOG_WARNING, "User '%s' has invalid shell, rejected",
276
306
ses.authstate.pw_name);
277
send_msg_userauth_failure(0, 1);
278
307
return DROPBEAR_FAILURE;
332
360
unsigned int delay;
333
361
genrandom((unsigned char*)&delay, sizeof(delay));
334
/* We delay for 300ms +- 50ms, 0.1ms granularity */
335
delay = 250000 + (delay % 1000)*100;
362
/* We delay for 300ms +- 50ms */
363
delay = 250000 + (delay % 100000);
337
365
ses.authstate.failcount++;