]> andersk Git - gssapi-openssh.git/blob - openssh/sshconnect2.c
merge with OpenSSH 3.6.1p1
[gssapi-openssh.git] / openssh / sshconnect2.c
1 /*
2  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "includes.h"
26 RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $");
27
28 #include "ssh.h"
29 #include "ssh2.h"
30 #include "xmalloc.h"
31 #include "buffer.h"
32 #include "packet.h"
33 #include "compat.h"
34 #include "bufaux.h"
35 #include "cipher.h"
36 #include "kex.h"
37 #include "myproposal.h"
38 #include "sshconnect.h"
39 #include "authfile.h"
40 #include "dh.h"
41 #include "authfd.h"
42 #include "log.h"
43 #include "readconf.h"
44 #include "readpass.h"
45 #include "match.h"
46 #include "dispatch.h"
47 #include "canohost.h"
48 #include "msg.h"
49 #include "pathnames.h"
50
51 #ifdef GSSAPI
52 #include "ssh-gss.h"
53 #endif
54
55 /* import */
56 extern char *client_version_string;
57 extern char *server_version_string;
58 extern Options options;
59
60 /*
61  * SSH2 key exchange
62  */
63
64 u_char *session_id2 = NULL;
65 int session_id2_len = 0;
66
67 char *xxx_host;
68 struct sockaddr *xxx_hostaddr;
69
70 Kex *xxx_kex = NULL;
71
72 static int
73 verify_host_key_callback(Key *hostkey)
74 {
75         if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
76                 fatal("Host key verification failed.");
77         return 0;
78 }
79
80 void
81 ssh_kex2(char *host, struct sockaddr *hostaddr)
82 {
83         Kex *kex;
84 #ifdef GSSAPI
85         char *orig, *gss;
86         int len;
87 #endif
88
89         xxx_host = host;
90         xxx_hostaddr = hostaddr;
91
92 #ifdef GSSAPI
93         if (options.gss_keyex) {
94         char *canonhost;
95         /* Add the GSSAPI mechanisms currently supported on this client to
96          * the key exchange algorithm proposal */
97         orig = myproposal[PROPOSAL_KEX_ALGS];
98         canonhost = xstrdup(get_canonical_hostname(1));
99         resolve_localhost(&canonhost);
100         gss = ssh_gssapi_mechanisms(canonhost);
101         xfree(canonhost);
102         canonhost=NULL;
103         if (gss) {
104            len = strlen(orig)+strlen(gss)+2;
105            myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
106            snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig);
107         }
108         }
109 #endif
110
111         if (options.ciphers == (char *)-1) {
112                 log("No valid ciphers for protocol version 2 given, using defaults.");
113                 options.ciphers = NULL;
114         }
115         if (options.ciphers != NULL) {
116                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
117                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
118         }
119         myproposal[PROPOSAL_ENC_ALGS_CTOS] =
120             compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
121         myproposal[PROPOSAL_ENC_ALGS_STOC] =
122             compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
123         if (options.compression) {
124                 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
125                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
126         } else {
127                 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
128                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
129         }
130         if (options.macs != NULL) {
131                 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
132                 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
133         }
134         if (options.hostkeyalgorithms != NULL)
135                 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
136                     options.hostkeyalgorithms;
137
138 #ifdef GSSAPI
139         /* If we've got GSSAPI algorithms, then we also support the
140          * 'null' hostkey, as a last resort */
141         if (options.gss_keyex && gss) {
142                 orig=myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
143                 len = strlen(orig)+sizeof(",null");
144                 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]=xmalloc(len);
145                 snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],len,"%s,null",orig);  
146         }
147 #endif
148
149         /* start key exchange */
150         kex = kex_setup(myproposal);
151         kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
152         kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
153 #ifdef GSSAPI
154         kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
155 #endif
156         kex->client_version_string=client_version_string;
157         kex->server_version_string=server_version_string;
158         kex->verify_host_key=&verify_host_key_callback;
159         kex->host=host;
160
161 #ifdef GSSAPI
162         kex->options.gss_deleg_creds=options.gss_deleg_creds;
163 #endif
164
165         xxx_kex = kex;
166
167         dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
168
169         session_id2 = kex->session_id;
170         session_id2_len = kex->session_id_len;
171
172 #ifdef DEBUG_KEXDH
173         /* send 1st encrypted/maced/compressed message */
174         packet_start(SSH2_MSG_IGNORE);
175         packet_put_cstring("markus");
176         packet_send();
177         packet_write_wait();
178 #endif
179 }
180
181 /*
182  * Authenticate user
183  */
184
185 typedef struct Authctxt Authctxt;
186 typedef struct Authmethod Authmethod;
187
188 typedef int sign_cb_fn(
189     Authctxt *authctxt, Key *key,
190     u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
191
192 struct Authctxt {
193         const char *server_user;
194         const char *local_user;
195         const char *host;
196         const char *service;
197         Authmethod *method;
198         int success;
199         char *authlist;
200         /* pubkey */
201         Key *last_key;
202         sign_cb_fn *last_key_sign;
203         int last_key_hint;
204         AuthenticationConnection *agent;
205         /* hostbased */
206         Sensitive *sensitive;
207         /* kbd-interactive */
208         int info_req_seen;
209         /* generic */
210         void *methoddata;
211 };
212 struct Authmethod {
213         char    *name;          /* string to compare against server's list */
214         int     (*userauth)(Authctxt *authctxt);
215         int     *enabled;       /* flag in option struct that enables method */
216         int     *batch_flag;    /* flag in option struct that disables method */
217 };
218
219 void    input_userauth_success(int, u_int32_t, void *);
220 void    input_userauth_failure(int, u_int32_t, void *);
221 void    input_userauth_banner(int, u_int32_t, void *);
222 void    input_userauth_error(int, u_int32_t, void *);
223 void    input_userauth_info_req(int, u_int32_t, void *);
224 void    input_userauth_pk_ok(int, u_int32_t, void *);
225 void    input_userauth_passwd_changereq(int, u_int32_t, void *);
226
227 int     userauth_none(Authctxt *);
228 int     userauth_pubkey(Authctxt *);
229 int     userauth_passwd(Authctxt *);
230 int     userauth_kbdint(Authctxt *);
231 int     userauth_hostbased(Authctxt *);
232
233 #ifdef GSSAPI
234 int     userauth_external(Authctxt *authctxt);
235 int     userauth_gssapi(Authctxt *authctxt);
236 void    input_gssapi_response(int type, u_int32_t plen, void *ctxt);
237 void    input_gssapi_token(int type, u_int32_t plen, void *ctxt);
238 void    input_gssapi_hash(int type, u_int32_t plen, void *ctxt);
239 #endif
240
241 void    userauth(Authctxt *, char *);
242
243 static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
244 static void clear_auth_state(Authctxt *);
245
246 static Authmethod *authmethod_get(char *authlist);
247 static Authmethod *authmethod_lookup(const char *name);
248 static char *authmethods_get(void);
249
250 Authmethod authmethods[] = {
251 #ifdef GSSAPI
252         {"external-keyx",
253                 userauth_external,
254                 &options.gss_authentication,
255                 NULL},
256         {"gssapi",
257                 userauth_gssapi,
258                 &options.gss_authentication,
259                 NULL},
260 #endif
261         {"hostbased",
262                 userauth_hostbased,
263                 &options.hostbased_authentication,
264                 NULL},
265         {"publickey",
266                 userauth_pubkey,
267                 &options.pubkey_authentication,
268                 NULL},
269         {"keyboard-interactive",
270                 userauth_kbdint,
271                 &options.kbd_interactive_authentication,
272                 &options.batch_mode},
273         {"password",
274                 userauth_passwd,
275                 &options.password_authentication,
276                 &options.batch_mode},
277         {"none",
278                 userauth_none,
279                 NULL,
280                 NULL},
281         {NULL, NULL, NULL, NULL}
282 };
283
284 void
285 ssh_userauth2(const char *local_user, const char *server_user, char *host,
286     Sensitive *sensitive)
287 {
288         Authctxt authctxt;
289         int type;
290
291         if (options.challenge_response_authentication)
292                 options.kbd_interactive_authentication = 1;
293
294         packet_start(SSH2_MSG_SERVICE_REQUEST);
295         packet_put_cstring("ssh-userauth");
296         packet_send();
297         debug("SSH2_MSG_SERVICE_REQUEST sent");
298         packet_write_wait();
299         type = packet_read();
300         if (type != SSH2_MSG_SERVICE_ACCEPT)
301                 fatal("Server denied authentication request: %d", type);
302         if (packet_remaining() > 0) {
303                 char *reply = packet_get_string(NULL);
304                 debug2("service_accept: %s", reply);
305                 xfree(reply);
306         } else {
307                 debug2("buggy server: service_accept w/o service");
308         }
309         packet_check_eom();
310         debug("SSH2_MSG_SERVICE_ACCEPT received");
311
312         if (options.preferred_authentications == NULL)
313                 options.preferred_authentications = authmethods_get();
314
315         /* setup authentication context */
316         memset(&authctxt, 0, sizeof(authctxt));
317         authctxt.agent = ssh_get_authentication_connection();
318         authctxt.server_user = server_user;
319         authctxt.local_user = local_user;
320         authctxt.host = host;
321         authctxt.service = "ssh-connection";            /* service name */
322         authctxt.success = 0;
323         authctxt.method = authmethod_lookup("none");
324         authctxt.authlist = NULL;
325         authctxt.methoddata = NULL;
326         authctxt.sensitive = sensitive;
327         authctxt.info_req_seen = 0;
328         if (authctxt.method == NULL)
329                 fatal("ssh_userauth2: internal error: cannot send userauth none request");
330
331         /* initial userauth request */
332         userauth_none(&authctxt);
333
334         dispatch_init(&input_userauth_error);
335         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
336         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
337         dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
338         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
339
340         if (authctxt.agent != NULL)
341                 ssh_close_authentication_connection(authctxt.agent);
342
343         debug("Authentication succeeded (%s).", authctxt.method->name);
344 }
345 void
346 userauth(Authctxt *authctxt, char *authlist)
347 {
348         if (authctxt->methoddata!=NULL) {
349                 xfree(authctxt->methoddata);
350                 authctxt->methoddata=NULL;
351         }
352            
353         if (authlist == NULL) {
354                 authlist = authctxt->authlist;
355         } else {
356                 if (authctxt->authlist)
357                         xfree(authctxt->authlist);
358                 authctxt->authlist = authlist;
359         }
360         for (;;) {
361                 Authmethod *method = authmethod_get(authlist);
362                 if (method == NULL)
363                         fatal("Permission denied (%s).", authlist);
364                 authctxt->method = method;
365                 if (method->userauth(authctxt) != 0) {
366                         debug2("we sent a %s packet, wait for reply", method->name);
367                         break;
368                 } else {
369                         debug2("we did not send a packet, disable method");
370                         method->enabled = NULL;
371                 }
372         }
373 }
374
375 void
376 input_userauth_error(int type, u_int32_t seq, void *ctxt)
377 {
378         fatal("input_userauth_error: bad message during authentication: "
379            "type %d", type);
380 }
381
382 void
383 input_userauth_banner(int type, u_int32_t seq, void *ctxt)
384 {
385         char *msg, *lang;
386         debug3("input_userauth_banner");
387         msg = packet_get_string(NULL);
388         lang = packet_get_string(NULL);
389         fprintf(stderr, "%s", msg);
390         xfree(msg);
391         xfree(lang);
392 }
393
394 void
395 input_userauth_success(int type, u_int32_t seq, void *ctxt)
396 {
397         Authctxt *authctxt = ctxt;
398         if (authctxt == NULL)
399                 fatal("input_userauth_success: no authentication context");
400         if (authctxt->authlist)
401                 xfree(authctxt->authlist);
402         if (authctxt->methoddata)
403                 xfree(authctxt->methoddata);
404         clear_auth_state(authctxt);
405         authctxt->success = 1;                  /* break out */
406 }
407
408 void
409 input_userauth_failure(int type, u_int32_t seq, void *ctxt)
410 {
411         Authctxt *authctxt = ctxt;
412         char *authlist = NULL;
413         int partial;
414
415         if (authctxt == NULL)
416                 fatal("input_userauth_failure: no authentication context");
417
418         authlist = packet_get_string(NULL);
419         partial = packet_get_char();
420         packet_check_eom();
421
422         if (partial != 0)
423                 log("Authenticated with partial success.");
424         debug("Authentications that can continue: %s", authlist);
425
426         clear_auth_state(authctxt);
427         userauth(authctxt, authlist);
428 }
429 void
430 input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
431 {
432         Authctxt *authctxt = ctxt;
433         Key *key = NULL;
434         Buffer b;
435         int pktype, sent = 0;
436         u_int alen, blen;
437         char *pkalg, *fp;
438         u_char *pkblob;
439
440         if (authctxt == NULL)
441                 fatal("input_userauth_pk_ok: no authentication context");
442         if (datafellows & SSH_BUG_PKOK) {
443                 /* this is similar to SSH_BUG_PKAUTH */
444                 debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
445                 pkblob = packet_get_string(&blen);
446                 buffer_init(&b);
447                 buffer_append(&b, pkblob, blen);
448                 pkalg = buffer_get_string(&b, &alen);
449                 buffer_free(&b);
450         } else {
451                 pkalg = packet_get_string(&alen);
452                 pkblob = packet_get_string(&blen);
453         }
454         packet_check_eom();
455
456         debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
457             pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
458
459         do {
460                 if (authctxt->last_key == NULL ||
461                     authctxt->last_key_sign == NULL) {
462                         debug("no last key or no sign cb");
463                         break;
464                 }
465                 if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
466                         debug("unknown pkalg %s", pkalg);
467                         break;
468                 }
469                 if ((key = key_from_blob(pkblob, blen)) == NULL) {
470                         debug("no key from blob. pkalg %s", pkalg);
471                         break;
472                 }
473                 if (key->type != pktype) {
474                         error("input_userauth_pk_ok: type mismatch "
475                             "for decoded key (received %d, expected %d)",
476                             key->type, pktype);
477                         break;
478                 }
479                 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
480                 debug2("input_userauth_pk_ok: fp %s", fp);
481                 xfree(fp);
482                 if (!key_equal(key, authctxt->last_key)) {
483                         debug("key != last_key");
484                         break;
485                 }
486                 sent = sign_and_send_pubkey(authctxt, key,
487                    authctxt->last_key_sign);
488         } while (0);
489
490         if (key != NULL)
491                 key_free(key);
492         xfree(pkalg);
493         xfree(pkblob);
494
495         /* unregister */
496         clear_auth_state(authctxt);
497         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
498
499         /* try another method if we did not send a packet */
500         if (sent == 0)
501                 userauth(authctxt, NULL);
502
503 }
504
505 #ifdef GSSAPI
506 int 
507 userauth_gssapi(Authctxt *authctxt)
508 {
509         Gssctxt *gssctxt;
510         static int mech=0;
511
512         if (datafellows & SSH_OLD_GSSAPI) return 0;
513         
514         /* Try each mechanism in turn.  Give up if we've tried all
515            supported mechanisms.
516          */
517         if (mech==GSS_LAST_ENTRY) return 0;
518         
519         /* Initialise as much of our context as we can, so failures can be
520          * trapped before sending any packets.
521          */
522         ssh_gssapi_build_ctx(&gssctxt);
523
524         if (ssh_gssapi_import_name(gssctxt,get_canonical_hostname(1))) {
525                 return(0);
526         }
527         
528         authctxt->methoddata=(void *)gssctxt;
529                 
530         packet_start(SSH2_MSG_USERAUTH_REQUEST);
531 #ifdef GSI
532         if(options.implicit && !(datafellows & SSH_BUG_GSS_EMPTYUSER)) {
533             packet_put_cstring("");
534         } else {
535 #endif
536             packet_put_cstring(authctxt->server_user);
537 #ifdef GSI
538         }
539 #endif
540         packet_put_cstring(authctxt->service);
541         packet_put_cstring(authctxt->method->name);
542
543         /* FIXME: This assumes that our current GSSAPI implementation
544          * supports all of the mechanisms listed in supported_mechs.
545          * This may not be the case - we should use something along
546          * the lines of the code in gss_genr to remove the ones that
547          * aren't supported */
548
549         /* Try one GSSAPI mechanism at a time. */
550         packet_put_int(1);
551         packet_put_string(supported_mechs[mech].oid.elements,
552                           supported_mechs[mech].oid.length);
553         packet_send();
554         packet_write_wait();
555
556         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
557         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
558         
559         mech++;                 /* Move to next mechanism for next time. */
560
561         return 1;
562 }
563
564 void
565 input_gssapi_response(int type, u_int32_t plen, void *ctxt) 
566 {
567         Authctxt *authctxt = ctxt;
568         Gssctxt *gssctxt;
569         OM_uint32 status,ms;
570         int oidlen;
571         char *oidv;
572         gss_buffer_desc send_tok;
573         
574         if (authctxt == NULL)
575                 fatal("input_gssapi_response: no authentication context");
576         gssctxt = authctxt->methoddata;
577         
578         /* Setup our OID */
579         oidv=packet_get_string(&oidlen);
580         ssh_gssapi_set_oid_data(gssctxt,oidv,oidlen);
581         
582         packet_check_eom();
583         
584         status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
585                                      GSS_C_NO_BUFFER, &send_tok, 
586                                      NULL);
587         if (GSS_ERROR(status)) {
588                 /* Start again with next method on list */
589                 debug("Trying to start again");
590                 userauth(authctxt,NULL);
591                 return;
592         }
593
594         /* We must have data to send */                                 
595         packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
596         packet_put_string(send_tok.value,send_tok.length);
597         packet_send();
598         packet_write_wait();
599         gss_release_buffer(&ms, &send_tok);
600 }
601
602 void
603 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
604 {
605         Authctxt *authctxt = ctxt;
606         Gssctxt *gssctxt;
607         gss_buffer_desc send_tok,recv_tok;
608         OM_uint32 status;
609         u_int slen;
610         
611         if (authctxt == NULL)
612                 fatal("input_gssapi_token: no authentication context");
613         gssctxt = authctxt->methoddata;
614         
615         recv_tok.value=packet_get_string(&slen);
616         recv_tok.length=slen;   /* safe typecast */
617
618         status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
619                                    &recv_tok, &send_tok, NULL);
620
621         packet_check_eom();
622         
623         if (GSS_ERROR(status)) {
624                 /* Start again with the next method in the list */
625                 userauth(authctxt,NULL);
626                 return;
627         }
628         
629         if (send_tok.length>0) {
630                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
631                 packet_put_string(send_tok.value,send_tok.length);
632                 packet_send();
633                 packet_write_wait();
634         }
635         
636         if (status == GSS_S_COMPLETE) {
637                 /* If that succeeded, send a exchange complete message */
638                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
639                 packet_send();
640                 packet_write_wait();
641         }
642 }
643
644 int
645 userauth_external(Authctxt *authctxt)
646 {
647         static int attempt =0;
648         
649         if (attempt++ >= 1)
650                 return 0;
651                                 
652         debug2("userauth_external");
653         packet_start(SSH2_MSG_USERAUTH_REQUEST);
654 #ifdef GSI
655         if(options.implicit && !(datafellows & SSH_BUG_GSS_EMPTYUSER)) {
656             packet_put_cstring("");
657         } else {
658 #endif
659             packet_put_cstring(authctxt->server_user);
660 #ifdef GSI
661         }
662 #endif
663         packet_put_cstring(authctxt->service);
664         packet_put_cstring(authctxt->method->name);
665         packet_send();
666         packet_write_wait();
667         return 1;
668 }                                                                                                
669 #endif /* GSSAPI */
670
671 int
672 userauth_none(Authctxt *authctxt)
673 {
674         /* initial userauth request */
675         packet_start(SSH2_MSG_USERAUTH_REQUEST);
676         packet_put_cstring(authctxt->server_user);
677         packet_put_cstring(authctxt->service);
678         packet_put_cstring(authctxt->method->name);
679         packet_send();
680         return 1;
681
682 }
683
684 int
685 userauth_passwd(Authctxt *authctxt)
686 {
687         static int attempt = 0;
688         char prompt[150];
689         char *password;
690
691         if (attempt++ >= options.number_of_password_prompts)
692                 return 0;
693
694         if (attempt != 1)
695                 error("Permission denied, please try again.");
696
697         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
698             authctxt->server_user, authctxt->host);
699         password = read_passphrase(prompt, 0);
700         packet_start(SSH2_MSG_USERAUTH_REQUEST);
701         packet_put_cstring(authctxt->server_user);
702         packet_put_cstring(authctxt->service);
703         packet_put_cstring(authctxt->method->name);
704         packet_put_char(0);
705         packet_put_cstring(password);
706         memset(password, 0, strlen(password));
707         xfree(password);
708         packet_add_padding(64);
709         packet_send();
710
711         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
712             &input_userauth_passwd_changereq);
713
714         return 1;
715 }
716 /*
717  * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
718  */
719 void
720 input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
721 {
722         Authctxt *authctxt = ctxt;
723         char *info, *lang, *password = NULL, *retype = NULL;
724         char prompt[150];
725
726         debug2("input_userauth_passwd_changereq");
727
728         if (authctxt == NULL)
729                 fatal("input_userauth_passwd_changereq: "
730                     "no authentication context");
731
732         info = packet_get_string(NULL);
733         lang = packet_get_string(NULL);
734         if (strlen(info) > 0)
735                 log("%s", info);
736         xfree(info);
737         xfree(lang);
738         packet_start(SSH2_MSG_USERAUTH_REQUEST);
739         packet_put_cstring(authctxt->server_user);
740         packet_put_cstring(authctxt->service);
741         packet_put_cstring(authctxt->method->name);
742         packet_put_char(1);                     /* additional info */
743         snprintf(prompt, sizeof(prompt),
744             "Enter %.30s@%.128s's old password: ",
745             authctxt->server_user, authctxt->host);
746         password = read_passphrase(prompt, 0);
747         packet_put_cstring(password);
748         memset(password, 0, strlen(password));
749         xfree(password);
750         password = NULL;
751         while (password == NULL) {
752                 snprintf(prompt, sizeof(prompt),
753                     "Enter %.30s@%.128s's new password: ",
754                     authctxt->server_user, authctxt->host);
755                 password = read_passphrase(prompt, RP_ALLOW_EOF);
756                 if (password == NULL) {
757                         /* bail out */
758                         return;
759                 }
760                 snprintf(prompt, sizeof(prompt),
761                     "Retype %.30s@%.128s's new password: ",
762                     authctxt->server_user, authctxt->host);
763                 retype = read_passphrase(prompt, 0);
764                 if (strcmp(password, retype) != 0) {
765                         memset(password, 0, strlen(password));
766                         xfree(password);
767                         log("Mismatch; try again, EOF to quit.");
768                         password = NULL;
769                 }
770                 memset(retype, 0, strlen(retype));
771                 xfree(retype);
772         }
773         packet_put_cstring(password);
774         memset(password, 0, strlen(password));
775         xfree(password);
776         packet_add_padding(64);
777         packet_send();
778
779         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
780             &input_userauth_passwd_changereq);
781 }
782
783 static void
784 clear_auth_state(Authctxt *authctxt)
785 {
786         /* XXX clear authentication state */
787         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
788
789         if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
790                 debug3("clear_auth_state: key_free %p", authctxt->last_key);
791                 key_free(authctxt->last_key);
792         }
793         authctxt->last_key = NULL;
794         authctxt->last_key_hint = -2;
795         authctxt->last_key_sign = NULL;
796 }
797
798 static int
799 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
800 {
801         Buffer b;
802         u_char *blob, *signature;
803         u_int bloblen, slen;
804         int skip = 0;
805         int ret = -1;
806         int have_sig = 1;
807
808         debug3("sign_and_send_pubkey");
809
810         if (key_to_blob(k, &blob, &bloblen) == 0) {
811                 /* we cannot handle this key */
812                 debug3("sign_and_send_pubkey: cannot handle key");
813                 return 0;
814         }
815         /* data to be signed */
816         buffer_init(&b);
817         if (datafellows & SSH_OLD_SESSIONID) {
818                 buffer_append(&b, session_id2, session_id2_len);
819                 skip = session_id2_len;
820         } else {
821                 buffer_put_string(&b, session_id2, session_id2_len);
822                 skip = buffer_len(&b);
823         }
824         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
825         buffer_put_cstring(&b, authctxt->server_user);
826         buffer_put_cstring(&b,
827             datafellows & SSH_BUG_PKSERVICE ?
828             "ssh-userauth" :
829             authctxt->service);
830         if (datafellows & SSH_BUG_PKAUTH) {
831                 buffer_put_char(&b, have_sig);
832         } else {
833                 buffer_put_cstring(&b, authctxt->method->name);
834                 buffer_put_char(&b, have_sig);
835                 buffer_put_cstring(&b, key_ssh_name(k));
836         }
837         buffer_put_string(&b, blob, bloblen);
838
839         /* generate signature */
840         ret = (*sign_callback)(authctxt, k, &signature, &slen,
841             buffer_ptr(&b), buffer_len(&b));
842         if (ret == -1) {
843                 xfree(blob);
844                 buffer_free(&b);
845                 return 0;
846         }
847 #ifdef DEBUG_PK
848         buffer_dump(&b);
849 #endif
850         if (datafellows & SSH_BUG_PKSERVICE) {
851                 buffer_clear(&b);
852                 buffer_append(&b, session_id2, session_id2_len);
853                 skip = session_id2_len;
854                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
855                 buffer_put_cstring(&b, authctxt->server_user);
856                 buffer_put_cstring(&b, authctxt->service);
857                 buffer_put_cstring(&b, authctxt->method->name);
858                 buffer_put_char(&b, have_sig);
859                 if (!(datafellows & SSH_BUG_PKAUTH))
860                         buffer_put_cstring(&b, key_ssh_name(k));
861                 buffer_put_string(&b, blob, bloblen);
862         }
863         xfree(blob);
864
865         /* append signature */
866         buffer_put_string(&b, signature, slen);
867         xfree(signature);
868
869         /* skip session id and packet type */
870         if (buffer_len(&b) < skip + 1)
871                 fatal("userauth_pubkey: internal error");
872         buffer_consume(&b, skip + 1);
873
874         /* put remaining data from buffer into packet */
875         packet_start(SSH2_MSG_USERAUTH_REQUEST);
876         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
877         buffer_free(&b);
878         packet_send();
879
880         return 1;
881 }
882
883 static int
884 send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
885     int hint)
886 {
887         u_char *blob;
888         u_int bloblen, have_sig = 0;
889
890         debug3("send_pubkey_test");
891
892         if (key_to_blob(k, &blob, &bloblen) == 0) {
893                 /* we cannot handle this key */
894                 debug3("send_pubkey_test: cannot handle key");
895                 return 0;
896         }
897         /* register callback for USERAUTH_PK_OK message */
898         authctxt->last_key_sign = sign_callback;
899         authctxt->last_key_hint = hint;
900         authctxt->last_key = k;
901         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
902
903         packet_start(SSH2_MSG_USERAUTH_REQUEST);
904         packet_put_cstring(authctxt->server_user);
905         packet_put_cstring(authctxt->service);
906         packet_put_cstring(authctxt->method->name);
907         packet_put_char(have_sig);
908         if (!(datafellows & SSH_BUG_PKAUTH))
909                 packet_put_cstring(key_ssh_name(k));
910         packet_put_string(blob, bloblen);
911         xfree(blob);
912         packet_send();
913         return 1;
914 }
915
916 static Key *
917 load_identity_file(char *filename)
918 {
919         Key *private;
920         char prompt[300], *passphrase;
921         int quit, i;
922         struct stat st;
923
924         if (stat(filename, &st) < 0) {
925                 debug3("no such identity: %s", filename);
926                 return NULL;
927         }
928         private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
929         if (private == NULL) {
930                 if (options.batch_mode)
931                         return NULL;
932                 snprintf(prompt, sizeof prompt,
933                     "Enter passphrase for key '%.100s': ", filename);
934                 for (i = 0; i < options.number_of_password_prompts; i++) {
935                         passphrase = read_passphrase(prompt, 0);
936                         if (strcmp(passphrase, "") != 0) {
937                                 private = key_load_private_type(KEY_UNSPEC, filename,
938                                     passphrase, NULL);
939                                 quit = 0;
940                         } else {
941                                 debug2("no passphrase given, try next key");
942                                 quit = 1;
943                         }
944                         memset(passphrase, 0, strlen(passphrase));
945                         xfree(passphrase);
946                         if (private != NULL || quit)
947                                 break;
948                         debug2("bad passphrase given, try again...");
949                 }
950         }
951         return private;
952 }
953
954 static int
955 identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
956     u_char *data, u_int datalen)
957 {
958         Key *private;
959         int idx, ret;
960
961         idx = authctxt->last_key_hint;
962         if (idx < 0)
963                 return -1;
964
965         /* private key is stored in external hardware */
966         if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
967                 return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
968
969         private = load_identity_file(options.identity_files[idx]);
970         if (private == NULL)
971                 return -1;
972         ret = key_sign(private, sigp, lenp, data, datalen);
973         key_free(private);
974         return ret;
975 }
976
977 static int
978 agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
979     u_char *data, u_int datalen)
980 {
981         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
982 }
983
984 static int
985 key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
986     u_char *data, u_int datalen)
987 {
988         return key_sign(key, sigp, lenp, data, datalen);
989 }
990
991 static int
992 userauth_pubkey_agent(Authctxt *authctxt)
993 {
994         static int called = 0;
995         int ret = 0;
996         char *comment;
997         Key *k;
998
999         if (called == 0) {
1000                 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
1001                         debug2("userauth_pubkey_agent: no keys at all");
1002                 called = 1;
1003         }
1004         k = ssh_get_next_identity(authctxt->agent, &comment, 2);
1005         if (k == NULL) {
1006                 debug2("userauth_pubkey_agent: no more keys");
1007         } else {
1008                 debug("Offering agent key: %s", comment);
1009                 xfree(comment);
1010                 ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
1011                 if (ret == 0)
1012                         key_free(k);
1013         }
1014         if (ret == 0)
1015                 debug2("userauth_pubkey_agent: no message sent");
1016         return ret;
1017 }
1018
1019 int
1020 userauth_pubkey(Authctxt *authctxt)
1021 {
1022         static int idx = 0;
1023         int sent = 0;
1024         Key *key;
1025         char *filename;
1026
1027         if (authctxt->agent != NULL) {
1028                 do {
1029                         sent = userauth_pubkey_agent(authctxt);
1030                 } while (!sent && authctxt->agent->howmany > 0);
1031         }
1032         while (!sent && idx < options.num_identity_files) {
1033                 key = options.identity_keys[idx];
1034                 filename = options.identity_files[idx];
1035                 if (key == NULL) {
1036                         debug("Trying private key: %s", filename);
1037                         key = load_identity_file(filename);
1038                         if (key != NULL) {
1039                                 sent = sign_and_send_pubkey(authctxt, key,
1040                                     key_sign_cb);
1041                                 key_free(key);
1042                         }
1043                 } else if (key->type != KEY_RSA1) {
1044                         debug("Offering public key: %s", filename);
1045                         sent = send_pubkey_test(authctxt, key,
1046                             identity_sign_cb, idx);
1047                 }
1048                 idx++;
1049         }
1050         return sent;
1051 }
1052
1053 /*
1054  * Send userauth request message specifying keyboard-interactive method.
1055  */
1056 int
1057 userauth_kbdint(Authctxt *authctxt)
1058 {
1059         static int attempt = 0;
1060
1061         if (attempt++ >= options.number_of_password_prompts)
1062                 return 0;
1063         /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
1064         if (attempt > 1 && !authctxt->info_req_seen) {
1065                 debug3("userauth_kbdint: disable: no info_req_seen");
1066                 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
1067                 return 0;
1068         }
1069
1070         debug2("userauth_kbdint");
1071         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1072         packet_put_cstring(authctxt->server_user);
1073         packet_put_cstring(authctxt->service);
1074         packet_put_cstring(authctxt->method->name);
1075         packet_put_cstring("");                                 /* lang */
1076         packet_put_cstring(options.kbd_interactive_devices ?
1077             options.kbd_interactive_devices : "");
1078         packet_send();
1079
1080         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
1081         return 1;
1082 }
1083
1084 /*
1085  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1086  */
1087 void
1088 input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
1089 {
1090         Authctxt *authctxt = ctxt;
1091         char *name, *inst, *lang, *prompt, *response;
1092         u_int num_prompts, i;
1093         int echo = 0;
1094
1095         debug2("input_userauth_info_req");
1096
1097         if (authctxt == NULL)
1098                 fatal("input_userauth_info_req: no authentication context");
1099
1100         authctxt->info_req_seen = 1;
1101
1102         name = packet_get_string(NULL);
1103         inst = packet_get_string(NULL);
1104         lang = packet_get_string(NULL);
1105         if (strlen(name) > 0)
1106                 log("%s", name);
1107         if (strlen(inst) > 0)
1108                 log("%s", inst);
1109         xfree(name);
1110         xfree(inst);
1111         xfree(lang);
1112
1113         num_prompts = packet_get_int();
1114         /*
1115          * Begin to build info response packet based on prompts requested.
1116          * We commit to providing the correct number of responses, so if
1117          * further on we run into a problem that prevents this, we have to
1118          * be sure and clean this up and send a correct error response.
1119          */
1120         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
1121         packet_put_int(num_prompts);
1122
1123         debug2("input_userauth_info_req: num_prompts %d", num_prompts);
1124         for (i = 0; i < num_prompts; i++) {
1125                 prompt = packet_get_string(NULL);
1126                 echo = packet_get_char();
1127
1128                 response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1129
1130                 packet_put_cstring(response);
1131                 memset(response, 0, strlen(response));
1132                 xfree(response);
1133                 xfree(prompt);
1134         }
1135         packet_check_eom(); /* done with parsing incoming message. */
1136
1137         packet_add_padding(64);
1138         packet_send();
1139 }
1140
1141 static int
1142 ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
1143     u_char *data, u_int datalen)
1144 {
1145         Buffer b;
1146         struct stat st;
1147         pid_t pid;
1148         int to[2], from[2], status, version = 2;
1149
1150         debug2("ssh_keysign called");
1151
1152         if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
1153                 error("ssh_keysign: no installed: %s", strerror(errno));
1154                 return -1;
1155         }
1156         if (fflush(stdout) != 0)
1157                 error("ssh_keysign: fflush: %s", strerror(errno));
1158         if (pipe(to) < 0) {
1159                 error("ssh_keysign: pipe: %s", strerror(errno));
1160                 return -1;
1161         }
1162         if (pipe(from) < 0) {
1163                 error("ssh_keysign: pipe: %s", strerror(errno));
1164                 return -1;
1165         }
1166         if ((pid = fork()) < 0) {
1167                 error("ssh_keysign: fork: %s", strerror(errno));
1168                 return -1;
1169         }
1170         if (pid == 0) {
1171                 seteuid(getuid());
1172                 setuid(getuid());
1173                 close(from[0]);
1174                 if (dup2(from[1], STDOUT_FILENO) < 0)
1175                         fatal("ssh_keysign: dup2: %s", strerror(errno));
1176                 close(to[1]);
1177                 if (dup2(to[0], STDIN_FILENO) < 0)
1178                         fatal("ssh_keysign: dup2: %s", strerror(errno));
1179                 close(from[1]);
1180                 close(to[0]);
1181                 execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
1182                 fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
1183                     strerror(errno));
1184         }
1185         close(from[1]);
1186         close(to[0]);
1187
1188         buffer_init(&b);
1189         buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
1190         buffer_put_string(&b, data, datalen);
1191         ssh_msg_send(to[1], version, &b);
1192
1193         if (ssh_msg_recv(from[0], &b) < 0) {
1194                 error("ssh_keysign: no reply");
1195                 buffer_clear(&b);
1196                 return -1;
1197         }
1198         close(from[0]);
1199         close(to[1]);
1200
1201         while (waitpid(pid, &status, 0) < 0)
1202                 if (errno != EINTR)
1203                         break;
1204
1205         if (buffer_get_char(&b) != version) {
1206                 error("ssh_keysign: bad version");
1207                 buffer_clear(&b);
1208                 return -1;
1209         }
1210         *sigp = buffer_get_string(&b, lenp);
1211         buffer_clear(&b);
1212
1213         return 0;
1214 }
1215
1216 int
1217 userauth_hostbased(Authctxt *authctxt)
1218 {
1219         Key *private = NULL;
1220         Sensitive *sensitive = authctxt->sensitive;
1221         Buffer b;
1222         u_char *signature, *blob;
1223         char *chost, *pkalg, *p;
1224         const char *service;
1225         u_int blen, slen;
1226         int ok, i, len, found = 0;
1227
1228         /* check for a useful key */
1229         for (i = 0; i < sensitive->nkeys; i++) {
1230                 private = sensitive->keys[i];
1231                 if (private && private->type != KEY_RSA1) {
1232                         found = 1;
1233                         /* we take and free the key */
1234                         sensitive->keys[i] = NULL;
1235                         break;
1236                 }
1237         }
1238         if (!found) {
1239                 debug("No more client hostkeys for hostbased authentication.");
1240                 return 0;
1241         }
1242         if (key_to_blob(private, &blob, &blen) == 0) {
1243                 key_free(private);
1244                 return 0;
1245         }
1246         /* figure out a name for the client host */
1247         p = get_local_name(packet_get_connection_in());
1248         if (p == NULL) {
1249                 error("userauth_hostbased: cannot get local ipaddr/name");
1250                 key_free(private);
1251                 return 0;
1252         }
1253         len = strlen(p) + 2;
1254         chost = xmalloc(len);
1255         strlcpy(chost, p, len);
1256         strlcat(chost, ".", len);
1257         debug2("userauth_hostbased: chost %s", chost);
1258         xfree(p);
1259
1260         service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1261             authctxt->service;
1262         pkalg = xstrdup(key_ssh_name(private));
1263         buffer_init(&b);
1264         /* construct data */
1265         buffer_put_string(&b, session_id2, session_id2_len);
1266         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1267         buffer_put_cstring(&b, authctxt->server_user);
1268         buffer_put_cstring(&b, service);
1269         buffer_put_cstring(&b, authctxt->method->name);
1270         buffer_put_cstring(&b, pkalg);
1271         buffer_put_string(&b, blob, blen);
1272         buffer_put_cstring(&b, chost);
1273         buffer_put_cstring(&b, authctxt->local_user);
1274 #ifdef DEBUG_PK
1275         buffer_dump(&b);
1276 #endif
1277         if (sensitive->external_keysign)
1278                 ok = ssh_keysign(private, &signature, &slen,
1279                     buffer_ptr(&b), buffer_len(&b));
1280         else
1281                 ok = key_sign(private, &signature, &slen,
1282                     buffer_ptr(&b), buffer_len(&b));
1283         key_free(private);
1284         buffer_free(&b);
1285         if (ok != 0) {
1286                 error("key_sign failed");
1287                 xfree(chost);
1288                 xfree(pkalg);
1289                 return 0;
1290         }
1291         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1292         packet_put_cstring(authctxt->server_user);
1293         packet_put_cstring(authctxt->service);
1294         packet_put_cstring(authctxt->method->name);
1295         packet_put_cstring(pkalg);
1296         packet_put_string(blob, blen);
1297         packet_put_cstring(chost);
1298         packet_put_cstring(authctxt->local_user);
1299         packet_put_string(signature, slen);
1300         memset(signature, 's', slen);
1301         xfree(signature);
1302         xfree(chost);
1303         xfree(pkalg);
1304
1305         packet_send();
1306         return 1;
1307 }
1308
1309 /* find auth method */
1310
1311 /*
1312  * given auth method name, if configurable options permit this method fill
1313  * in auth_ident field and return true, otherwise return false.
1314  */
1315 static int
1316 authmethod_is_enabled(Authmethod *method)
1317 {
1318         if (method == NULL)
1319                 return 0;
1320         /* return false if options indicate this method is disabled */
1321         if  (method->enabled == NULL || *method->enabled == 0)
1322                 return 0;
1323         /* return false if batch mode is enabled but method needs interactive mode */
1324         if  (method->batch_flag != NULL && *method->batch_flag != 0)
1325                 return 0;
1326         return 1;
1327 }
1328
1329 static Authmethod *
1330 authmethod_lookup(const char *name)
1331 {
1332         Authmethod *method = NULL;
1333         if (name != NULL)
1334                 for (method = authmethods; method->name != NULL; method++)
1335                         if (strcmp(name, method->name) == 0)
1336                                 return method;
1337         debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1338         return NULL;
1339 }
1340
1341 /* XXX internal state */
1342 static Authmethod *current = NULL;
1343 static char *supported = NULL;
1344 static char *preferred = NULL;
1345
1346 /*
1347  * Given the authentication method list sent by the server, return the
1348  * next method we should try.  If the server initially sends a nil list,
1349  * use a built-in default list.
1350  */
1351 static Authmethod *
1352 authmethod_get(char *authlist)
1353 {
1354         char *name = NULL;
1355         u_int next;
1356
1357         /* Use a suitable default if we're passed a nil list.  */
1358         if (authlist == NULL || strlen(authlist) == 0)
1359                 authlist = options.preferred_authentications;
1360
1361         if (supported == NULL || strcmp(authlist, supported) != 0) {
1362                 debug3("start over, passed a different list %s", authlist);
1363                 if (supported != NULL)
1364                         xfree(supported);
1365                 supported = xstrdup(authlist);
1366                 preferred = options.preferred_authentications;
1367                 debug3("preferred %s", preferred);
1368                 current = NULL;
1369         } else if (current != NULL && authmethod_is_enabled(current))
1370                 return current;
1371
1372         for (;;) {
1373                 if ((name = match_list(preferred, supported, &next)) == NULL) {
1374                         debug("No more authentication methods to try.");
1375                         current = NULL;
1376                         return NULL;
1377                 }
1378                 preferred += next;
1379                 debug3("authmethod_lookup %s", name);
1380                 debug3("remaining preferred: %s", preferred);
1381                 if ((current = authmethod_lookup(name)) != NULL &&
1382                     authmethod_is_enabled(current)) {
1383                         debug3("authmethod_is_enabled %s", name);
1384                         debug("Next authentication method: %s", name);
1385                         return current;
1386                 }
1387         }
1388 }
1389
1390 static char *
1391 authmethods_get(void)
1392 {
1393         Authmethod *method = NULL;
1394         Buffer b;
1395         char *list;
1396
1397         buffer_init(&b);
1398         for (method = authmethods; method->name != NULL; method++) {
1399                 if (authmethod_is_enabled(method)) {
1400                         if (buffer_len(&b) > 0)
1401                                 buffer_append(&b, ",", 1);
1402                         buffer_append(&b, method->name, strlen(method->name));
1403                 }
1404         }
1405         buffer_append(&b, "\0", 1);
1406         list = xstrdup(buffer_ptr(&b));
1407         buffer_free(&b);
1408         return list;
1409 }
This page took 0.159387 seconds and 5 git commands to generate.