comparison svr-auth.c @ 165:0cfba3034be5

Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
author Matt Johnston <matt@ucc.asn.au>
date Sun, 02 Jan 2005 20:25:56 +0000
parents 364a75cfebab
children f4cf0415fec1 740e782679be baea1d43e7eb
comparison
equal deleted inserted replaced
161:b9d3f725e00b 165:0cfba3034be5
65 65
66 /* Send a banner message if specified to the client. The client might 66 /* Send a banner message if specified to the client. The client might
67 * ignore this, but possibly serves as a legal "no trespassing" sign */ 67 * ignore this, but possibly serves as a legal "no trespassing" sign */
68 static void send_msg_userauth_banner() { 68 static void send_msg_userauth_banner() {
69 69
70 TRACE(("enter send_msg_userauth_banner")); 70 TRACE(("enter send_msg_userauth_banner"))
71 if (svr_opts.banner == NULL) { 71 if (svr_opts.banner == NULL) {
72 TRACE(("leave send_msg_userauth_banner: banner is NULL")); 72 TRACE(("leave send_msg_userauth_banner: banner is NULL"))
73 return; 73 return;
74 } 74 }
75 75
76 CHECKCLEARTOWRITE(); 76 CHECKCLEARTOWRITE();
77 77
82 82
83 encrypt_packet(); 83 encrypt_packet();
84 buf_free(svr_opts.banner); 84 buf_free(svr_opts.banner);
85 svr_opts.banner = NULL; 85 svr_opts.banner = NULL;
86 86
87 TRACE(("leave send_msg_userauth_banner")); 87 TRACE(("leave send_msg_userauth_banner"))
88 } 88 }
89 89
90 /* handle a userauth request, check validity, pass to password or pubkey 90 /* handle a userauth request, check validity, pass to password or pubkey
91 * checking, and handle success or failure */ 91 * checking, and handle success or failure */
92 void recv_msg_userauth_request() { 92 void recv_msg_userauth_request() {
93 93
94 unsigned char *username = NULL, *servicename = NULL, *methodname = NULL; 94 unsigned char *username = NULL, *servicename = NULL, *methodname = NULL;
95 unsigned int userlen, servicelen, methodlen; 95 unsigned int userlen, servicelen, methodlen;
96 96
97 TRACE(("enter recv_msg_userauth_request")); 97 TRACE(("enter recv_msg_userauth_request"))
98 98
99 /* ignore packets if auth is already done */ 99 /* ignore packets if auth is already done */
100 if (ses.authstate.authdone == 1) { 100 if (ses.authstate.authdone == 1) {
101 TRACE(("leave recv_msg_userauth_request: authdone already")); 101 TRACE(("leave recv_msg_userauth_request: authdone already"))
102 return; 102 return;
103 } 103 }
104 104
105 /* send the banner if it exists, it will only exist once */ 105 /* send the banner if it exists, it will only exist once */
106 if (svr_opts.banner) { 106 if (svr_opts.banner) {
126 126
127 /* user wants to know what methods are supported */ 127 /* user wants to know what methods are supported */
128 if (methodlen == AUTH_METHOD_NONE_LEN && 128 if (methodlen == AUTH_METHOD_NONE_LEN &&
129 strncmp(methodname, AUTH_METHOD_NONE, 129 strncmp(methodname, AUTH_METHOD_NONE,
130 AUTH_METHOD_NONE_LEN) == 0) { 130 AUTH_METHOD_NONE_LEN) == 0) {
131 TRACE(("recv_msg_userauth_request: 'none' request")); 131 TRACE(("recv_msg_userauth_request: 'none' request"))
132 send_msg_userauth_failure(0, 0); 132 send_msg_userauth_failure(0, 0);
133 goto out; 133 goto out;
134 } 134 }
135 135
136 /* check username is good before continuing */ 136 /* check username is good before continuing */
137 if (checkusername(username, userlen) == DROPBEAR_FAILURE) { 137 if (checkusername(username, userlen) == DROPBEAR_FAILURE) {
138 /* username is invalid/no shell/etc - send failure */ 138 /* username is invalid/no shell/etc - send failure */
139 TRACE(("sending checkusername failure")); 139 TRACE(("sending checkusername failure"))
140 send_msg_userauth_failure(0, 1); 140 send_msg_userauth_failure(0, 1);
141 goto out; 141 goto out;
142 } 142 }
143 143
144 #ifdef ENABLE_SVR_PASSWORD_AUTH 144 #ifdef ENABLE_SVR_PASSWORD_AUTH
193 static int checkusername(unsigned char *username, unsigned int userlen) { 193 static int checkusername(unsigned char *username, unsigned int userlen) {
194 194
195 char* listshell = NULL; 195 char* listshell = NULL;
196 char* usershell = NULL; 196 char* usershell = NULL;
197 197
198 TRACE(("enter checkusername")); 198 TRACE(("enter checkusername"))
199 if (userlen > MAX_USERNAME_LEN) { 199 if (userlen > MAX_USERNAME_LEN) {
200 return DROPBEAR_FAILURE; 200 return DROPBEAR_FAILURE;
201 } 201 }
202 202
203 /* new user or username has changed */ 203 /* new user or username has changed */
215 m_free(ses.authstate.printableuser); 215 m_free(ses.authstate.printableuser);
216 } 216 }
217 217
218 /* check that user exists */ 218 /* check that user exists */
219 if (ses.authstate.pw == NULL) { 219 if (ses.authstate.pw == NULL) {
220 TRACE(("leave checkusername: user '%s' doesn't exist", username)); 220 TRACE(("leave checkusername: user '%s' doesn't exist", username))
221 dropbear_log(LOG_WARNING, 221 dropbear_log(LOG_WARNING,
222 "login attempt for nonexistent user from %s", 222 "login attempt for nonexistent user from %s",
223 svr_ses.addrstring); 223 svr_ses.addrstring);
224 send_msg_userauth_failure(0, 1); 224 send_msg_userauth_failure(0, 1);
225 return DROPBEAR_FAILURE; 225 return DROPBEAR_FAILURE;
228 /* We can set it once we know its a real user */ 228 /* We can set it once we know its a real user */
229 ses.authstate.printableuser = m_strdup(ses.authstate.pw->pw_name); 229 ses.authstate.printableuser = m_strdup(ses.authstate.pw->pw_name);
230 230
231 /* check for non-root if desired */ 231 /* check for non-root if desired */
232 if (svr_opts.norootlogin && ses.authstate.pw->pw_uid == 0) { 232 if (svr_opts.norootlogin && ses.authstate.pw->pw_uid == 0) {
233 TRACE(("leave checkusername: root login disabled")); 233 TRACE(("leave checkusername: root login disabled"))
234 dropbear_log(LOG_WARNING, "root login rejected"); 234 dropbear_log(LOG_WARNING, "root login rejected");
235 send_msg_userauth_failure(0, 1); 235 send_msg_userauth_failure(0, 1);
236 return DROPBEAR_FAILURE; 236 return DROPBEAR_FAILURE;
237 } 237 }
238 238
239 /* check for an empty password */ 239 /* check for an empty password */
240 if (ses.authstate.pw->pw_passwd[0] == '\0') { 240 if (ses.authstate.pw->pw_passwd[0] == '\0') {
241 TRACE(("leave checkusername: empty pword")); 241 TRACE(("leave checkusername: empty pword"))
242 dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected", 242 dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected",
243 ses.authstate.printableuser); 243 ses.authstate.printableuser);
244 send_msg_userauth_failure(0, 1); 244 send_msg_userauth_failure(0, 1);
245 return DROPBEAR_FAILURE; 245 return DROPBEAR_FAILURE;
246 } 246 }
247 247
248 TRACE(("shell is %s", ses.authstate.pw->pw_shell)); 248 TRACE(("shell is %s", ses.authstate.pw->pw_shell))
249 249
250 /* check that the shell is set */ 250 /* check that the shell is set */
251 usershell = ses.authstate.pw->pw_shell; 251 usershell = ses.authstate.pw->pw_shell;
252 if (usershell[0] == '\0') { 252 if (usershell[0] == '\0') {
253 /* empty shell in /etc/passwd means /bin/sh according to passwd(5) */ 253 /* empty shell in /etc/passwd means /bin/sh according to passwd(5) */
257 /* check the shell is valid. If /etc/shells doesn't exist, getusershell() 257 /* check the shell is valid. If /etc/shells doesn't exist, getusershell()
258 * should return some standard shells like "/bin/sh" and "/bin/csh" (this 258 * should return some standard shells like "/bin/sh" and "/bin/csh" (this
259 * is platform-specific) */ 259 * is platform-specific) */
260 setusershell(); 260 setusershell();
261 while ((listshell = getusershell()) != NULL) { 261 while ((listshell = getusershell()) != NULL) {
262 TRACE(("test shell is '%s'", listshell)); 262 TRACE(("test shell is '%s'", listshell))
263 if (strcmp(listshell, usershell) == 0) { 263 if (strcmp(listshell, usershell) == 0) {
264 /* have a match */ 264 /* have a match */
265 goto goodshell; 265 goto goodshell;
266 } 266 }
267 } 267 }
268 /* no matching shell */ 268 /* no matching shell */
269 endusershell(); 269 endusershell();
270 TRACE(("no matching shell")); 270 TRACE(("no matching shell"))
271 dropbear_log(LOG_WARNING, "user '%s' has invalid shell, rejected", 271 dropbear_log(LOG_WARNING, "user '%s' has invalid shell, rejected",
272 ses.authstate.printableuser); 272 ses.authstate.printableuser);
273 send_msg_userauth_failure(0, 1); 273 send_msg_userauth_failure(0, 1);
274 return DROPBEAR_FAILURE; 274 return DROPBEAR_FAILURE;
275 275
276 goodshell: 276 goodshell:
277 endusershell(); 277 endusershell();
278 TRACE(("matching shell")); 278 TRACE(("matching shell"))
279 279
280 TRACE(("uid = %d", ses.authstate.pw->pw_uid)); 280 TRACE(("uid = %d", ses.authstate.pw->pw_uid))
281 TRACE(("leave checkusername")); 281 TRACE(("leave checkusername"))
282 return DROPBEAR_SUCCESS; 282 return DROPBEAR_SUCCESS;
283 283
284 } 284 }
285 285
286 /* Send a failure message to the client, in responds to a userauth_request. 286 /* Send a failure message to the client, in responds to a userauth_request.
290 * failures */ 290 * failures */
291 void send_msg_userauth_failure(int partial, int incrfail) { 291 void send_msg_userauth_failure(int partial, int incrfail) {
292 292
293 buffer *typebuf = NULL; 293 buffer *typebuf = NULL;
294 294
295 TRACE(("enter send_msg_userauth_failure")); 295 TRACE(("enter send_msg_userauth_failure"))
296 296
297 CHECKCLEARTOWRITE(); 297 CHECKCLEARTOWRITE();
298 298
299 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_FAILURE); 299 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_FAILURE);
300 300
329 } 329 }
330 330
331 if (ses.authstate.failcount >= MAX_AUTH_TRIES) { 331 if (ses.authstate.failcount >= MAX_AUTH_TRIES) {
332 char * userstr; 332 char * userstr;
333 /* XXX - send disconnect ? */ 333 /* XXX - send disconnect ? */
334 TRACE(("Max auth tries reached, exiting")); 334 TRACE(("Max auth tries reached, exiting"))
335 335
336 if (ses.authstate.printableuser == NULL) { 336 if (ses.authstate.printableuser == NULL) {
337 userstr = "is invalid"; 337 userstr = "is invalid";
338 } else { 338 } else {
339 userstr = ses.authstate.printableuser; 339 userstr = ses.authstate.printableuser;
340 } 340 }
341 dropbear_exit("Max auth tries reached - user '%s' from %s", 341 dropbear_exit("Max auth tries reached - user '%s' from %s",
342 userstr, svr_ses.addrstring); 342 userstr, svr_ses.addrstring);
343 } 343 }
344 344
345 TRACE(("leave send_msg_userauth_failure")); 345 TRACE(("leave send_msg_userauth_failure"))
346 } 346 }
347 347
348 /* Send a success message to the user, and set the "authdone" flag */ 348 /* Send a success message to the user, and set the "authdone" flag */
349 void send_msg_userauth_success() { 349 void send_msg_userauth_success() {
350 350
351 TRACE(("enter send_msg_userauth_success")); 351 TRACE(("enter send_msg_userauth_success"))
352 352
353 CHECKCLEARTOWRITE(); 353 CHECKCLEARTOWRITE();
354 354
355 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS); 355 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS);
356 encrypt_packet(); 356 encrypt_packet();
366 /* Remove from the list of pre-auth sockets. Should be m_close(), since if 366 /* Remove from the list of pre-auth sockets. Should be m_close(), since if
367 * we fail, we might end up leaking connection slots, and disallow new 367 * we fail, we might end up leaking connection slots, and disallow new
368 * logins - a nasty situation. */ 368 * logins - a nasty situation. */
369 m_close(svr_ses.childpipe); 369 m_close(svr_ses.childpipe);
370 370
371 TRACE(("leave send_msg_userauth_success")); 371 TRACE(("leave send_msg_userauth_success"))
372 372
373 } 373 }