]> andersk Git - openssh.git/blame - auth.c
- OpenBSD CVS updates.
[openssh.git] / auth.c
CommitLineData
7368a6c8 1/*
2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 * All rights reserved
e78a59f5 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
7368a6c8 5 */
6
7#include "includes.h"
6ae2364d 8RCSID("$OpenBSD: auth.c,v 1.4 2000/04/14 10:30:29 markus Exp $");
7368a6c8 9
10#include "xmalloc.h"
11#include "rsa.h"
12#include "ssh.h"
13#include "pty.h"
14#include "packet.h"
15#include "buffer.h"
16#include "cipher.h"
17#include "mpaux.h"
18#include "servconf.h"
e78a59f5 19#include "compat.h"
7368a6c8 20#include "channels.h"
21#include "match.h"
22
e78a59f5 23#include "bufaux.h"
24#include "ssh2.h"
25#include "auth.h"
7368a6c8 26#include "session.h"
27#include "dispatch.h"
28
e78a59f5 29
7368a6c8 30/* import */
31extern ServerOptions options;
32extern char *forced_command;
33
34/*
35 * Check if the user is allowed to log in via ssh. If user is listed in
36 * DenyUsers or user's primary group is listed in DenyGroups, false will
37 * be returned. If AllowUsers isn't empty and user isn't listed there, or
38 * if AllowGroups isn't empty and user isn't listed there, false will be
6ae2364d 39 * returned.
7368a6c8 40 * If the user's shell is not executable, false will be returned.
6ae2364d 41 * Otherwise true is returned.
7368a6c8 42 */
43static int
44allowed_user(struct passwd * pw)
45{
46 struct stat st;
47 struct group *grp;
48 int i;
49#ifdef WITH_AIXAUTHENTICATE
50 char *loginmsg;
51#endif /* WITH_AIXAUTHENTICATE */
52
53 /* Shouldn't be called if pw is NULL, but better safe than sorry... */
54 if (!pw)
55 return 0;
56
57 /* deny if shell does not exists or is not executable */
58 if (stat(pw->pw_shell, &st) != 0)
59 return 0;
60 if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
61 return 0;
62
63 /* Return false if user is listed in DenyUsers */
64 if (options.num_deny_users > 0) {
65 if (!pw->pw_name)
66 return 0;
67 for (i = 0; i < options.num_deny_users; i++)
68 if (match_pattern(pw->pw_name, options.deny_users[i]))
69 return 0;
70 }
71 /* Return false if AllowUsers isn't empty and user isn't listed there */
72 if (options.num_allow_users > 0) {
73 if (!pw->pw_name)
74 return 0;
75 for (i = 0; i < options.num_allow_users; i++)
76 if (match_pattern(pw->pw_name, options.allow_users[i]))
77 break;
78 /* i < options.num_allow_users iff we break for loop */
79 if (i >= options.num_allow_users)
80 return 0;
81 }
82 /* Get the primary group name if we need it. Return false if it fails */
83 if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
84 grp = getgrgid(pw->pw_gid);
85 if (!grp)
86 return 0;
87
88 /* Return false if user's group is listed in DenyGroups */
89 if (options.num_deny_groups > 0) {
90 if (!grp->gr_name)
91 return 0;
92 for (i = 0; i < options.num_deny_groups; i++)
93 if (match_pattern(grp->gr_name, options.deny_groups[i]))
94 return 0;
95 }
96 /*
97 * Return false if AllowGroups isn't empty and user's group
98 * isn't listed there
99 */
100 if (options.num_allow_groups > 0) {
101 if (!grp->gr_name)
102 return 0;
103 for (i = 0; i < options.num_allow_groups; i++)
104 if (match_pattern(grp->gr_name, options.allow_groups[i]))
105 break;
106 /* i < options.num_allow_groups iff we break for
107 loop */
108 if (i >= options.num_allow_groups)
109 return 0;
110 }
111 }
112
113#ifdef WITH_AIXAUTHENTICATE
114 if (loginrestrictions(pw->pw_name,S_LOGIN,NULL,&loginmsg) != 0)
115 return 0;
116#endif /* WITH_AIXAUTHENTICATE */
117
118 /* We found no reason not to let this user try to log on... */
119 return 1;
120}
121
122/*
123 * convert ssh auth msg type into description
124 */
125char *
126get_authname(int type)
127{
128 static char buf[1024];
129 switch (type) {
130 case SSH_CMSG_AUTH_PASSWORD:
131 return "password";
132 case SSH_CMSG_AUTH_RSA:
133 return "rsa";
134 case SSH_CMSG_AUTH_RHOSTS_RSA:
135 return "rhosts-rsa";
136 case SSH_CMSG_AUTH_RHOSTS:
137 return "rhosts";
138#ifdef KRB4
139 case SSH_CMSG_AUTH_KERBEROS:
140 return "kerberos";
141#endif
142#ifdef SKEY
143 case SSH_CMSG_AUTH_TIS_RESPONSE:
144 return "s/key";
145#endif
146 }
147 snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
148 return buf;
149}
150
151#define AUTH_FAIL_MAX 6
152#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
153#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
154
155/*
156 * The user does not exist or access is denied,
157 * but fake indication that authentication is needed.
158 */
159void
160do_fake_authloop1(char *user)
161{
162 int attempt = 0;
163
164 log("Faking authloop for illegal user %.200s from %.200s port %d",
165 user,
166 get_remote_ipaddr(),
167 get_remote_port());
168
169#ifdef WITH_AIXAUTHENTICATE
170 if (strncmp(get_authname(type),"password",
171 strlen(get_authname(type))) == 0)
172 loginfailed(pw->pw_name,get_canonical_hostname(),"ssh");
173#endif /* WITH_AIXAUTHENTICATE */
174
175 /* Indicate that authentication is needed. */
176 packet_start(SSH_SMSG_FAILURE);
177 packet_send();
178 packet_write_wait();
179
180 /*
181 * Keep reading packets, and always respond with a failure. This is
182 * to avoid disclosing whether such a user really exists.
183 */
184 for (attempt = 1;; attempt++) {
185 /* Read a packet. This will not return if the client disconnects. */
186 int plen;
187#ifndef SKEY
188 (void)packet_read(&plen);
189#else /* SKEY */
190 int type = packet_read(&plen);
191 unsigned int dlen;
192 char *password, *skeyinfo;
193 /* Try to send a fake s/key challenge. */
194 if (options.skey_authentication == 1 &&
195 (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
196 password = NULL;
197 if (type == SSH_CMSG_AUTH_TIS) {
198 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
199 packet_put_string(skeyinfo, strlen(skeyinfo));
200 packet_send();
201 packet_write_wait();
202 continue;
203 } else if (type == SSH_CMSG_AUTH_PASSWORD &&
6ae2364d 204 options.password_authentication &&
205 (password = packet_get_string(&dlen)) != NULL &&
206 dlen == 5 &&
207 strncasecmp(password, "s/key", 5) == 0 ) {
7368a6c8 208 packet_send_debug(skeyinfo);
209 }
210 if (password != NULL)
211 xfree(password);
212 }
213#endif
214 if (attempt > AUTH_FAIL_MAX)
215 packet_disconnect(AUTH_FAIL_MSG, user);
216
217 /*
218 * Send failure. This should be indistinguishable from a
219 * failed authentication.
220 */
221 packet_start(SSH_SMSG_FAILURE);
222 packet_send();
223 packet_write_wait();
224 }
225 /* NOTREACHED */
226 abort();
227}
228
229/*
230 * read packets and try to authenticate local user *pw.
231 * return if authentication is successfull
232 */
233void
234do_authloop(struct passwd * pw)
235{
236 int attempt = 0;
237 unsigned int bits;
238 RSA *client_host_key;
239 BIGNUM *n;
240 char *client_user = NULL, *password = NULL;
241 char user[1024];
242 unsigned int dlen;
243 int plen, nlen, elen;
244 unsigned int ulen;
245 int type = 0;
246 void (*authlog) (const char *fmt,...) = verbose;
247
248 /* Indicate that authentication is needed. */
249 packet_start(SSH_SMSG_FAILURE);
250 packet_send();
251 packet_write_wait();
252
253 for (attempt = 1;; attempt++) {
254 int authenticated = 0;
255 strlcpy(user, "", sizeof user);
256
257 /* Get a packet from the client. */
258 type = packet_read(&plen);
259
260 /* Process the packet. */
261 switch (type) {
262#ifdef AFS
263 case SSH_CMSG_HAVE_KERBEROS_TGT:
264 if (!options.kerberos_tgt_passing) {
265 /* packet_get_all(); */
266 verbose("Kerberos tgt passing disabled.");
267 break;
268 } else {
269 /* Accept Kerberos tgt. */
270 char *tgt = packet_get_string(&dlen);
271 packet_integrity_check(plen, 4 + dlen, type);
272 if (!auth_kerberos_tgt(pw, tgt))
273 verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
274 xfree(tgt);
275 }
276 continue;
277
278 case SSH_CMSG_HAVE_AFS_TOKEN:
279 if (!options.afs_token_passing || !k_hasafs()) {
280 /* packet_get_all(); */
281 verbose("AFS token passing disabled.");
282 break;
283 } else {
284 /* Accept AFS token. */
285 char *token_string = packet_get_string(&dlen);
286 packet_integrity_check(plen, 4 + dlen, type);
287 if (!auth_afs_token(pw, token_string))
288 verbose("AFS token REFUSED for %s", pw->pw_name);
289 xfree(token_string);
290 }
291 continue;
292#endif /* AFS */
293#ifdef KRB4
294 case SSH_CMSG_AUTH_KERBEROS:
295 if (!options.kerberos_authentication) {
296 /* packet_get_all(); */
297 verbose("Kerberos authentication disabled.");
298 break;
299 } else {
300 /* Try Kerberos v4 authentication. */
301 KTEXT_ST auth;
302 char *tkt_user = NULL;
303 char *kdata = packet_get_string((unsigned int *) &auth.length);
304 packet_integrity_check(plen, 4 + auth.length, type);
305
306 if (auth.length < MAX_KTXT_LEN)
307 memcpy(auth.dat, kdata, auth.length);
308 xfree(kdata);
309
310 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
311
312 if (authenticated) {
313 snprintf(user, sizeof user, " tktuser %s", tkt_user);
314 xfree(tkt_user);
315 }
316 }
317 break;
318#endif /* KRB4 */
319
320 case SSH_CMSG_AUTH_RHOSTS:
321 if (!options.rhosts_authentication) {
322 verbose("Rhosts authentication disabled.");
323 break;
324 }
325 /*
326 * Get client user name. Note that we just have to
327 * trust the client; this is one reason why rhosts
328 * authentication is insecure. (Another is
329 * IP-spoofing on a local network.)
330 */
331 client_user = packet_get_string(&ulen);
332 packet_integrity_check(plen, 4 + ulen, type);
333
334 /* Try to authenticate using /etc/hosts.equiv and
335 .rhosts. */
336 authenticated = auth_rhosts(pw, client_user);
337
338 snprintf(user, sizeof user, " ruser %s", client_user);
339 break;
340
341 case SSH_CMSG_AUTH_RHOSTS_RSA:
342 if (!options.rhosts_rsa_authentication) {
343 verbose("Rhosts with RSA authentication disabled.");
344 break;
345 }
346 /*
347 * Get client user name. Note that we just have to
348 * trust the client; root on the client machine can
349 * claim to be any user.
350 */
351 client_user = packet_get_string(&ulen);
352
353 /* Get the client host key. */
354 client_host_key = RSA_new();
355 if (client_host_key == NULL)
356 fatal("RSA_new failed");
357 client_host_key->e = BN_new();
358 client_host_key->n = BN_new();
359 if (client_host_key->e == NULL || client_host_key->n == NULL)
360 fatal("BN_new failed");
361 bits = packet_get_int();
362 packet_get_bignum(client_host_key->e, &elen);
363 packet_get_bignum(client_host_key->n, &nlen);
364
365 if (bits != BN_num_bits(client_host_key->n))
366 error("Warning: keysize mismatch for client_host_key: "
367 "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
368 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
369
370 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
371 RSA_free(client_host_key);
372
373 snprintf(user, sizeof user, " ruser %s", client_user);
374 break;
375
376 case SSH_CMSG_AUTH_RSA:
377 if (!options.rsa_authentication) {
378 verbose("RSA authentication disabled.");
379 break;
380 }
381 /* RSA authentication requested. */
382 n = BN_new();
383 packet_get_bignum(n, &nlen);
384 packet_integrity_check(plen, nlen, type);
385 authenticated = auth_rsa(pw, n);
386 BN_clear_free(n);
387 break;
388
389 case SSH_CMSG_AUTH_PASSWORD:
390 if (!options.password_authentication) {
391 verbose("Password authentication disabled.");
392 break;
393 }
394 /*
395 * Read user password. It is in plain text, but was
396 * transmitted over the encrypted channel so it is
397 * not visible to an outside observer.
398 */
399 password = packet_get_string(&dlen);
400 packet_integrity_check(plen, 4 + dlen, type);
401
402#ifdef USE_PAM
403 /* Do PAM auth with password */
404 authenticated = auth_pam_password(pw, password);
405#else /* USE_PAM */
406 /* Try authentication with the password. */
407 authenticated = auth_password(pw, password);
408#endif /* USE_PAM */
409 memset(password, 0, strlen(password));
410 xfree(password);
411 break;
412
413#ifdef SKEY
414 case SSH_CMSG_AUTH_TIS:
415 debug("rcvd SSH_CMSG_AUTH_TIS");
416 if (options.skey_authentication == 1) {
417 char *skeyinfo = skey_keyinfo(pw->pw_name);
418 if (skeyinfo == NULL) {
419 debug("generating fake skeyinfo for %.100s.", pw->pw_name);
420 skeyinfo = skey_fake_keyinfo(pw->pw_name);
421 }
422 if (skeyinfo != NULL) {
423 /* we send our s/key- in tis-challenge messages */
424 debug("sending challenge '%s'", skeyinfo);
425 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
426 packet_put_string(skeyinfo, strlen(skeyinfo));
427 packet_send();
428 packet_write_wait();
429 continue;
430 }
431 }
432 break;
433 case SSH_CMSG_AUTH_TIS_RESPONSE:
434 debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
435 if (options.skey_authentication == 1) {
436 char *response = packet_get_string(&dlen);
437 debug("skey response == '%s'", response);
438 packet_integrity_check(plen, 4 + dlen, type);
439 authenticated = (skey_haskey(pw->pw_name) == 0 &&
440 skey_passcheck(pw->pw_name, response) != -1);
441 xfree(response);
442 }
443 break;
444#else
445 case SSH_CMSG_AUTH_TIS:
446 /* TIS Authentication is unsupported */
447 log("TIS authentication unsupported.");
448 break;
449#endif
450
451 default:
452 /*
453 * Any unknown messages will be ignored (and failure
454 * returned) during authentication.
455 */
456 log("Unknown message during authentication: type %d", type);
457 break;
458 }
459
6ae2364d 460 /*
461 * Check if the user is logging in as root and root logins
462 * are disallowed.
463 * Note that root login is allowed for forced commands.
464 */
465 if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
466 if (forced_command) {
467 log("Root login accepted for forced command.");
468 } else {
469 authenticated = 0;
470 log("ROOT LOGIN REFUSED FROM %.200s",
471 get_canonical_hostname());
472 }
473 }
7368a6c8 474
475 /* Raise logging level */
476 if (authenticated ||
477 attempt == AUTH_FAIL_LOG ||
478 type == SSH_CMSG_AUTH_PASSWORD)
479 authlog = log;
480
481 authlog("%s %s for %.200s from %.200s port %d%s",
482 authenticated ? "Accepted" : "Failed",
483 get_authname(type),
484 pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
485 get_remote_ipaddr(),
486 get_remote_port(),
487 user);
488
489#ifdef USE_PAM
490 if (authenticated) {
491 if (!do_pam_account(pw->pw_name, client_user)) {
492 if (client_user != NULL) {
493 xfree(client_user);
494 client_user = NULL;
495 }
496 do_fake_authloop1(pw->pw_name);
497 }
498 return;
499 }
500#else /* USE_PAM */
501 if (authenticated) {
502 return;
503 }
504#endif /* USE_PAM */
505
506 if (client_user != NULL) {
507 xfree(client_user);
508 client_user = NULL;
509 }
510
511 if (attempt > AUTH_FAIL_MAX)
512 packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
513
514 /* Send a message indicating that the authentication attempt failed. */
515 packet_start(SSH_SMSG_FAILURE);
516 packet_send();
517 packet_write_wait();
518 }
519}
520
521/*
522 * Performs authentication of an incoming connection. Session key has already
523 * been exchanged and encryption is enabled.
524 */
525void
526do_authentication()
527{
528 struct passwd *pw, pwcopy;
529 int plen;
530 unsigned int ulen;
531 char *user;
532#ifdef WITH_AIXAUTHENTICATE
533 char *loginmsg;
534#endif /* WITH_AIXAUTHENTICATE */
535
536 /* Get the name of the user that we wish to log in as. */
537 packet_read_expect(&plen, SSH_CMSG_USER);
538
539 /* Get the user name. */
540 user = packet_get_string(&ulen);
541 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
542
543 setproctitle("%s", user);
544
545#ifdef AFS
546 /* If machine has AFS, set process authentication group. */
547 if (k_hasafs()) {
548 k_setpag();
549 k_unlog();
550 }
551#endif /* AFS */
552
553 /* Verify that the user is a valid user. */
554 pw = getpwnam(user);
555 if (!pw || !allowed_user(pw))
556 do_fake_authloop1(user);
557 xfree(user);
558
559 /* Take a copy of the returned structure. */
560 memset(&pwcopy, 0, sizeof(pwcopy));
561 pwcopy.pw_name = xstrdup(pw->pw_name);
562 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
563 pwcopy.pw_uid = pw->pw_uid;
564 pwcopy.pw_gid = pw->pw_gid;
565 pwcopy.pw_dir = xstrdup(pw->pw_dir);
566 pwcopy.pw_shell = xstrdup(pw->pw_shell);
567 pw = &pwcopy;
568
569#ifdef USE_PAM
570 start_pam(pw);
571#endif
572
573 /*
574 * If we are not running as root, the user must have the same uid as
575 * the server.
576 */
577 if (getuid() != 0 && pw->pw_uid != getuid())
578 packet_disconnect("Cannot change user when server not running as root.");
579
580 debug("Attempting authentication for %.100s.", pw->pw_name);
581
582 /* If the user has no password, accept authentication immediately. */
583 if (options.password_authentication &&
584#ifdef KRB4
585 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
586#endif /* KRB4 */
587#ifdef USE_PAM
588 auth_pam_password(pw, "")) {
589#else /* USE_PAM */
590 auth_password(pw, "")) {
591#endif /* USE_PAM */
592 /* Authentication with empty password succeeded. */
593 log("Login for user %s from %.100s, accepted without authentication.",
594 pw->pw_name, get_remote_ipaddr());
595 } else {
596 /* Loop until the user has been authenticated or the
597 connection is closed, do_authloop() returns only if
598 authentication is successfull */
599 do_authloop(pw);
600 }
601
602 /* The user has been authenticated and accepted. */
603#ifdef WITH_AIXAUTHENTICATE
604 loginsuccess(user,get_canonical_hostname(),"ssh",&loginmsg);
605#endif /* WITH_AIXAUTHENTICATE */
606 packet_start(SSH_SMSG_SUCCESS);
607 packet_send();
608 packet_write_wait();
609
610 /* Perform session preparation. */
611 do_authenticated(pw);
612}
e78a59f5 613
614
615void input_service_request(int type, int plen);
616void input_userauth_request(int type, int plen);
617void ssh2_pty_cleanup(void);
618
619typedef struct Authctxt Authctxt;
620struct Authctxt {
621 char *user;
622 char *service;
623 struct passwd pw;
624 int valid;
625};
626static Authctxt *authctxt = NULL;
627static int userauth_success = 0;
628
629struct passwd*
630auth_get_user(void)
631{
632 return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
633}
634struct passwd*
635auth_set_user(char *u, char *s)
636{
637 struct passwd *pw, *copy;
638
639 if (authctxt == NULL) {
640 authctxt = xmalloc(sizeof(*authctxt));
641 authctxt->valid = 0;
642 authctxt->user = xstrdup(u);
643 authctxt->service = xstrdup(s);
644 setproctitle("%s", u);
645 pw = getpwnam(u);
646 if (!pw || !allowed_user(pw)) {
647 log("auth_set_user: bad user %s", u);
648 return NULL;
649 }
650#ifdef USE_PAM
651 start_pam(pw);
652#endif
653 copy = &authctxt->pw;
654 memset(copy, 0, sizeof(*copy));
655 copy->pw_name = xstrdup(pw->pw_name);
656 copy->pw_passwd = xstrdup(pw->pw_passwd);
657 copy->pw_uid = pw->pw_uid;
658 copy->pw_gid = pw->pw_gid;
659 copy->pw_dir = xstrdup(pw->pw_dir);
660 copy->pw_shell = xstrdup(pw->pw_shell);
661 authctxt->valid = 1;
662 } else {
663 if (strcmp(u, authctxt->user) != 0 ||
664 strcmp(s, authctxt->service) != 0) {
665 log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
666 u, s, authctxt->user, authctxt->service);
667 return NULL;
668 }
669 }
670 return auth_get_user();
671}
672
673static void
674protocol_error(int type, int plen)
675{
676 log("auth: protocol error: type %d plen %d", type, plen);
677 packet_start(SSH2_MSG_UNIMPLEMENTED);
678 packet_put_int(0);
679 packet_send();
680 packet_write_wait();
681}
682void
683input_service_request(int type, int plen)
684{
685 unsigned int len;
686 int accept = 0;
687 char *service = packet_get_string(&len);
6ae2364d 688 packet_done();
e78a59f5 689
690 if (strcmp(service, "ssh-userauth") == 0) {
691 if (!userauth_success) {
692 accept = 1;
693 /* now we can handle user-auth requests */
694 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
695 }
696 }
697 /* XXX all other service requests are denied */
698
699 if (accept) {
700 packet_start(SSH2_MSG_SERVICE_ACCEPT);
701 packet_put_cstring(service);
702 packet_send();
703 packet_write_wait();
704 } else {
705 debug("bad service request %s", service);
706 packet_disconnect("bad service request %s", service);
707 }
708 xfree(service);
709}
710void
711input_userauth_request(int type, int plen)
712{
713 static int try = 0;
714 unsigned int len;
715 int c, authenticated = 0;
716 char *user, *service, *method;
717 struct passwd *pw;
718
719 if (++try == AUTH_FAIL_MAX)
720 packet_disconnect("too many failed userauth_requests");
721
722 user = packet_get_string(&len);
723 service = packet_get_string(&len);
724 method = packet_get_string(&len);
725 debug("userauth-request for user %s service %s method %s", user, service, method);
726
727 /* XXX we only allow the ssh-connection service */
728 pw = auth_set_user(user, service);
729 if (pw && strcmp(service, "ssh-connection")==0) {
730 if (strcmp(method, "none") == 0 && try == 1) {
6ae2364d 731 packet_done();
e78a59f5 732#ifdef USE_PAM
733 /* Do PAM auth with password */
734 authenticated = auth_pam_password(pw, "");
735#else /* USE_PAM */
736 /* Try authentication with the password. */
737 authenticated = auth_password(pw, "");
738#endif /* USE_PAM */
739 } else if (strcmp(method, "password") == 0) {
740 char *password;
741 c = packet_get_char();
742 if (c)
743 debug("password change not supported");
744 password = packet_get_string(&len);
6ae2364d 745 packet_done();
e78a59f5 746#ifdef USE_PAM
747 /* Do PAM auth with password */
748 authenticated = auth_pam_password(pw, password);
749#else /* USE_PAM */
750 /* Try authentication with the password. */
751 authenticated = auth_password(pw, password);
752#endif /* USE_PAM */
753 memset(password, 0, len);
754 xfree(password);
755 } else if (strcmp(method, "publickey") == 0) {
756 /* XXX TODO */
6ae2364d 757 char *pkalg, *pkblob, *sig;
758 int have_sig = packet_get_char();
e78a59f5 759 pkalg = packet_get_string(&len);
760 pkblob = packet_get_string(&len);
6ae2364d 761 if (have_sig) {
762 sig = packet_get_string(&len);
763 /* test for correct signature */
764 packet_done();
765 xfree(sig);
766 } else {
767 packet_done();
768 /* test whether pkalg/pkblob are acceptable */
769 }
e78a59f5 770 xfree(pkalg);
771 xfree(pkblob);
772 }
773 }
774 /* XXX check if other auth methods are needed */
775 if (authenticated) {
776 /* turn off userauth */
777 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
e78a59f5 778 packet_start(SSH2_MSG_USERAUTH_SUCCESS);
779 packet_send();
780 packet_write_wait();
781 log("userauth success for %s", user);
782 /* now we can break out */
783 userauth_success = 1;
784 } else {
785 packet_start(SSH2_MSG_USERAUTH_FAILURE);
786 packet_put_cstring("password");
787 packet_put_char(0); /* partial success */
788 packet_send();
789 packet_write_wait();
790 }
791 xfree(service);
792 xfree(user);
793 xfree(method);
794}
6ae2364d 795void
e78a59f5 796do_authentication2()
797{
798 dispatch_init(&protocol_error);
799 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
800 dispatch_run(DISPATCH_BLOCK, &userauth_success);
801 do_authenticated2();
802}
This page took 0.152052 seconds and 5 git commands to generate.