]> andersk Git - gssapi-openssh.git/blob - openssh/sshconnect2.c
minor updates from Simon's openssh-3.6.1p2-gssapi-20030430.diff patch
[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_client_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         /* start key exchange */
149         kex = kex_setup(myproposal);
150         kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
151         kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
152 #ifdef GSSAPI
153         kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
154 #endif
155         kex->client_version_string=client_version_string;
156         kex->server_version_string=server_version_string;
157         kex->verify_host_key=&verify_host_key_callback;
158 #ifdef GSSAPI
159         kex->options.gss_deleg_creds=options.gss_deleg_creds;
160 #endif
161         xxx_kex = kex;
162
163         dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
164
165         session_id2 = kex->session_id;
166         session_id2_len = kex->session_id_len;
167
168 #ifdef DEBUG_KEXDH
169         /* send 1st encrypted/maced/compressed message */
170         packet_start(SSH2_MSG_IGNORE);
171         packet_put_cstring("markus");
172         packet_send();
173         packet_write_wait();
174 #endif
175 }
176
177 /*
178  * Authenticate user
179  */
180
181 typedef struct Authctxt Authctxt;
182 typedef struct Authmethod Authmethod;
183
184 typedef int sign_cb_fn(
185     Authctxt *authctxt, Key *key,
186     u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
187
188 struct Authctxt {
189         const char *server_user;
190         const char *local_user;
191         const char *host;
192         const char *service;
193         Authmethod *method;
194         int success;
195         char *authlist;
196         /* pubkey */
197         Key *last_key;
198         sign_cb_fn *last_key_sign;
199         int last_key_hint;
200         AuthenticationConnection *agent;
201         /* hostbased */
202         Sensitive *sensitive;
203         /* kbd-interactive */
204         int info_req_seen;
205         /* generic */
206         void *methoddata;
207 };
208 struct Authmethod {
209         char    *name;          /* string to compare against server's list */
210         int     (*userauth)(Authctxt *authctxt);
211         int     *enabled;       /* flag in option struct that enables method */
212         int     *batch_flag;    /* flag in option struct that disables method */
213 };
214
215 void    input_userauth_success(int, u_int32_t, void *);
216 void    input_userauth_failure(int, u_int32_t, void *);
217 void    input_userauth_banner(int, u_int32_t, void *);
218 void    input_userauth_error(int, u_int32_t, void *);
219 void    input_userauth_info_req(int, u_int32_t, void *);
220 void    input_userauth_pk_ok(int, u_int32_t, void *);
221 void    input_userauth_passwd_changereq(int, u_int32_t, void *);
222
223 int     userauth_none(Authctxt *);
224 int     userauth_pubkey(Authctxt *);
225 int     userauth_passwd(Authctxt *);
226 int     userauth_kbdint(Authctxt *);
227 int     userauth_hostbased(Authctxt *);
228
229 #ifdef GSSAPI
230 int     userauth_external(Authctxt *authctxt);
231 int     userauth_gssapi(Authctxt *authctxt);
232 void    input_gssapi_response(int type, u_int32_t, void *);
233 void    input_gssapi_token(int type, u_int32_t, void *);
234 void    input_gssapi_hash(int type, u_int32_t, void *);
235 void    input_gssapi_error(int, u_int32_t, void *);
236 void    input_gssapi_errtok(int, u_int32_t, void *);
237 #endif
238
239 void    userauth(Authctxt *, char *);
240
241 static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
242 static void clear_auth_state(Authctxt *);
243
244 static Authmethod *authmethod_get(char *authlist);
245 static Authmethod *authmethod_lookup(const char *name);
246 static char *authmethods_get(void);
247
248 Authmethod authmethods[] = {
249 #ifdef GSSAPI
250         {"external-keyx",
251                 userauth_external,
252                 &options.gss_authentication,
253                 NULL},
254         {"gssapi",
255                 userauth_gssapi,
256                 &options.gss_authentication,
257                 NULL},
258 #endif
259         {"hostbased",
260                 userauth_hostbased,
261                 &options.hostbased_authentication,
262                 NULL},
263         {"publickey",
264                 userauth_pubkey,
265                 &options.pubkey_authentication,
266                 NULL},
267         {"keyboard-interactive",
268                 userauth_kbdint,
269                 &options.kbd_interactive_authentication,
270                 &options.batch_mode},
271         {"password",
272                 userauth_passwd,
273                 &options.password_authentication,
274                 &options.batch_mode},
275         {"none",
276                 userauth_none,
277                 NULL,
278                 NULL},
279         {NULL, NULL, NULL, NULL}
280 };
281
282 void
283 ssh_userauth2(const char *local_user, const char *server_user, char *host,
284     Sensitive *sensitive)
285 {
286         Authctxt authctxt;
287         int type;
288
289         if (options.challenge_response_authentication)
290                 options.kbd_interactive_authentication = 1;
291
292         packet_start(SSH2_MSG_SERVICE_REQUEST);
293         packet_put_cstring("ssh-userauth");
294         packet_send();
295         debug("SSH2_MSG_SERVICE_REQUEST sent");
296         packet_write_wait();
297         type = packet_read();
298         if (type != SSH2_MSG_SERVICE_ACCEPT)
299                 fatal("Server denied authentication request: %d", type);
300         if (packet_remaining() > 0) {
301                 char *reply = packet_get_string(NULL);
302                 debug2("service_accept: %s", reply);
303                 xfree(reply);
304         } else {
305                 debug2("buggy server: service_accept w/o service");
306         }
307         packet_check_eom();
308         debug("SSH2_MSG_SERVICE_ACCEPT received");
309
310         if (options.preferred_authentications == NULL)
311                 options.preferred_authentications = authmethods_get();
312
313         /* setup authentication context */
314         memset(&authctxt, 0, sizeof(authctxt));
315         authctxt.agent = ssh_get_authentication_connection();
316         authctxt.server_user = server_user;
317         authctxt.local_user = local_user;
318         authctxt.host = host;
319         authctxt.service = "ssh-connection";            /* service name */
320         authctxt.success = 0;
321         authctxt.method = authmethod_lookup("none");
322         authctxt.authlist = NULL;
323         authctxt.methoddata = NULL;
324         authctxt.sensitive = sensitive;
325         authctxt.info_req_seen = 0;
326         if (authctxt.method == NULL)
327                 fatal("ssh_userauth2: internal error: cannot send userauth none request");
328
329         /* initial userauth request */
330         userauth_none(&authctxt);
331
332         dispatch_init(&input_userauth_error);
333         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
334         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
335         dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
336         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
337
338         if (authctxt.agent != NULL)
339                 ssh_close_authentication_connection(authctxt.agent);
340
341         debug("Authentication succeeded (%s).", authctxt.method->name);
342 }
343 void
344 userauth(Authctxt *authctxt, char *authlist)
345 {
346         if (authctxt->methoddata!=NULL) {
347                 xfree(authctxt->methoddata);
348                 authctxt->methoddata=NULL;
349         }
350            
351         if (authlist == NULL) {
352                 authlist = authctxt->authlist;
353         } else {
354                 if (authctxt->authlist)
355                         xfree(authctxt->authlist);
356                 authctxt->authlist = authlist;
357         }
358         for (;;) {
359                 Authmethod *method = authmethod_get(authlist);
360                 if (method == NULL)
361                         fatal("Permission denied (%s).", authlist);
362                 authctxt->method = method;
363                 if (method->userauth(authctxt) != 0) {
364                         debug2("we sent a %s packet, wait for reply", method->name);
365                         break;
366                 } else {
367                         debug2("we did not send a packet, disable method");
368                         method->enabled = NULL;
369                 }
370         }
371 }
372
373 void
374 input_userauth_error(int type, u_int32_t seq, void *ctxt)
375 {
376         fatal("input_userauth_error: bad message during authentication: "
377            "type %d", type);
378 }
379
380 void
381 input_userauth_banner(int type, u_int32_t seq, void *ctxt)
382 {
383         char *msg, *lang;
384         debug3("input_userauth_banner");
385         msg = packet_get_string(NULL);
386         lang = packet_get_string(NULL);
387         fprintf(stderr, "%s", msg);
388         xfree(msg);
389         xfree(lang);
390 }
391
392 void
393 input_userauth_success(int type, u_int32_t seq, void *ctxt)
394 {
395         Authctxt *authctxt = ctxt;
396         if (authctxt == NULL)
397                 fatal("input_userauth_success: no authentication context");
398         if (authctxt->authlist)
399                 xfree(authctxt->authlist);
400         if (authctxt->methoddata)
401                 xfree(authctxt->methoddata);
402         clear_auth_state(authctxt);
403         authctxt->success = 1;                  /* break out */
404 }
405
406 void
407 input_userauth_failure(int type, u_int32_t seq, void *ctxt)
408 {
409         Authctxt *authctxt = ctxt;
410         char *authlist = NULL;
411         int partial;
412
413         if (authctxt == NULL)
414                 fatal("input_userauth_failure: no authentication context");
415
416         authlist = packet_get_string(NULL);
417         partial = packet_get_char();
418         packet_check_eom();
419
420         if (partial != 0)
421                 log("Authenticated with partial success.");
422         debug("Authentications that can continue: %s", authlist);
423
424         clear_auth_state(authctxt);
425         userauth(authctxt, authlist);
426 }
427 void
428 input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
429 {
430         Authctxt *authctxt = ctxt;
431         Key *key = NULL;
432         Buffer b;
433         int pktype, sent = 0;
434         u_int alen, blen;
435         char *pkalg, *fp;
436         u_char *pkblob;
437
438         if (authctxt == NULL)
439                 fatal("input_userauth_pk_ok: no authentication context");
440         if (datafellows & SSH_BUG_PKOK) {
441                 /* this is similar to SSH_BUG_PKAUTH */
442                 debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
443                 pkblob = packet_get_string(&blen);
444                 buffer_init(&b);
445                 buffer_append(&b, pkblob, blen);
446                 pkalg = buffer_get_string(&b, &alen);
447                 buffer_free(&b);
448         } else {
449                 pkalg = packet_get_string(&alen);
450                 pkblob = packet_get_string(&blen);
451         }
452         packet_check_eom();
453
454         debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
455             pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
456
457         do {
458                 if (authctxt->last_key == NULL ||
459                     authctxt->last_key_sign == NULL) {
460                         debug("no last key or no sign cb");
461                         break;
462                 }
463                 if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
464                         debug("unknown pkalg %s", pkalg);
465                         break;
466                 }
467                 if ((key = key_from_blob(pkblob, blen)) == NULL) {
468                         debug("no key from blob. pkalg %s", pkalg);
469                         break;
470                 }
471                 if (key->type != pktype) {
472                         error("input_userauth_pk_ok: type mismatch "
473                             "for decoded key (received %d, expected %d)",
474                             key->type, pktype);
475                         break;
476                 }
477                 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
478                 debug2("input_userauth_pk_ok: fp %s", fp);
479                 xfree(fp);
480                 if (!key_equal(key, authctxt->last_key)) {
481                         debug("key != last_key");
482                         break;
483                 }
484                 sent = sign_and_send_pubkey(authctxt, key,
485                    authctxt->last_key_sign);
486         } while (0);
487
488         if (key != NULL)
489                 key_free(key);
490         xfree(pkalg);
491         xfree(pkblob);
492
493         /* unregister */
494         clear_auth_state(authctxt);
495         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
496
497         /* try another method if we did not send a packet */
498         if (sent == 0)
499                 userauth(authctxt, NULL);
500
501 }
502
503 #ifdef GSSAPI
504 int 
505 userauth_gssapi(Authctxt *authctxt)
506 {
507         Gssctxt *gssctxt = NULL;
508         static gss_OID_set supported = NULL;
509         static int mech=0;
510         OM_uint32 min;
511         int ok=0;
512
513         /* Things work better if we send one mechanism at a time, rather
514          * than them all at once. This means that if we fail at some point
515          * in the middle of a negotiation, we can come back and try something
516          * different. */
517
518         if (datafellows & SSH_OLD_GSSAPI) return 0;
519         
520         /* Before we offer a mechanism, check that we can support it. Don't
521          * bother trying to get credentials - as the standard fallback will
522          * deal with that kind of failure.
523          */
524
525         if (supported==NULL) gss_indicate_mechs(&min, &supported);
526         
527         while (mech<supported->count && !ok) {
528                 if (gssctxt) ssh_gssapi_delete_ctx(&gssctxt);
529                 ssh_gssapi_build_ctx(&gssctxt);
530                 ssh_gssapi_set_oid(gssctxt,&supported->elements[mech]);
531
532                 /* The DER encoding below only works for lengths<128,
533                  * so check this here 
534                  */
535                 if (supported->elements[mech].length<128 &&
536                     !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
537                                                       authctxt->host))) {
538                         ok = 1; /* Mechanism works */
539                 } else {
540                         mech++;
541                 }
542         }
543         
544         if (!ok) return 0;
545         
546         authctxt->methoddata=(void *)gssctxt;
547                 
548         packet_start(SSH2_MSG_USERAUTH_REQUEST);
549         packet_put_cstring(authctxt->server_user);
550         packet_put_cstring(authctxt->service);
551         packet_put_cstring(authctxt->method->name);
552         
553         packet_put_int(1);
554
555         /* The newest gsskeyex draft stipulates that OIDs should
556          * be DER encoded, so we need to add the object type and
557          * length information back on */
558         if (datafellows & SSH_BUG_GSSAPI_BER) {
559                 packet_put_string(supported->elements[mech].elements,
560                                   supported->elements[mech].length);
561         } else {
562                 packet_put_int((supported->elements[mech].length)+2);
563                 packet_put_char(0x06);
564                 packet_put_char(supported->elements[mech].length);
565                 packet_put_raw(supported->elements[mech].elements,
566                                supported->elements[mech].length);
567         }
568
569         packet_send();
570         packet_write_wait();
571
572         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
573         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
574         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error);
575         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok);
576         
577         mech++; /* Move along to next candidate */
578
579         return 1;
580 }
581
582 void
583 input_gssapi_response(int type, u_int32_t plen, void *ctxt) 
584 {
585         Authctxt *authctxt = ctxt;
586         Gssctxt *gssctxt;
587         OM_uint32 status,ms;
588         int oidlen;
589         char *oidv;
590         gss_buffer_desc send_tok;
591         
592         if (authctxt == NULL)
593                 fatal("input_gssapi_response: no authentication context");
594         gssctxt = authctxt->methoddata;
595         
596         /* Setup our OID */
597         oidv=packet_get_string(&oidlen);
598         
599         if (datafellows & SSH_BUG_GSSAPI_BER) {
600                 if (!ssh_gssapi_check_oid(gssctxt,oidv,oidlen)) {
601                         fatal("Server returned different OID than expected");
602                 }
603                 ssh_gssapi_set_oid_data(gssctxt,oidv,oidlen);
604         } else {
605                 if(oidv[0]!=0x06 || oidv[1]!=oidlen-2) {
606                         debug("Badly encoded mechanism OID received");
607                         clear_auth_state(authctxt);
608                         userauth(authctxt,NULL);
609                         return;
610                 }
611                 if (!ssh_gssapi_check_oid(gssctxt,oidv+2,oidlen-2)) {
612                         fatal("Server returned different OID than expected");
613                 }
614                 ssh_gssapi_set_oid_data(gssctxt,oidv+2,oidlen-2);
615         }
616                 
617         packet_check_eom();
618         
619         status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
620                                      GSS_C_NO_BUFFER, &send_tok, 
621                                      NULL);
622         if (GSS_ERROR(status)) {
623                 if (send_tok.length>0) {
624                         packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
625                         packet_put_string(send_tok.value,send_tok.length);
626                         packet_send();
627                         packet_write_wait();
628                 }
629                 /* Start again with next method on list */
630                 debug("Trying to start again");
631                 clear_auth_state(authctxt);
632                 userauth(authctxt,NULL);
633                 return;
634         }
635
636         /* We must have data to send */                                 
637         packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
638         packet_put_string(send_tok.value,send_tok.length);
639         packet_send();
640         packet_write_wait();
641         gss_release_buffer(&ms, &send_tok);
642 }
643
644 void
645 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
646 {
647         Authctxt *authctxt = ctxt;
648         Gssctxt *gssctxt;
649         gss_buffer_desc send_tok,recv_tok;
650         OM_uint32 status;
651         u_int slen;
652         
653         if (authctxt == NULL)
654                 fatal("input_gssapi_token: no authentication context");
655         gssctxt = authctxt->methoddata;
656         
657         recv_tok.value=packet_get_string(&slen);
658         recv_tok.length=slen;   /* safe typecast */
659
660         status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
661                                    &recv_tok, &send_tok, NULL);
662
663         packet_check_eom();
664         
665         if (GSS_ERROR(status)) {
666                 if (send_tok.length>0) {
667                         packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
668                         packet_put_string(send_tok.value,send_tok.length);
669                         packet_send();
670                         packet_write_wait();
671                 }
672                 /* Start again with the next method in the list */
673                 clear_auth_state(authctxt);
674                 userauth(authctxt,NULL);
675                 return;
676         }
677         
678         if (send_tok.length>0) {
679                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
680                 packet_put_string(send_tok.value,send_tok.length);
681                 packet_send();
682                 packet_write_wait();
683         }
684         
685         if (status == GSS_S_COMPLETE) {
686                 /* If that succeeded, send a exchange complete message */
687                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
688                 packet_send();
689                 packet_write_wait();
690         }
691 }
692
693 void
694 input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
695 {
696         Authctxt *authctxt = ctxt;
697         Gssctxt *gssctxt;
698         gss_buffer_desc send_tok,recv_tok;
699         OM_uint32 status;
700         
701         if (authctxt == NULL)
702                 fatal("input_gssapi_response: no authentication context");
703         gssctxt = authctxt->methoddata;
704         
705         recv_tok.value=packet_get_string(&recv_tok.length);
706
707         /* Stick it into GSSAPI and see what it says */
708         status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
709                                    &recv_tok, &send_tok, NULL);
710
711         packet_check_eom();
712         
713         /* We can't send a packet to the server */
714
715         /* The draft says that we should wait for the server to fail 
716          * before starting the next authentication. So, we clear the
717          * state, but don't do anything else */
718         clear_auth_state(authctxt);
719         return;
720 }
721
722 void
723 input_gssapi_error(int type, u_int32_t plen, void *ctxt)
724 {
725         OM_uint32 maj,min;
726         char *msg;
727         char *lang;
728         
729         maj=packet_get_int();
730         min=packet_get_int();
731         msg=packet_get_string(NULL);
732         lang=packet_get_string(NULL);
733
734         packet_check_eom();
735         
736         fprintf(stderr, "Server GSSAPI Error:\n%s\n", msg);
737         xfree(msg);
738         xfree(lang);
739 }
740
741 int
742 userauth_external(Authctxt *authctxt)
743 {
744         static int attempt =0;
745         
746         if (attempt++ >= 1)
747                 return 0;
748                                 
749         debug2("userauth_external");
750         packet_start(SSH2_MSG_USERAUTH_REQUEST);
751 #ifdef GSI
752         if(options.implicit && !(datafellows & SSH_BUG_GSS_EMPTYUSER)) {
753             packet_put_cstring("");
754         } else {
755 #endif
756             packet_put_cstring(authctxt->server_user);
757 #ifdef GSI
758         }
759 #endif
760         packet_put_cstring(authctxt->service);
761         packet_put_cstring(authctxt->method->name);
762         packet_send();
763         packet_write_wait();
764         return 1;
765 }                                                                                                
766 #endif /* GSSAPI */
767
768 int
769 userauth_none(Authctxt *authctxt)
770 {
771         /* initial userauth request */
772         packet_start(SSH2_MSG_USERAUTH_REQUEST);
773         packet_put_cstring(authctxt->server_user);
774         packet_put_cstring(authctxt->service);
775         packet_put_cstring(authctxt->method->name);
776         packet_send();
777         return 1;
778
779 }
780
781 int
782 userauth_passwd(Authctxt *authctxt)
783 {
784         static int attempt = 0;
785         char prompt[150];
786         char *password;
787
788         if (attempt++ >= options.number_of_password_prompts)
789                 return 0;
790
791         if (attempt != 1)
792                 error("Permission denied, please try again.");
793
794         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
795             authctxt->server_user, authctxt->host);
796         password = read_passphrase(prompt, 0);
797         packet_start(SSH2_MSG_USERAUTH_REQUEST);
798         packet_put_cstring(authctxt->server_user);
799         packet_put_cstring(authctxt->service);
800         packet_put_cstring(authctxt->method->name);
801         packet_put_char(0);
802         packet_put_cstring(password);
803         memset(password, 0, strlen(password));
804         xfree(password);
805         packet_add_padding(64);
806         packet_send();
807
808         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
809             &input_userauth_passwd_changereq);
810
811         return 1;
812 }
813 /*
814  * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
815  */
816 void
817 input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
818 {
819         Authctxt *authctxt = ctxt;
820         char *info, *lang, *password = NULL, *retype = NULL;
821         char prompt[150];
822
823         debug2("input_userauth_passwd_changereq");
824
825         if (authctxt == NULL)
826                 fatal("input_userauth_passwd_changereq: "
827                     "no authentication context");
828
829         info = packet_get_string(NULL);
830         lang = packet_get_string(NULL);
831         if (strlen(info) > 0)
832                 log("%s", info);
833         xfree(info);
834         xfree(lang);
835         packet_start(SSH2_MSG_USERAUTH_REQUEST);
836         packet_put_cstring(authctxt->server_user);
837         packet_put_cstring(authctxt->service);
838         packet_put_cstring(authctxt->method->name);
839         packet_put_char(1);                     /* additional info */
840         snprintf(prompt, sizeof(prompt),
841             "Enter %.30s@%.128s's old password: ",
842             authctxt->server_user, authctxt->host);
843         password = read_passphrase(prompt, 0);
844         packet_put_cstring(password);
845         memset(password, 0, strlen(password));
846         xfree(password);
847         password = NULL;
848         while (password == NULL) {
849                 snprintf(prompt, sizeof(prompt),
850                     "Enter %.30s@%.128s's new password: ",
851                     authctxt->server_user, authctxt->host);
852                 password = read_passphrase(prompt, RP_ALLOW_EOF);
853                 if (password == NULL) {
854                         /* bail out */
855                         return;
856                 }
857                 snprintf(prompt, sizeof(prompt),
858                     "Retype %.30s@%.128s's new password: ",
859                     authctxt->server_user, authctxt->host);
860                 retype = read_passphrase(prompt, 0);
861                 if (strcmp(password, retype) != 0) {
862                         memset(password, 0, strlen(password));
863                         xfree(password);
864                         log("Mismatch; try again, EOF to quit.");
865                         password = NULL;
866                 }
867                 memset(retype, 0, strlen(retype));
868                 xfree(retype);
869         }
870         packet_put_cstring(password);
871         memset(password, 0, strlen(password));
872         xfree(password);
873         packet_add_padding(64);
874         packet_send();
875
876         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
877             &input_userauth_passwd_changereq);
878 }
879
880 static void
881 clear_auth_state(Authctxt *authctxt)
882 {
883         /* XXX clear authentication state */
884         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
885 #ifdef GSSAPI
886         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,NULL);
887         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
888         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,NULL);
889 #endif
890         
891         if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
892                 debug3("clear_auth_state: key_free %p", authctxt->last_key);
893                 key_free(authctxt->last_key);
894         }
895         authctxt->last_key = NULL;
896         authctxt->last_key_hint = -2;
897         authctxt->last_key_sign = NULL;
898 }
899
900 static int
901 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
902 {
903         Buffer b;
904         u_char *blob, *signature;
905         u_int bloblen, slen;
906         int skip = 0;
907         int ret = -1;
908         int have_sig = 1;
909
910         debug3("sign_and_send_pubkey");
911
912         if (key_to_blob(k, &blob, &bloblen) == 0) {
913                 /* we cannot handle this key */
914                 debug3("sign_and_send_pubkey: cannot handle key");
915                 return 0;
916         }
917         /* data to be signed */
918         buffer_init(&b);
919         if (datafellows & SSH_OLD_SESSIONID) {
920                 buffer_append(&b, session_id2, session_id2_len);
921                 skip = session_id2_len;
922         } else {
923                 buffer_put_string(&b, session_id2, session_id2_len);
924                 skip = buffer_len(&b);
925         }
926         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
927         buffer_put_cstring(&b, authctxt->server_user);
928         buffer_put_cstring(&b,
929             datafellows & SSH_BUG_PKSERVICE ?
930             "ssh-userauth" :
931             authctxt->service);
932         if (datafellows & SSH_BUG_PKAUTH) {
933                 buffer_put_char(&b, have_sig);
934         } else {
935                 buffer_put_cstring(&b, authctxt->method->name);
936                 buffer_put_char(&b, have_sig);
937                 buffer_put_cstring(&b, key_ssh_name(k));
938         }
939         buffer_put_string(&b, blob, bloblen);
940
941         /* generate signature */
942         ret = (*sign_callback)(authctxt, k, &signature, &slen,
943             buffer_ptr(&b), buffer_len(&b));
944         if (ret == -1) {
945                 xfree(blob);
946                 buffer_free(&b);
947                 return 0;
948         }
949 #ifdef DEBUG_PK
950         buffer_dump(&b);
951 #endif
952         if (datafellows & SSH_BUG_PKSERVICE) {
953                 buffer_clear(&b);
954                 buffer_append(&b, session_id2, session_id2_len);
955                 skip = session_id2_len;
956                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
957                 buffer_put_cstring(&b, authctxt->server_user);
958                 buffer_put_cstring(&b, authctxt->service);
959                 buffer_put_cstring(&b, authctxt->method->name);
960                 buffer_put_char(&b, have_sig);
961                 if (!(datafellows & SSH_BUG_PKAUTH))
962                         buffer_put_cstring(&b, key_ssh_name(k));
963                 buffer_put_string(&b, blob, bloblen);
964         }
965         xfree(blob);
966
967         /* append signature */
968         buffer_put_string(&b, signature, slen);
969         xfree(signature);
970
971         /* skip session id and packet type */
972         if (buffer_len(&b) < skip + 1)
973                 fatal("userauth_pubkey: internal error");
974         buffer_consume(&b, skip + 1);
975
976         /* put remaining data from buffer into packet */
977         packet_start(SSH2_MSG_USERAUTH_REQUEST);
978         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
979         buffer_free(&b);
980         packet_send();
981
982         return 1;
983 }
984
985 static int
986 send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
987     int hint)
988 {
989         u_char *blob;
990         u_int bloblen, have_sig = 0;
991
992         debug3("send_pubkey_test");
993
994         if (key_to_blob(k, &blob, &bloblen) == 0) {
995                 /* we cannot handle this key */
996                 debug3("send_pubkey_test: cannot handle key");
997                 return 0;
998         }
999         /* register callback for USERAUTH_PK_OK message */
1000         authctxt->last_key_sign = sign_callback;
1001         authctxt->last_key_hint = hint;
1002         authctxt->last_key = k;
1003         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
1004
1005         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1006         packet_put_cstring(authctxt->server_user);
1007         packet_put_cstring(authctxt->service);
1008         packet_put_cstring(authctxt->method->name);
1009         packet_put_char(have_sig);
1010         if (!(datafellows & SSH_BUG_PKAUTH))
1011                 packet_put_cstring(key_ssh_name(k));
1012         packet_put_string(blob, bloblen);
1013         xfree(blob);
1014         packet_send();
1015         return 1;
1016 }
1017
1018 static Key *
1019 load_identity_file(char *filename)
1020 {
1021         Key *private;
1022         char prompt[300], *passphrase;
1023         int quit, i;
1024         struct stat st;
1025
1026         if (stat(filename, &st) < 0) {
1027                 debug3("no such identity: %s", filename);
1028                 return NULL;
1029         }
1030         private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
1031         if (private == NULL) {
1032                 if (options.batch_mode)
1033                         return NULL;
1034                 snprintf(prompt, sizeof prompt,
1035                     "Enter passphrase for key '%.100s': ", filename);
1036                 for (i = 0; i < options.number_of_password_prompts; i++) {
1037                         passphrase = read_passphrase(prompt, 0);
1038                         if (strcmp(passphrase, "") != 0) {
1039                                 private = key_load_private_type(KEY_UNSPEC, filename,
1040                                     passphrase, NULL);
1041                                 quit = 0;
1042                         } else {
1043                                 debug2("no passphrase given, try next key");
1044                                 quit = 1;
1045                         }
1046                         memset(passphrase, 0, strlen(passphrase));
1047                         xfree(passphrase);
1048                         if (private != NULL || quit)
1049                                 break;
1050                         debug2("bad passphrase given, try again...");
1051                 }
1052         }
1053         return private;
1054 }
1055
1056 static int
1057 identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
1058     u_char *data, u_int datalen)
1059 {
1060         Key *private;
1061         int idx, ret;
1062
1063         idx = authctxt->last_key_hint;
1064         if (idx < 0)
1065                 return -1;
1066
1067         /* private key is stored in external hardware */
1068         if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
1069                 return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
1070
1071         private = load_identity_file(options.identity_files[idx]);
1072         if (private == NULL)
1073                 return -1;
1074         ret = key_sign(private, sigp, lenp, data, datalen);
1075         key_free(private);
1076         return ret;
1077 }
1078
1079 static int
1080 agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
1081     u_char *data, u_int datalen)
1082 {
1083         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
1084 }
1085
1086 static int
1087 key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
1088     u_char *data, u_int datalen)
1089 {
1090         return key_sign(key, sigp, lenp, data, datalen);
1091 }
1092
1093 static int
1094 userauth_pubkey_agent(Authctxt *authctxt)
1095 {
1096         static int called = 0;
1097         int ret = 0;
1098         char *comment;
1099         Key *k;
1100
1101         if (called == 0) {
1102                 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
1103                         debug2("userauth_pubkey_agent: no keys at all");
1104                 called = 1;
1105         }
1106         k = ssh_get_next_identity(authctxt->agent, &comment, 2);
1107         if (k == NULL) {
1108                 debug2("userauth_pubkey_agent: no more keys");
1109         } else {
1110                 debug("Offering agent key: %s", comment);
1111                 xfree(comment);
1112                 ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
1113                 if (ret == 0)
1114                         key_free(k);
1115         }
1116         if (ret == 0)
1117                 debug2("userauth_pubkey_agent: no message sent");
1118         return ret;
1119 }
1120
1121 int
1122 userauth_pubkey(Authctxt *authctxt)
1123 {
1124         static int idx = 0;
1125         int sent = 0;
1126         Key *key;
1127         char *filename;
1128
1129         if (authctxt->agent != NULL) {
1130                 do {
1131                         sent = userauth_pubkey_agent(authctxt);
1132                 } while (!sent && authctxt->agent->howmany > 0);
1133         }
1134         while (!sent && idx < options.num_identity_files) {
1135                 key = options.identity_keys[idx];
1136                 filename = options.identity_files[idx];
1137                 if (key == NULL) {
1138                         debug("Trying private key: %s", filename);
1139                         key = load_identity_file(filename);
1140                         if (key != NULL) {
1141                                 sent = sign_and_send_pubkey(authctxt, key,
1142                                     key_sign_cb);
1143                                 key_free(key);
1144                         }
1145                 } else if (key->type != KEY_RSA1) {
1146                         debug("Offering public key: %s", filename);
1147                         sent = send_pubkey_test(authctxt, key,
1148                             identity_sign_cb, idx);
1149                 }
1150                 idx++;
1151         }
1152         return sent;
1153 }
1154
1155 /*
1156  * Send userauth request message specifying keyboard-interactive method.
1157  */
1158 int
1159 userauth_kbdint(Authctxt *authctxt)
1160 {
1161         static int attempt = 0;
1162
1163         if (attempt++ >= options.number_of_password_prompts)
1164                 return 0;
1165         /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
1166         if (attempt > 1 && !authctxt->info_req_seen) {
1167                 debug3("userauth_kbdint: disable: no info_req_seen");
1168                 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
1169                 return 0;
1170         }
1171
1172         debug2("userauth_kbdint");
1173         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1174         packet_put_cstring(authctxt->server_user);
1175         packet_put_cstring(authctxt->service);
1176         packet_put_cstring(authctxt->method->name);
1177         packet_put_cstring("");                                 /* lang */
1178         packet_put_cstring(options.kbd_interactive_devices ?
1179             options.kbd_interactive_devices : "");
1180         packet_send();
1181
1182         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
1183         return 1;
1184 }
1185
1186 /*
1187  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1188  */
1189 void
1190 input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
1191 {
1192         Authctxt *authctxt = ctxt;
1193         char *name, *inst, *lang, *prompt, *response;
1194         u_int num_prompts, i;
1195         int echo = 0;
1196
1197         debug2("input_userauth_info_req");
1198
1199         if (authctxt == NULL)
1200                 fatal("input_userauth_info_req: no authentication context");
1201
1202         authctxt->info_req_seen = 1;
1203
1204         name = packet_get_string(NULL);
1205         inst = packet_get_string(NULL);
1206         lang = packet_get_string(NULL);
1207         if (strlen(name) > 0)
1208                 log("%s", name);
1209         if (strlen(inst) > 0)
1210                 log("%s", inst);
1211         xfree(name);
1212         xfree(inst);
1213         xfree(lang);
1214
1215         num_prompts = packet_get_int();
1216         /*
1217          * Begin to build info response packet based on prompts requested.
1218          * We commit to providing the correct number of responses, so if
1219          * further on we run into a problem that prevents this, we have to
1220          * be sure and clean this up and send a correct error response.
1221          */
1222         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
1223         packet_put_int(num_prompts);
1224
1225         debug2("input_userauth_info_req: num_prompts %d", num_prompts);
1226         for (i = 0; i < num_prompts; i++) {
1227                 prompt = packet_get_string(NULL);
1228                 echo = packet_get_char();
1229
1230                 response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1231
1232                 packet_put_cstring(response);
1233                 memset(response, 0, strlen(response));
1234                 xfree(response);
1235                 xfree(prompt);
1236         }
1237         packet_check_eom(); /* done with parsing incoming message. */
1238
1239         packet_add_padding(64);
1240         packet_send();
1241 }
1242
1243 static int
1244 ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
1245     u_char *data, u_int datalen)
1246 {
1247         Buffer b;
1248         struct stat st;
1249         pid_t pid;
1250         int to[2], from[2], status, version = 2;
1251
1252         debug2("ssh_keysign called");
1253
1254         if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
1255                 error("ssh_keysign: no installed: %s", strerror(errno));
1256                 return -1;
1257         }
1258         if (fflush(stdout) != 0)
1259                 error("ssh_keysign: fflush: %s", strerror(errno));
1260         if (pipe(to) < 0) {
1261                 error("ssh_keysign: pipe: %s", strerror(errno));
1262                 return -1;
1263         }
1264         if (pipe(from) < 0) {
1265                 error("ssh_keysign: pipe: %s", strerror(errno));
1266                 return -1;
1267         }
1268         if ((pid = fork()) < 0) {
1269                 error("ssh_keysign: fork: %s", strerror(errno));
1270                 return -1;
1271         }
1272         if (pid == 0) {
1273                 seteuid(getuid());
1274                 setuid(getuid());
1275                 close(from[0]);
1276                 if (dup2(from[1], STDOUT_FILENO) < 0)
1277                         fatal("ssh_keysign: dup2: %s", strerror(errno));
1278                 close(to[1]);
1279                 if (dup2(to[0], STDIN_FILENO) < 0)
1280                         fatal("ssh_keysign: dup2: %s", strerror(errno));
1281                 close(from[1]);
1282                 close(to[0]);
1283                 execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
1284                 fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
1285                     strerror(errno));
1286         }
1287         close(from[1]);
1288         close(to[0]);
1289
1290         buffer_init(&b);
1291         buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
1292         buffer_put_string(&b, data, datalen);
1293         ssh_msg_send(to[1], version, &b);
1294
1295         if (ssh_msg_recv(from[0], &b) < 0) {
1296                 error("ssh_keysign: no reply");
1297                 buffer_clear(&b);
1298                 return -1;
1299         }
1300         close(from[0]);
1301         close(to[1]);
1302
1303         while (waitpid(pid, &status, 0) < 0)
1304                 if (errno != EINTR)
1305                         break;
1306
1307         if (buffer_get_char(&b) != version) {
1308                 error("ssh_keysign: bad version");
1309                 buffer_clear(&b);
1310                 return -1;
1311         }
1312         *sigp = buffer_get_string(&b, lenp);
1313         buffer_clear(&b);
1314
1315         return 0;
1316 }
1317
1318 int
1319 userauth_hostbased(Authctxt *authctxt)
1320 {
1321         Key *private = NULL;
1322         Sensitive *sensitive = authctxt->sensitive;
1323         Buffer b;
1324         u_char *signature, *blob;
1325         char *chost, *pkalg, *p;
1326         const char *service;
1327         u_int blen, slen;
1328         int ok, i, len, found = 0;
1329
1330         /* check for a useful key */
1331         for (i = 0; i < sensitive->nkeys; i++) {
1332                 private = sensitive->keys[i];
1333                 if (private && private->type != KEY_RSA1) {
1334                         found = 1;
1335                         /* we take and free the key */
1336                         sensitive->keys[i] = NULL;
1337                         break;
1338                 }
1339         }
1340         if (!found) {
1341                 debug("No more client hostkeys for hostbased authentication.");
1342                 return 0;
1343         }
1344         if (key_to_blob(private, &blob, &blen) == 0) {
1345                 key_free(private);
1346                 return 0;
1347         }
1348         /* figure out a name for the client host */
1349         p = get_local_name(packet_get_connection_in());
1350         if (p == NULL) {
1351                 error("userauth_hostbased: cannot get local ipaddr/name");
1352                 key_free(private);
1353                 return 0;
1354         }
1355         len = strlen(p) + 2;
1356         chost = xmalloc(len);
1357         strlcpy(chost, p, len);
1358         strlcat(chost, ".", len);
1359         debug2("userauth_hostbased: chost %s", chost);
1360         xfree(p);
1361
1362         service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1363             authctxt->service;
1364         pkalg = xstrdup(key_ssh_name(private));
1365         buffer_init(&b);
1366         /* construct data */
1367         buffer_put_string(&b, session_id2, session_id2_len);
1368         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1369         buffer_put_cstring(&b, authctxt->server_user);
1370         buffer_put_cstring(&b, service);
1371         buffer_put_cstring(&b, authctxt->method->name);
1372         buffer_put_cstring(&b, pkalg);
1373         buffer_put_string(&b, blob, blen);
1374         buffer_put_cstring(&b, chost);
1375         buffer_put_cstring(&b, authctxt->local_user);
1376 #ifdef DEBUG_PK
1377         buffer_dump(&b);
1378 #endif
1379         if (sensitive->external_keysign)
1380                 ok = ssh_keysign(private, &signature, &slen,
1381                     buffer_ptr(&b), buffer_len(&b));
1382         else
1383                 ok = key_sign(private, &signature, &slen,
1384                     buffer_ptr(&b), buffer_len(&b));
1385         key_free(private);
1386         buffer_free(&b);
1387         if (ok != 0) {
1388                 error("key_sign failed");
1389                 xfree(chost);
1390                 xfree(pkalg);
1391                 return 0;
1392         }
1393         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1394         packet_put_cstring(authctxt->server_user);
1395         packet_put_cstring(authctxt->service);
1396         packet_put_cstring(authctxt->method->name);
1397         packet_put_cstring(pkalg);
1398         packet_put_string(blob, blen);
1399         packet_put_cstring(chost);
1400         packet_put_cstring(authctxt->local_user);
1401         packet_put_string(signature, slen);
1402         memset(signature, 's', slen);
1403         xfree(signature);
1404         xfree(chost);
1405         xfree(pkalg);
1406
1407         packet_send();
1408         return 1;
1409 }
1410
1411 /* find auth method */
1412
1413 /*
1414  * given auth method name, if configurable options permit this method fill
1415  * in auth_ident field and return true, otherwise return false.
1416  */
1417 static int
1418 authmethod_is_enabled(Authmethod *method)
1419 {
1420         if (method == NULL)
1421                 return 0;
1422         /* return false if options indicate this method is disabled */
1423         if  (method->enabled == NULL || *method->enabled == 0)
1424                 return 0;
1425         /* return false if batch mode is enabled but method needs interactive mode */
1426         if  (method->batch_flag != NULL && *method->batch_flag != 0)
1427                 return 0;
1428         return 1;
1429 }
1430
1431 static Authmethod *
1432 authmethod_lookup(const char *name)
1433 {
1434         Authmethod *method = NULL;
1435         if (name != NULL)
1436                 for (method = authmethods; method->name != NULL; method++)
1437                         if (strcmp(name, method->name) == 0)
1438                                 return method;
1439         debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1440         return NULL;
1441 }
1442
1443 /* XXX internal state */
1444 static Authmethod *current = NULL;
1445 static char *supported = NULL;
1446 static char *preferred = NULL;
1447
1448 /*
1449  * Given the authentication method list sent by the server, return the
1450  * next method we should try.  If the server initially sends a nil list,
1451  * use a built-in default list.
1452  */
1453 static Authmethod *
1454 authmethod_get(char *authlist)
1455 {
1456         char *name = NULL;
1457         u_int next;
1458
1459         /* Use a suitable default if we're passed a nil list.  */
1460         if (authlist == NULL || strlen(authlist) == 0)
1461                 authlist = options.preferred_authentications;
1462
1463         if (supported == NULL || strcmp(authlist, supported) != 0) {
1464                 debug3("start over, passed a different list %s", authlist);
1465                 if (supported != NULL)
1466                         xfree(supported);
1467                 supported = xstrdup(authlist);
1468                 preferred = options.preferred_authentications;
1469                 debug3("preferred %s", preferred);
1470                 current = NULL;
1471         } else if (current != NULL && authmethod_is_enabled(current))
1472                 return current;
1473
1474         for (;;) {
1475                 if ((name = match_list(preferred, supported, &next)) == NULL) {
1476                         debug("No more authentication methods to try.");
1477                         current = NULL;
1478                         return NULL;
1479                 }
1480                 preferred += next;
1481                 debug3("authmethod_lookup %s", name);
1482                 debug3("remaining preferred: %s", preferred);
1483                 if ((current = authmethod_lookup(name)) != NULL &&
1484                     authmethod_is_enabled(current)) {
1485                         debug3("authmethod_is_enabled %s", name);
1486                         debug("Next authentication method: %s", name);
1487                         return current;
1488                 }
1489         }
1490 }
1491
1492 static char *
1493 authmethods_get(void)
1494 {
1495         Authmethod *method = NULL;
1496         Buffer b;
1497         char *list;
1498
1499         buffer_init(&b);
1500         for (method = authmethods; method->name != NULL; method++) {
1501                 if (authmethod_is_enabled(method)) {
1502                         if (buffer_len(&b) > 0)
1503                                 buffer_append(&b, ",", 1);
1504                         buffer_append(&b, method->name, strlen(method->name));
1505                 }
1506         }
1507         buffer_append(&b, "\0", 1);
1508         list = xstrdup(buffer_ptr(&b));
1509         buffer_free(&b);
1510         return list;
1511 }
This page took 0.155897 seconds and 5 git commands to generate.