This source file includes following definitions.
- sftpfs_open_socket
- sftpfs_read_known_hosts
- sftpfs_update_known_hosts
- sftpfs_compute_fingerprint_hash
- sftpfs_process_known_host
- sftpfs_recognize_auth_types
- sftpfs_open_connection_ssh_agent
- sftpfs_open_connection_ssh_key
- LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC
- sftpfs_open_connection_ssh_password
- sftpfs_open_connection
- sftpfs_close_connection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28 #include <errno.h>
29
30 #include <netdb.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36
37 #include <libssh2.h>
38 #include <libssh2_sftp.h>
39
40 #include "lib/global.h"
41
42 #include "lib/util.h"
43 #include "lib/tty/tty.h"
44 #include "lib/vfs/utilvfs.h"
45 #include "lib/mcconfig.h"
46 #include "lib/widget.h"
47
48 #include "internal.h"
49
50
51
52
53
54 #define SHA1_DIGEST_LENGTH 20
55
56
57
58
59
60
61
62 #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
63 static const char *const hostkey_method_ssh_ed25519 = "ssh-ed25519";
64 #endif
65 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
66 static const char *const hostkey_method_ssh_ecdsa_521 = "ecdsa-sha2-nistp521";
67 #endif
68 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
69 static const char *const hostkey_method_ssh_ecdsa_384 = "ecdsa-sha2-nistp384";
70 #endif
71 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
72 static const char *const hostkey_method_ssh_ecdsa_256 = "ecdsa-sha2-nistp256";
73 #endif
74 static const char *const hostkey_method_ssh_rsa = "ssh-rsa";
75 static const char *const hostkey_method_ssh_dss = "ssh-dss";
76
77 static const char *default_hostkey_methods =
78 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
79 "ecdsa-sha2-nistp256,"
80 #endif
81 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
82 "ecdsa-sha2-nistp384,"
83 #endif
84 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
85 "ecdsa-sha2-nistp521,"
86 #endif
87 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
88 "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
89 #endif
90 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
91 "ecdsa-sha2-nistp384-cert-v01@openssh.com,"
92 #endif
93 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
94 "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
95 #endif
96 #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
97 "ssh-ed25519,"
98 "ssh-ed25519-cert-v01@openssh.com,"
99 #endif
100 "rsa-sha2-256,"
101 "rsa-sha2-512,"
102 "ssh-rsa,"
103 "ssh-rsa-cert-v01@openssh.com,"
104 "ssh-dss";
105
106
107
108
109
110
111
112
113
114
115
116 static const char *kbi_passwd = NULL;
117 static const struct vfs_s_super *kbi_super = NULL;
118
119
120
121
122
123
124
125
126
127
128
129
130 static int
131 sftpfs_open_socket (struct vfs_s_super *super, GError **mcerror)
132 {
133 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
134 struct addrinfo hints, *res = NULL, *curr_res;
135 int my_socket = 0;
136 char port[BUF_TINY];
137 static char address_ipv4[INET_ADDRSTRLEN];
138 static char address_ipv6[INET6_ADDRSTRLEN];
139 int e;
140
141 mc_return_val_if_error (mcerror, LIBSSH2_INVALID_SOCKET);
142
143 if (super->path_element->host == NULL || *super->path_element->host == '\0')
144 {
145 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: Invalid host name."));
146 return LIBSSH2_INVALID_SOCKET;
147 }
148
149 sprintf (port, "%hu", (unsigned short) super->path_element->port);
150
151 tty_enable_interrupt_key ();
152
153 memset (&hints, 0, sizeof (hints));
154 hints.ai_family = AF_UNSPEC;
155 hints.ai_socktype = SOCK_STREAM;
156
157 #ifdef AI_ADDRCONFIG
158
159
160
161 hints.ai_flags = AI_ADDRCONFIG;
162 #endif
163
164 e = getaddrinfo (super->path_element->host, port, &hints, &res);
165
166 #ifdef AI_ADDRCONFIG
167 if (e == EAI_BADFLAGS)
168 {
169
170 hints.ai_flags = 0;
171 e = getaddrinfo (super->path_element->host, port, &hints, &res);
172 }
173 #endif
174
175 if (e != 0)
176 {
177 mc_propagate_error (mcerror, e, _ ("sftp: %s"), gai_strerror (e));
178 my_socket = LIBSSH2_INVALID_SOCKET;
179 goto ret;
180 }
181
182 for (curr_res = res; curr_res != NULL; curr_res = curr_res->ai_next)
183 {
184 int save_errno;
185
186 switch (curr_res->ai_addr->sa_family)
187 {
188 case AF_INET:
189 sftpfs_super->ip_address =
190 inet_ntop (AF_INET, &((struct sockaddr_in *) curr_res->ai_addr)->sin_addr,
191 address_ipv4, INET_ADDRSTRLEN);
192 break;
193 case AF_INET6:
194 sftpfs_super->ip_address =
195 inet_ntop (AF_INET6, &((struct sockaddr_in6 *) curr_res->ai_addr)->sin6_addr,
196 address_ipv6, INET6_ADDRSTRLEN);
197 break;
198 default:
199 sftpfs_super->ip_address = NULL;
200 }
201
202 if (sftpfs_super->ip_address == NULL)
203 {
204 mc_propagate_error (
205 mcerror, 0, "%s",
206 _ ("sftp: failed to convert remote host IP address into text form"));
207 my_socket = LIBSSH2_INVALID_SOCKET;
208 goto ret;
209 }
210
211 my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol);
212
213 if (my_socket < 0)
214 {
215 if (curr_res->ai_next != NULL)
216 continue;
217
218 vfs_print_message (_ ("sftp: %s"), unix_error_string (errno));
219 my_socket = LIBSSH2_INVALID_SOCKET;
220 goto ret;
221 }
222
223 vfs_print_message (_ ("sftp: making connection to %s"), super->path_element->host);
224
225 if (connect (my_socket, curr_res->ai_addr, curr_res->ai_addrlen) >= 0)
226 break;
227
228 save_errno = errno;
229
230 close (my_socket);
231
232 if (save_errno == EINTR && tty_got_interrupt ())
233 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: connection interrupted by user"));
234 else if (res->ai_next == NULL)
235 mc_propagate_error (mcerror, save_errno, _ ("sftp: connection to server failed: %s"),
236 unix_error_string (save_errno));
237 else
238 continue;
239
240 my_socket = LIBSSH2_INVALID_SOCKET;
241 break;
242 }
243
244 ret:
245 if (res != NULL)
246 freeaddrinfo (res);
247 tty_disable_interrupt_key ();
248 return my_socket;
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262 static gboolean
263 sftpfs_read_known_hosts (struct vfs_s_super *super, GError **mcerror)
264 {
265 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
266 struct libssh2_knownhost *store = NULL;
267 int rc;
268 gboolean found = FALSE;
269
270 sftpfs_super->known_hosts = libssh2_knownhost_init (sftpfs_super->session);
271 if (sftpfs_super->known_hosts == NULL)
272 goto err;
273
274 sftpfs_super->known_hosts_file =
275 mc_build_filename (mc_config_get_home_dir (), ".ssh", "known_hosts", (char *) NULL);
276
277 if (!exist_file (sftpfs_super->known_hosts_file))
278 {
279 mc_propagate_error (mcerror, 0, _ ("sftp: cannot open %s:\n%s"),
280 sftpfs_super->known_hosts_file, unix_error_string (errno));
281 return FALSE;
282 }
283
284 rc = libssh2_knownhost_readfile (sftpfs_super->known_hosts, sftpfs_super->known_hosts_file,
285 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
286 if (rc > 0)
287 {
288 const char *kh_name_end = NULL;
289
290 while (!found && libssh2_knownhost_get (sftpfs_super->known_hosts, &store, store) == 0)
291 {
292
293
294 if (store == NULL)
295 continue;
296
297 if (store->name == NULL)
298
299 continue;
300
301 if (store->name[0] != '[')
302 found = strcmp (store->name, super->path_element->host) == 0;
303 else
304 {
305 int port;
306
307 kh_name_end = strstr (store->name, "]:");
308 if (kh_name_end == NULL)
309
310 continue;
311
312 port = (int) g_ascii_strtoll (kh_name_end + 2, NULL, 10);
313 if (port == super->path_element->port)
314 {
315 size_t kh_name_size;
316
317 kh_name_size = strlen (store->name) - 1 - strlen (kh_name_end);
318 found = strncmp (store->name + 1, super->path_element->host, kh_name_size) == 0;
319 }
320 }
321 }
322 }
323
324 if (found)
325 {
326 int mask;
327 const char *hostkey_method = NULL;
328 char *hostkey_methods;
329
330 mask = store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
331
332 switch (mask)
333 {
334 #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
335 case LIBSSH2_KNOWNHOST_KEY_ED25519:
336 hostkey_method = hostkey_method_ssh_ed25519;
337 break;
338 #endif
339 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
340 case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
341 hostkey_method = hostkey_method_ssh_ecdsa_521;
342 break;
343 #endif
344 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
345 case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
346 hostkey_method = hostkey_method_ssh_ecdsa_384;
347 break;
348 #endif
349 #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
350 case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
351 hostkey_method = hostkey_method_ssh_ecdsa_256;
352 break;
353 #endif
354 case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
355 hostkey_method = hostkey_method_ssh_rsa;
356 break;
357 case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
358 hostkey_method = hostkey_method_ssh_dss;
359 break;
360 case LIBSSH2_KNOWNHOST_KEY_RSA1:
361 mc_propagate_error (mcerror, 0, "%s",
362 _ ("sftp: found host key of unsupported type: RSA1"));
363 return FALSE;
364 default:
365 mc_propagate_error (mcerror, 0, "%s 0x%x", _ ("sftp: unknown host key type:"),
366 (unsigned int) mask);
367 return FALSE;
368 }
369
370
371
372
373
374
375 hostkey_methods = g_strdup_printf ("%s,%s", hostkey_method, default_hostkey_methods);
376 rc = libssh2_session_method_pref (sftpfs_super->session, LIBSSH2_METHOD_HOSTKEY,
377 hostkey_methods);
378 g_free (hostkey_methods);
379 if (rc < 0)
380 goto err;
381 }
382
383 return TRUE;
384
385 err:
386 {
387 int sftp_errno;
388
389 sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
390 sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
391 }
392 return FALSE;
393 }
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408 static int
409 sftpfs_update_known_hosts (struct vfs_s_super *super, const char *remote_key, size_t remote_key_len,
410 int type_mask)
411 {
412 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
413 int rc;
414
415
416 rc = libssh2_knownhost_addc (sftpfs_super->known_hosts, super->path_element->host, NULL,
417 remote_key, remote_key_len, NULL, 0, type_mask, NULL);
418 if (rc < 0)
419 return rc;
420
421
422 rc = libssh2_knownhost_writefile (sftpfs_super->known_hosts, sftpfs_super->known_hosts_file,
423 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
424
425 if (rc < 0)
426 return rc;
427
428 (void) message (D_NORMAL, _ ("Information"),
429 _ ("Permanently added\n%s (%s)\nto the list of known hosts."),
430 super->path_element->host, sftpfs_super->ip_address);
431
432 return 0;
433 }
434
435
436
437
438
439
440
441
442 static const char *
443 sftpfs_compute_fingerprint_hash (LIBSSH2_SESSION *session)
444 {
445 static char result[SHA1_DIGEST_LENGTH * 3 + 1];
446 const char *fingerprint;
447 size_t i;
448
449
450 fingerprint = libssh2_hostkey_hash (session, LIBSSH2_HOSTKEY_HASH_SHA1);
451 if (fingerprint == NULL)
452 return NULL;
453
454 for (i = 0; i < SHA1_DIGEST_LENGTH && i * 3 < sizeof (result) - 1; i++)
455 g_snprintf ((gchar *) (result + i * 3), 4, "%02x:", (guint8) fingerprint[i]);
456
457
458 result[i * 3 - 1] = '\0';
459
460 return result;
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474 static gboolean
475 sftpfs_process_known_host (struct vfs_s_super *super, GError **mcerror)
476 {
477 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
478 const char *remote_key;
479 const char *key_type;
480 const char *fingerprint_hash;
481 size_t remote_key_len = 0;
482 int remote_key_type = LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
483 int keybit = 0;
484 struct libssh2_knownhost *host = NULL;
485 int rc;
486 char *msg = NULL;
487 gboolean handle_query = FALSE;
488
489 remote_key = libssh2_session_hostkey (sftpfs_super->session, &remote_key_len, &remote_key_type);
490 if (remote_key == NULL || remote_key_len == 0
491 || remote_key_type == LIBSSH2_HOSTKEY_TYPE_UNKNOWN)
492 {
493 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: cannot get the remote host key"));
494 return FALSE;
495 }
496
497 switch (remote_key_type)
498 {
499 case LIBSSH2_HOSTKEY_TYPE_RSA:
500 keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
501 key_type = "RSA";
502 break;
503 case LIBSSH2_HOSTKEY_TYPE_DSS:
504 keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
505 key_type = "DSS";
506 break;
507 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
508 case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
509 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
510 key_type = "ECDSA";
511 break;
512 #endif
513 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
514 case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
515 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
516 key_type = "ECDSA";
517 break;
518 #endif
519 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
520 case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
521 keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
522 key_type = "ECDSA";
523 break;
524 #endif
525 #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
526 case LIBSSH2_HOSTKEY_TYPE_ED25519:
527 keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
528 key_type = "ED25519";
529 break;
530 #endif
531 default:
532 mc_propagate_error (mcerror, 0, "%s",
533 _ ("sftp: unsupported key type, can't check remote host key"));
534 return FALSE;
535 }
536
537 fingerprint_hash = sftpfs_compute_fingerprint_hash (sftpfs_super->session);
538 if (fingerprint_hash == NULL)
539 {
540 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: can't compute host key fingerprint hash"));
541 return FALSE;
542 }
543
544 rc = libssh2_knownhost_checkp (
545 sftpfs_super->known_hosts, super->path_element->host, super->path_element->port, remote_key,
546 remote_key_len, LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW | keybit,
547 &host);
548
549 switch (rc)
550 {
551 default:
552 case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
553
554 goto err;
555
556 case LIBSSH2_KNOWNHOST_CHECK_MATCH:
557
558 break;
559
560 case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
561
562 msg = g_strdup_printf (
563 _ ("The authenticity of host\n%s (%s)\ncan't be established!\n"
564 "%s key fingerprint hash is\nSHA1:%s.\n"
565 "Do you want to add it to the list of known hosts and continue connecting?"),
566 super->path_element->host, sftpfs_super->ip_address, key_type, fingerprint_hash);
567
568 query_set_sel (2);
569 rc = query_dialog (_ ("Warning"), msg, D_NORMAL, 3, _ ("&Yes"), _ ("&Ignore"), _ ("&No"));
570 g_free (msg);
571 handle_query = TRUE;
572 break;
573
574 case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
575 msg = g_strdup_printf (_ ("%s (%s)\nis found in the list of known hosts but\n"
576 "KEYS DO NOT MATCH! THIS COULD BE A MITM ATTACK!\n"
577 "Are you sure you want to add it to the list of known hosts and "
578 "continue connecting?"),
579 super->path_element->host, sftpfs_super->ip_address);
580
581 query_set_sel (2);
582 rc = query_dialog (MSG_ERROR, msg, D_ERROR, 3, _ ("&Yes"), _ ("&Ignore"), _ ("&No"));
583 g_free (msg);
584 handle_query = TRUE;
585 break;
586 }
587
588 if (handle_query)
589 switch (rc)
590 {
591 case 0:
592
593 if (sftpfs_update_known_hosts (super, remote_key, remote_key_len,
594 LIBSSH2_KNOWNHOST_TYPE_PLAIN
595 | LIBSSH2_KNOWNHOST_KEYENC_RAW | keybit)
596 < 0)
597 goto err;
598 break;
599 case 1:
600
601 break;
602 case 2:
603 default:
604 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: host key verification failed"));
605
606 goto err;
607 }
608
609 return TRUE;
610
611 err:
612 {
613 int sftp_errno;
614
615 sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
616 sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
617 }
618
619 return FALSE;
620 }
621
622
623
624
625
626
627
628
629
630 static gboolean
631 sftpfs_recognize_auth_types (struct vfs_s_super *super)
632 {
633 char *userauthlist;
634 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
635
636
637
638 userauthlist = libssh2_userauth_list (sftpfs_super->session, super->path_element->user,
639 strlen (super->path_element->user));
640
641 if (userauthlist == NULL)
642 return FALSE;
643
644 if ((strstr (userauthlist, "password") != NULL
645 || strstr (userauthlist, "keyboard-interactive") != NULL)
646 && (sftpfs_super->config_auth_type & PASSWORD) != 0)
647 sftpfs_super->auth_type |= PASSWORD;
648
649 if (strstr (userauthlist, "publickey") != NULL
650 && (sftpfs_super->config_auth_type & PUBKEY) != 0)
651 sftpfs_super->auth_type |= PUBKEY;
652
653 if ((sftpfs_super->config_auth_type & AGENT) != 0)
654 sftpfs_super->auth_type |= AGENT;
655
656 return TRUE;
657 }
658
659
660
661
662
663
664
665
666
667
668 static gboolean
669 sftpfs_open_connection_ssh_agent (struct vfs_s_super *super, GError **mcerror)
670 {
671 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
672 struct libssh2_agent_publickey *identity, *prev_identity = NULL;
673 int rc;
674
675 mc_return_val_if_error (mcerror, FALSE);
676
677 sftpfs_super->agent = NULL;
678
679 if ((sftpfs_super->auth_type & AGENT) == 0)
680 return FALSE;
681
682
683 sftpfs_super->agent = libssh2_agent_init (sftpfs_super->session);
684 if (sftpfs_super->agent == NULL)
685 return FALSE;
686
687 if (libssh2_agent_connect (sftpfs_super->agent) != 0)
688 return FALSE;
689
690 if (libssh2_agent_list_identities (sftpfs_super->agent) != 0)
691 return FALSE;
692
693 while (TRUE)
694 {
695 rc = libssh2_agent_get_identity (sftpfs_super->agent, &identity, prev_identity);
696 if (rc == 1)
697 break;
698
699 if (rc < 0)
700 return FALSE;
701
702 if (libssh2_agent_userauth (sftpfs_super->agent, super->path_element->user, identity) == 0)
703 break;
704
705 prev_identity = identity;
706 }
707
708 return (rc == 0);
709 }
710
711
712
713
714
715
716
717
718
719
720 static gboolean
721 sftpfs_open_connection_ssh_key (struct vfs_s_super *super, GError **mcerror)
722 {
723 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
724 char *p, *passwd;
725 gboolean ret_value = FALSE;
726
727 mc_return_val_if_error (mcerror, FALSE);
728
729 if ((sftpfs_super->auth_type & PUBKEY) == 0)
730 return FALSE;
731
732 if (sftpfs_super->privkey == NULL)
733 return FALSE;
734
735 if (libssh2_userauth_publickey_fromfile (sftpfs_super->session, super->path_element->user,
736 sftpfs_super->pubkey, sftpfs_super->privkey,
737 super->path_element->password)
738 == 0)
739 return TRUE;
740
741 p = g_strdup_printf (_ ("sftp: Enter passphrase for %s "), super->path_element->user);
742 passwd = vfs_get_password (p);
743 g_free (p);
744
745 if (passwd == NULL)
746 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: Passphrase is empty."));
747 else
748 {
749 ret_value = (libssh2_userauth_publickey_fromfile (
750 sftpfs_super->session, super->path_element->user, sftpfs_super->pubkey,
751 sftpfs_super->privkey, passwd)
752 == 0);
753 g_free (passwd);
754 }
755
756 return ret_value;
757 }
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777 static LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC (sftpfs_keyboard_interactive_helper)
778 {
779 int i;
780 size_t len;
781
782 (void) instruction;
783 (void) instruction_len;
784 (void) abstract;
785
786 if (kbi_super == NULL || kbi_passwd == NULL)
787 return;
788
789 if (strncmp (name, kbi_super->path_element->user, name_len) != 0)
790 return;
791
792
793 len = strlen (kbi_passwd);
794
795 for (i = 0; i < num_prompts; ++i)
796 if (memcmp (prompts[i].text, "Password: ", prompts[i].length) == 0)
797 {
798 responses[i].text = strdup (kbi_passwd);
799 responses[i].length = len;
800 }
801 }
802
803
804
805
806
807
808
809
810
811
812 static gboolean
813 sftpfs_open_connection_ssh_password (struct vfs_s_super *super, GError **mcerror)
814 {
815 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
816 char *p, *passwd;
817 gboolean ret_value = FALSE;
818 int rc;
819
820 mc_return_val_if_error (mcerror, FALSE);
821
822 if ((sftpfs_super->auth_type & PASSWORD) == 0)
823 return FALSE;
824
825 if (super->path_element->password != NULL)
826 {
827 while ((rc = libssh2_userauth_password (sftpfs_super->session, super->path_element->user,
828 super->path_element->password))
829 == LIBSSH2_ERROR_EAGAIN)
830 ;
831 if (rc == 0)
832 return TRUE;
833
834 kbi_super = super;
835 kbi_passwd = super->path_element->password;
836
837 while ((rc = libssh2_userauth_keyboard_interactive (sftpfs_super->session,
838 super->path_element->user,
839 sftpfs_keyboard_interactive_helper))
840 == LIBSSH2_ERROR_EAGAIN)
841 ;
842
843 kbi_super = NULL;
844 kbi_passwd = NULL;
845
846 if (rc == 0)
847 return TRUE;
848 }
849
850 p = g_strdup_printf (_ ("sftp: Enter password for %s "), super->path_element->user);
851 passwd = vfs_get_password (p);
852 g_free (p);
853
854 if (passwd == NULL)
855 mc_propagate_error (mcerror, 0, "%s", _ ("sftp: Password is empty."));
856 else
857 {
858 while ((rc = libssh2_userauth_password (sftpfs_super->session, super->path_element->user,
859 passwd))
860 == LIBSSH2_ERROR_EAGAIN)
861 ;
862
863 if (rc != 0)
864 {
865 kbi_super = super;
866 kbi_passwd = passwd;
867
868 while ((rc = libssh2_userauth_keyboard_interactive (sftpfs_super->session,
869 super->path_element->user,
870 sftpfs_keyboard_interactive_helper))
871 == LIBSSH2_ERROR_EAGAIN)
872 ;
873
874 kbi_super = NULL;
875 kbi_passwd = NULL;
876 }
877
878 if (rc == 0)
879 {
880 ret_value = TRUE;
881 g_free (super->path_element->password);
882 super->path_element->password = passwd;
883 }
884 else
885 g_free (passwd);
886 }
887
888 return ret_value;
889 }
890
891
892
893
894
895
896
897
898
899
900
901
902 int
903 sftpfs_open_connection (struct vfs_s_super *super, GError **mcerror)
904 {
905 int rc;
906 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
907
908 mc_return_val_if_error (mcerror, -1);
909
910
911
912
913
914 sftpfs_super->socket_handle = sftpfs_open_socket (super, mcerror);
915 if (sftpfs_super->socket_handle == LIBSSH2_INVALID_SOCKET)
916 return (-1);
917
918
919 sftpfs_super->session = libssh2_session_init ();
920 if (sftpfs_super->session == NULL)
921 return (-1);
922
923 if (!sftpfs_read_known_hosts (super, mcerror))
924 return (-1);
925
926
927
928
929 while ((rc = libssh2_session_handshake (sftpfs_super->session,
930 (libssh2_socket_t) sftpfs_super->socket_handle))
931 == LIBSSH2_ERROR_EAGAIN)
932 ;
933 if (rc != 0)
934 {
935 mc_propagate_error (mcerror, rc, "%s", _ ("sftp: failure establishing SSH session"));
936 return (-1);
937 }
938
939 if (!sftpfs_process_known_host (super, mcerror))
940 return (-1);
941
942 if (!sftpfs_recognize_auth_types (super))
943 {
944 int sftp_errno;
945
946 sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
947 sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
948 return (-1);
949 }
950
951 if (!sftpfs_open_connection_ssh_agent (super, mcerror)
952 && !sftpfs_open_connection_ssh_key (super, mcerror)
953 && !sftpfs_open_connection_ssh_password (super, mcerror))
954 return (-1);
955
956 sftpfs_super->sftp_session = libssh2_sftp_init (sftpfs_super->session);
957
958 if (sftpfs_super->sftp_session == NULL)
959 return (-1);
960
961
962 libssh2_session_set_blocking (sftpfs_super->session, 1);
963
964 return 0;
965 }
966
967
968
969
970
971
972
973
974
975
976 void
977 sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_message, GError **mcerror)
978 {
979 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
980
981
982 (void) mcerror;
983
984 if (sftpfs_super->sftp_session != NULL)
985 {
986 libssh2_sftp_shutdown (sftpfs_super->sftp_session);
987 sftpfs_super->sftp_session = NULL;
988 }
989
990 if (sftpfs_super->agent != NULL)
991 {
992 libssh2_agent_disconnect (sftpfs_super->agent);
993 libssh2_agent_free (sftpfs_super->agent);
994 sftpfs_super->agent = NULL;
995 }
996
997 if (sftpfs_super->known_hosts != NULL)
998 {
999 libssh2_knownhost_free (sftpfs_super->known_hosts);
1000 sftpfs_super->known_hosts = NULL;
1001 }
1002
1003 MC_PTR_FREE (sftpfs_super->known_hosts_file);
1004
1005 if (sftpfs_super->session != NULL)
1006 {
1007 libssh2_session_disconnect (sftpfs_super->session, shutdown_message);
1008 libssh2_session_free (sftpfs_super->session);
1009 sftpfs_super->session = NULL;
1010 }
1011
1012 if (sftpfs_super->socket_handle != LIBSSH2_INVALID_SOCKET)
1013 {
1014 close (sftpfs_super->socket_handle);
1015 sftpfs_super->socket_handle = LIBSSH2_INVALID_SOCKET;
1016 }
1017 }
1018
1019