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