View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.sftp;
18  
19  import java.io.File;
20  import java.io.Serializable;
21  import java.time.Duration;
22  import java.util.Objects;
23  import java.util.stream.Stream;
24  
25  import org.apache.commons.vfs2.FileSystem;
26  import org.apache.commons.vfs2.FileSystemConfigBuilder;
27  import org.apache.commons.vfs2.FileSystemException;
28  import org.apache.commons.vfs2.FileSystemOptions;
29  
30  import com.jcraft.jsch.ConfigRepository;
31  import com.jcraft.jsch.UserInfo;
32  
33  /**
34   * The config builder for various SFTP configuration options.
35   */
36  public final class SftpFileSystemConfigBuilder extends FileSystemConfigBuilder {
37  
38      /**
39       * Proxy type.
40       */
41      public static final class ProxyType implements Serializable, Comparable<ProxyType> {
42  
43          /**
44           * serialVersionUID format is YYYYMMDD for the date of the last binary change.
45           */
46          private static final long serialVersionUID = 20101208L;
47  
48          /**
49           * The proxy type.
50           */
51          private final String proxyType;
52  
53          private ProxyType(final String proxyType) {
54              this.proxyType = proxyType;
55          }
56  
57          @Override
58          public int compareTo(final ProxyType pType) {
59              return proxyType.compareTo(pType.proxyType);
60          }
61  
62          @Override
63          public boolean equals(final Object obj) {
64              if (this == obj) {
65                  return true;
66              }
67              if (obj == null || this.getClass() != obj.getClass()) {
68                  return false;
69              }
70              return Objects.equals(proxyType, ((ProxyType) obj).proxyType);
71          }
72  
73          /**
74           * @return a hash code value for this object.
75           * @since 2.0
76           */
77          @Override
78          public int hashCode() {
79              return proxyType.hashCode();
80          }
81      }
82  
83      /** HTTP Proxy. */
84      public static final ProxyType PROXY_HTTP = new ProxyType("http");
85  
86      /** SOCKS Proxy. */
87      public static final ProxyType PROXY_SOCKS5 = new ProxyType("socks");
88  
89      /**
90       * Connects to the SFTP server through a remote host reached by SSH.
91       * <p>
92       * On this proxy host, a command (e.g. {@linkplain SftpStreamProxy#NETCAT_COMMAND} or
93       * {@linkplain SftpStreamProxy#NETCAT_COMMAND}) is run to forward input/output streams between the target host and
94       * the VFS host.
95       * </p>
96       * <p>
97       * When used, the proxy username ({@linkplain #setProxyUser}) and hostname ({@linkplain #setProxyHost}) <strong>must</strong>
98       * be set. Optionally, the command ({@linkplain #setProxyCommand}), password ({@linkplain #setProxyPassword}) and
99       * connection options ({@linkplain #setProxyOptions}) can be set.
100      * </p>
101      */
102     public static final ProxyType PROXY_STREAM = new ProxyType("stream");
103 
104     private static final Duration DEFAULT_CONNECT_TIMEOUT = Duration.ZERO;
105 
106     private static final Duration DEFAULT_SESSION_TIMEOUT = Duration.ZERO;
107 
108     private static final String PREFIX = SftpFileSystemConfigBuilder.class.getName();
109     private static final SftpFileSystemConfigBuilder BUILDER = new SftpFileSystemConfigBuilder();
110     private static final String COMPRESSION = PREFIX + "COMPRESSION";
111     private static final String CONNECT_TIMEOUT = PREFIX + ".CONNECT_TIMEOUT";
112     private static final String ENCODING = PREFIX + ".ENCODING";
113     private static final String HOST_KEY_CHECK_ASK = "ask";
114     private static final String HOST_KEY_CHECK_NO = "no";
115     private static final String HOST_KEY_CHECK_YES = "yes";
116     private static final String IDENTITIES = PREFIX + ".IDENTITIES";
117     private static final String IDENTITY_REPOSITORY_FACTORY = PREFIX + "IDENTITY_REPOSITORY_FACTORY";
118     private static final String CONFIG_REPOSITORY = PREFIX + "CONFIG_REPOSITORY";
119     private static final String KEY_EXCHANGE_ALGORITHM = PREFIX + ".KEY_EXCHANGE_ALGORITHM";
120     private static final String LOAD_OPENSSH_CONFIG = PREFIX + "LOAD_OPENSSH_CONFIG";
121     private static final String KNOWN_HOSTS = PREFIX + ".KNOWN_HOSTS";
122     private static final String PREFERRED_AUTHENTICATIONS = PREFIX + ".PREFERRED_AUTHENTICATIONS";
123     private static final String PROXY_COMMAND = PREFIX + ".PROXY_COMMAND";
124     private static final String PROXY_HOST = PREFIX + ".PROXY_HOST";
125     private static final String PROXY_OPTIONS = PREFIX + ".PROXY_OPTIONS";
126     private static final String PROXY_PASSWORD = PREFIX + ".PROXY_PASSWORD";
127     private static final String PROXY_PORT = PREFIX + ".PROXY_PORT";
128     private static final String DISABLE_DETECT_EXEC_CHANNEL = PREFIX + ".DISABLE_DETECT_EXEC_CHANNEL";
129 
130     private static final String PROXY_TYPE = PREFIX + ".PROXY_TYPE";
131     private static final String PROXY_USER = PREFIX + ".PROXY_USER";
132     private static final String SESSION_TIMEOUT = PREFIX + ".TIMEOUT";
133     private static final String STRICT_HOST_KEY_CHECKING = PREFIX + ".STRICT_HOST_KEY_CHECKING";
134     private static final String USER_DIR_IS_ROOT = PREFIX + ".USER_DIR_IS_ROOT";
135 
136     /**
137      * Gets the singleton builder.
138      *
139      * @return the singleton builder.
140      */
141     public static SftpFileSystemConfigBuilder getInstance() {
142         return BUILDER;
143     }
144 
145     private SftpFileSystemConfigBuilder() {
146         super("sftp.");
147     }
148 
149     /**
150      * Gets the names of the compression algorithms, comma-separated.
151      *
152      * @param options The FileSystem options.
153      * @return The names of the compression algorithms, comma-separated.
154      * @see #setCompression
155      */
156     public String getCompression(final FileSystemOptions options) {
157         return this.getString(options, COMPRESSION);
158     }
159 
160     @Override
161     protected Class<? extends FileSystem> getConfigClass() {
162         return SftpFileSystem.class;
163     }
164 
165     /**
166      * Gets the config repository.
167      *
168      * @param options The FileSystem options.
169      * @return the ConfigRepository
170      */
171     public ConfigRepository getConfigRepository(final FileSystemOptions options) {
172         return getParam(options, CONFIG_REPOSITORY);
173     }
174 
175     /**
176      * Gets the connect timeout duration.
177      *
178      * @param options The FileSystem options.
179      * @return The connect timeout duration.
180      * @see #setConnectTimeoutMillis
181      * @since 2.8.0
182      */
183     public Duration getConnectTimeout(final FileSystemOptions options) {
184         return this.getDuration(options, CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT);
185     }
186 
187     /**
188      * Gets the connect timeout duration.
189      *
190      * @param options The FileSystem options.
191      * @return The connect timeout value in milliseconds.
192      * @see #setConnectTimeoutMillis
193      * @since 2.3
194      * @deprecated Use {@link #getConnectTimeout(FileSystemOptions)}.
195      */
196     @Deprecated
197     public Integer getConnectTimeoutMillis(final FileSystemOptions options) {
198         return this.getDurationInteger(options, CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT);
199     }
200 
201     /**
202      * Gets the file name encoding.
203      *
204      * @param options The FileSystem options.
205      * @return the file name encoding
206      */
207     public String getFileNameEncoding(final FileSystemOptions options) {
208         return this.getString(options, ENCODING);
209     }
210 
211     /**
212      * Gets the identity files (your private key files).
213      * <p>
214      * We use java.io.File because JSch cannot deal with VFS FileObjects.
215      * </p>
216      *
217      * @param options The FileSystem options.
218      * @return the array of identity Files.
219      * @see #setIdentities
220      * @deprecated As of 2.1 use {@link #getIdentityInfo(FileSystemOptions)}
221      */
222     @Deprecated
223     public File[] getIdentities(final FileSystemOptions options) {
224         final IdentityInfo[] info = getIdentityInfo(options);
225         if (info != null) {
226             return Stream.of(info).map(IdentityInfo::getPrivateKey).toArray(File[]::new);
227         }
228         return null;
229     }
230 
231     /**
232      * Gets the identity infos.
233      *
234      * @param options The FileSystem options.
235      * @return the array of identity info.
236      * @see #setIdentityInfo
237      */
238     public IdentityInfo[] getIdentityInfo(final FileSystemOptions options) {
239         final IdentityProvider[] infos = getIdentityProvider(options);
240         if (infos != null) {
241             return Stream.of(infos).filter(IdentityInfo.class::isInstance).map(info -> (IdentityInfo) info).toArray(IdentityInfo[]::new);
242         }
243         return null;
244     }
245 
246     /**
247      * Gets the identity providers.
248      *
249      * @param options The FileSystem options.
250      * @return the array of identity providers.
251      * @see #setIdentityProvider
252      * @since 2.4
253      */
254     public IdentityProvider[] getIdentityProvider(final FileSystemOptions options) {
255         return getParam(options, IDENTITIES);
256     }
257 
258     /**
259      * Gets the identity repository factory.
260      *
261      * @param options The FileSystem options.
262      * @return the IdentityRepositoryFactory
263      */
264     public IdentityRepositoryFactory getIdentityRepositoryFactory(final FileSystemOptions options) {
265         return getParam(options, IDENTITY_REPOSITORY_FACTORY);
266     }
267 
268     /**
269      * Gets the option value for specific key exchange algorithm.
270      *
271      * @param options The FileSystem options.
272      * @return the option value for specific key exchange algorithm.
273      * @see #setKeyExchangeAlgorithm(FileSystemOptions, String)
274      * @since 2.4
275      */
276     public String getKeyExchangeAlgorithm(final FileSystemOptions options) {
277         return this.getString(options, KEY_EXCHANGE_ALGORITHM);
278     }
279 
280     /**
281      * Gets the known hosts File.
282      *
283      * @param options The FileSystem options.
284      * @return the known hosts File.
285      * @see #setKnownHosts
286      */
287     public File getKnownHosts(final FileSystemOptions options) {
288         return getParam(options, KNOWN_HOSTS);
289     }
290 
291     /**
292      * Gets authentication order.
293      *
294      * @param options The FileSystem options.
295      * @return The authentication order.
296      * @since 2.0
297      */
298     public String getPreferredAuthentications(final FileSystemOptions options) {
299         return getString(options, PREFERRED_AUTHENTICATIONS);
300     }
301 
302     /**
303      * Gets the command that will be run on the proxy host when using a {@linkplain SftpStreamProxy}. The command
304      * defaults to {@linkplain SftpStreamProxy#NETCAT_COMMAND}.
305      *
306      * @param options The FileSystem options.
307      * @return proxyOptions
308      * @see SftpStreamProxy
309      * @see #setProxyOptions
310      * @since 2.1
311      */
312     public String getProxyCommand(final FileSystemOptions options) {
313         return this.getString(options, PROXY_COMMAND, SftpStreamProxy.NETCAT_COMMAND);
314     }
315 
316     /**
317      * Gets the proxy to use for the SFTP connection.
318      *
319      * @param options The FileSystem options.
320      * @return proxyHost
321      * @see #getProxyPort
322      * @see #setProxyHost
323      */
324     public String getProxyHost(final FileSystemOptions options) {
325         return this.getString(options, PROXY_HOST);
326     }
327 
328     /**
329      * Gets the proxy options that are used to connect to the proxy host.
330      *
331      * @param options The FileSystem options.
332      * @return proxyOptions
333      * @see SftpStreamProxy
334      * @see #setProxyOptions
335      * @since 2.1
336      */
337     public FileSystemOptions getProxyOptions(final FileSystemOptions options) {
338         return getParam(options, PROXY_OPTIONS);
339     }
340 
341     /**
342      * Gets the proxy password that are used to connect to the proxy host.
343      *
344      * @param options The FileSystem options.
345      * @return proxyOptions
346      * @see SftpStreamProxy
347      * @see #setProxyPassword
348      * @since 2.1
349      */
350     public String getProxyPassword(final FileSystemOptions options) {
351         return this.getString(options, PROXY_PASSWORD);
352     }
353 
354     /**
355      * Gets the proxy-port to use for the SFTP the connection.
356      *
357      * @param options The FileSystem options.
358      * @return proxyPort: the port number or 0 if it is not set
359      * @see #setProxyPort
360      * @see #getProxyHost
361      */
362     public int getProxyPort(final FileSystemOptions options) {
363         return this.getInteger(options, PROXY_PORT, 0);
364     }
365 
366     /**
367      * Gets the proxy type to use for the SFTP connection.
368      *
369      * @param options The FileSystem options.
370      * @return The ProxyType.
371      */
372     public ProxyType getProxyType(final FileSystemOptions options) {
373         return getParam(options, PROXY_TYPE);
374     }
375 
376     /**
377      * Gets the user name for the proxy used for the SFTP connection.
378      *
379      * @param options The FileSystem options.
380      * @return proxyUser
381      * @see #setProxyUser
382      * @since 2.1
383      */
384     public String getProxyUser(final FileSystemOptions options) {
385         return this.getString(options, PROXY_USER);
386     }
387 
388     /**
389      * Gets the session timeout value in milliseconds.
390      *
391      * @param options The FileSystem options.
392      * @return The session timeout value in milliseconds.
393      * @see #setSessionTimeout
394      * @since 2.3
395      */
396     public Duration getSessionTimeout(final FileSystemOptions options) {
397         return this.getDuration(options, SESSION_TIMEOUT, DEFAULT_SESSION_TIMEOUT);
398     }
399 
400     /**
401      * Gets the session timeout value in milliseconds.
402      *
403      * @param options The FileSystem options.
404      * @return The session timeout value in milliseconds.
405      * @see #setSessionTimeoutMillis
406      * @since 2.3
407      * @deprecated Use {@link #getSessionTimeout(FileSystemOptions)}.
408      */
409     @Deprecated
410     public Integer getSessionTimeoutMillis(final FileSystemOptions options) {
411         return this.getDurationInteger(options, SESSION_TIMEOUT, DEFAULT_SESSION_TIMEOUT);
412     }
413 
414     /**
415      * Gets the option value The host key checking.
416      *
417      * @param options The FileSystem options.
418      * @return the option value The host key checking.
419      * @see #setStrictHostKeyChecking(FileSystemOptions, String)
420      */
421     public String getStrictHostKeyChecking(final FileSystemOptions options) {
422         return this.getString(options, STRICT_HOST_KEY_CHECKING, HOST_KEY_CHECK_NO);
423     }
424 
425     /**
426      * Gets the timeout value in milliseconds.
427      *
428      * @param options The FileSystem options.
429      * @return The timeout value in milliseconds.
430      * @see #setTimeout
431      * @deprecated Use {@link #getSessionTimeoutMillis(FileSystemOptions)}
432      */
433     @Deprecated
434     public Integer getTimeout(final FileSystemOptions options) {
435         return this.getInteger(options, SESSION_TIMEOUT);
436     }
437 
438     /**
439      * Gets {@link Boolean#TRUE} if VFS should treat the user directory as the root directory. Defaults to
440      * {@code Boolean.TRUE} if the method {@link #setUserDirIsRoot(FileSystemOptions, boolean)} has not been
441      * invoked.
442      *
443      * @param options The FileSystemOptions.
444      * @return {@code Boolean.TRUE} if VFS treats the user directory as the root directory.
445      * @see #setUserDirIsRoot
446      */
447     public Boolean getUserDirIsRoot(final FileSystemOptions options) {
448         return this.getBoolean(options, USER_DIR_IS_ROOT, Boolean.TRUE);
449     }
450 
451     /**
452      * Gets the UserInfo.
453      *
454      * @param options The FileSystem options.
455      * @return The UserInfo.
456      * @see #setUserInfo
457      */
458     public UserInfo getUserInfo(final FileSystemOptions options) {
459         return getParam(options, UserInfo.class.getName());
460     }
461 
462     /**
463      * Returns {@code true} if the detection of the exec channel should be disabled.
464      * Returns {@code false} if the detection of the exec channel should be enabled.
465      * Defaults to {@code false} if the method {@link #setDisableDetectExecChannel(FileSystemOptions, boolean)} has not been invoked.
466      *
467      * @param options The FileSystemOptions.
468      * @return {@code true} if detection of exec channel should be disabled.
469      * @see #setDisableDetectExecChannel(FileSystemOptions, boolean)
470      * @since 2.7.0
471      */
472     public boolean isDisableDetectExecChannel(final FileSystemOptions options) {
473         return this.getBoolean(options, DISABLE_DETECT_EXEC_CHANNEL, Boolean.FALSE);
474     }
475 
476     /**
477      * Returns {@link Boolean#TRUE} if VFS should load the OpenSSH config. Defaults to {@code Boolean.FALSE} if the
478      * method {@link #setLoadOpenSSHConfig(FileSystemOptions, boolean)} has not been invoked.
479      *
480      * @param options The FileSystemOptions.
481      * @return {@code Boolean.TRUE} if VFS should load the OpenSSH config.
482      * @see #setLoadOpenSSHConfig
483      */
484     public boolean isLoadOpenSSHConfig(final FileSystemOptions options) {
485         return this.getBoolean(options, LOAD_OPENSSH_CONFIG, Boolean.FALSE);
486     }
487 
488     /**
489      * Configures the compression algorithms to use.
490      * <p>
491      * For example, use {@code "zlib,none"} to enable compression.
492      * </p>
493      * <p>
494      * See the Jsch documentation (in particular the README file) for details.
495      * </p>
496      *
497      * @param options        The FileSystem options.
498      * @param compression The names of the compression algorithms, comma-separated.
499      */
500     public void setCompression(final FileSystemOptions options, final String compression) {
501         this.setParam(options, COMPRESSION, compression);
502     }
503 
504     /**
505      * Sets the config repository. e.g. {@code /home/user/.ssh/config}.
506      * <p>
507      * This is useful when you want to use OpenSSHConfig.
508      * </p>
509      *
510      * @param options             The FileSystem options.
511      * @param configRepository An config repository.
512      * @see <a href="http://www.jcraft.com/jsch/examples/OpenSSHConfig.java.html">OpenSSHConfig</a>
513      */
514     public void setConfigRepository(final FileSystemOptions options, final ConfigRepository configRepository) {
515         this.setParam(options, CONFIG_REPOSITORY, configRepository);
516     }
517 
518     /**
519      * Sets the timeout value to create a Jsch connection.
520      *
521      * @param options    The FileSystem options.
522      * @param timeout The connect timeout in milliseconds.
523      * @since 2.8.0
524      */
525     public void setConnectTimeout(final FileSystemOptions options, final Duration timeout) {
526         this.setParam(options, CONNECT_TIMEOUT, timeout);
527     }
528 
529     /**
530      * Sets the timeout value to create a Jsch connection.
531      *
532      * @param options    The FileSystem options.
533      * @param timeout The connect timeout in milliseconds.
534      * @since 2.3
535      * @deprecated Use {@link #setConnectTimeout(FileSystemOptions, Duration)}.
536      */
537     @Deprecated
538     public void setConnectTimeoutMillis(final FileSystemOptions options, final Integer timeout) {
539         setConnectTimeout(options, Duration.ofMillis(timeout));
540     }
541 
542     /**
543      * Sets whether detection of exec channel is disabled.
544      * If this value is true the FileSystem will not test if the server allows to exec commands and disable the use of the exec channel.
545      *
546      * @param options        The FileSystem options.
547      * @param disableDetectExecChannel true if the detection of exec channel should be disabled.
548      * @since 2.7.0
549      */
550     public void setDisableDetectExecChannel(final FileSystemOptions options, final boolean disableDetectExecChannel) {
551         this.setParam(options, DISABLE_DETECT_EXEC_CHANNEL, toBooleanObject(disableDetectExecChannel));
552     }
553 
554     /**
555      * Sets the file name encoding.
556      *
557      * @param options             The FileSystem options.
558      * @param fileNameEncoding The name of the encoding to use for file names.
559      */
560     public void setFileNameEncoding(final FileSystemOptions options, final String fileNameEncoding) {
561         this.setParam(options, ENCODING, fileNameEncoding);
562     }
563 
564     /**
565      * Sets the identity files (your private key files).
566      * <p>
567      * We use {@link File} because JSch cannot deal with VFS FileObjects.
568      * </p>
569      *
570      * @param options          The FileSystem options.
571      * @param identityFiles An array of identity Files.
572      * @deprecated As of 2.1 use {@link #setIdentityInfo(FileSystemOptions, IdentityInfo...)}
573      */
574     @Deprecated
575     public void setIdentities(final FileSystemOptions options, final File... identityFiles) {
576         IdentityProvider[] info = null;
577         if (identityFiles != null) {
578             info = Stream.of(identityFiles).filter(Objects::nonNull).filter(Objects::nonNull).map(IdentityInfo::new).toArray(IdentityProvider[]::new);
579         }
580         this.setParam(options, IDENTITIES, info);
581     }
582 
583     /**
584      * Sets the identity info (your private key files).
585      *
586      * @param options      The FileSystem options.
587      * @param identities An array of identity info.
588      * @since 2.1
589      * @deprecated Use {@link #setIdentityProvider(FileSystemOptions,IdentityProvider...)}
590      */
591     @Deprecated
592     public void setIdentityInfo(final FileSystemOptions options, final IdentityInfo... identities) {
593         this.setParam(options, IDENTITIES, identities);
594     }
595 
596     /**
597      * Sets the identity info (your private key files).
598      *
599      * @param options      The FileSystem options.
600      * @param identities An array of identity info.
601      * @since 2.4
602      */
603     public void setIdentityProvider(final FileSystemOptions options, final IdentityProvider... identities) {
604         this.setParam(options, IDENTITIES, identities);
605     }
606 
607     /**
608      * Sets the identity repository.
609      * <p>
610      * This is useful when you want to use e.g. an SSH agent as provided.
611      * </p>
612      *
613      * @param options    The FileSystem options.
614      * @param factory An identity repository.
615      * @see <a href="http://www.jcraft.com/jsch-agent-proxy/">JSch agent proxy</a>
616      */
617     public void setIdentityRepositoryFactory(final FileSystemOptions options, final IdentityRepositoryFactory factory) {
618         this.setParam(options, IDENTITY_REPOSITORY_FACTORY, factory);
619     }
620 
621     /**
622      * Configures Key exchange algorithm explicitly e.g. diffie-hellman-group14-sha1,
623      * diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1.
624      *
625      * @param options                The FileSystem options.
626      * @param keyExchangeAlgorithm The key exchange algorithm picked.
627      * @since 2.4
628      */
629     public void setKeyExchangeAlgorithm(final FileSystemOptions options, final String keyExchangeAlgorithm) {
630         setParam(options, KEY_EXCHANGE_ALGORITHM, keyExchangeAlgorithm);
631     }
632 
633     /**
634      * Sets the known_hosts file. e.g. {@code /home/user/.ssh/known_hosts2}.
635      * <p>
636      * We use {@link File} because JSch cannot deal with VFS FileObjects.
637      * </p>
638      *
639      * @param options       The FileSystem options.
640      * @param knownHosts The known hosts file.
641      */
642     public void setKnownHosts(final FileSystemOptions options, final File knownHosts) {
643         this.setParam(options, KNOWN_HOSTS, knownHosts);
644     }
645 
646     /**
647      * Sets the whether to load OpenSSH config.
648      *
649      * @param options              The FileSystem options.
650      * @param loadOpenSSHConfig true if the OpenSSH config should be loaded.
651      */
652     public void setLoadOpenSSHConfig(final FileSystemOptions options, final boolean loadOpenSSHConfig) {
653         this.setParam(options, LOAD_OPENSSH_CONFIG, toBooleanObject(loadOpenSSHConfig));
654     }
655 
656     /**
657      * Configures authentication order.
658      *
659      * @param options                     The FileSystem options.
660      * @param preferredAuthentications The authentication order.
661      * @since 2.0
662      */
663     public void setPreferredAuthentications(final FileSystemOptions options, final String preferredAuthentications) {
664         this.setParam(options, PREFERRED_AUTHENTICATIONS, preferredAuthentications);
665     }
666 
667     /**
668      * Sets the proxy username to use for the SFTP connection.
669      *
670      * @param options         The FileSystem options.
671      * @param proxyCommand the port
672      * @see #getProxyOptions
673      * @since 2.1
674      */
675     public void setProxyCommand(final FileSystemOptions options, final String proxyCommand) {
676         this.setParam(options, PROXY_COMMAND, proxyCommand);
677     }
678 
679     /**
680      * Sets the proxy to use for the SFTP connection.
681      *
682      * You MUST also set the proxy port to use the proxy.
683      *
684      * @param options      The FileSystem options.
685      * @param proxyHost the host
686      * @see #setProxyPort
687      */
688     public void setProxyHost(final FileSystemOptions options, final String proxyHost) {
689         this.setParam(options, PROXY_HOST, proxyHost);
690     }
691 
692     /**
693      * Sets the proxy username to use for the SFTP connection.
694      *
695      * @param options         The FileSystem options.
696      * @param proxyOptions the options
697      * @see #getProxyOptions
698      * @since 2.1
699      */
700     public void setProxyOptions(final FileSystemOptions options, final FileSystemOptions proxyOptions) {
701         this.setParam(options, PROXY_OPTIONS, proxyOptions);
702     }
703 
704     /**
705      * Sets the proxy password to use for the SFTP connection.
706      *
707      * @param options          The FileSystem options.
708      * @param proxyPassword the username used to connect to the proxy
709      * @see #getProxyPassword
710      * @since 2.1
711      */
712     public void setProxyPassword(final FileSystemOptions options, final String proxyPassword) {
713         this.setParam(options, PROXY_PASSWORD, proxyPassword);
714     }
715 
716     /**
717      * Sets the proxy port to use for the SFTP connection.
718      * <p>
719      * You MUST also set the proxy host to use the proxy.
720      * </p>
721      *
722      * @param options      The FileSystem options.
723      * @param proxyPort the port
724      * @see #setProxyHost
725      */
726     public void setProxyPort(final FileSystemOptions options, final int proxyPort) {
727         this.setParam(options, PROXY_PORT, Integer.valueOf(proxyPort));
728     }
729 
730     /**
731      * Sets the proxy type to use for the SFTP connection.
732      * <p>
733      * The possibles values are:
734      * </p>
735      * <ul>
736      * <li>{@linkplain #PROXY_HTTP} connects using an HTTP proxy</li>
737      * <li>{@linkplain #PROXY_SOCKS5} connects using an Socket5 proxy</li>
738      * <li>{@linkplain #PROXY_STREAM} connects through a remote host stream command</li>
739      * </ul>
740      *
741      * @param options      The FileSystem options.
742      * @param proxyType the type of the proxy to use.
743      */
744     public void setProxyType(final FileSystemOptions options, final ProxyType proxyType) {
745         this.setParam(options, PROXY_TYPE, proxyType);
746     }
747 
748     /**
749      * Sets the proxy username to use for the SFTP connection.
750      *
751      * @param options      The FileSystem options.
752      * @param proxyUser the username used to connect to the proxy
753      * @see #getProxyUser
754      * @since 2.1
755      */
756     public void setProxyUser(final FileSystemOptions options, final String proxyUser) {
757         this.setParam(options, PROXY_USER, proxyUser);
758     }
759 
760     /**
761      * Sets the timeout value on Jsch session.
762      *
763      * @param options    The FileSystem options.
764      * @param timeout The session timeout in milliseconds.
765      * @since 2.8.0
766      */
767     public void setSessionTimeout(final FileSystemOptions options, final Duration timeout) {
768         this.setParam(options, SESSION_TIMEOUT, timeout);
769     }
770 
771     /**
772      * Sets the timeout value on Jsch session.
773      *
774      * @param options    The FileSystem options.
775      * @param timeout The session timeout in milliseconds.
776      * @since 2.3
777      * @deprecated Use {@link #setSessionTimeout(FileSystemOptions, Duration)}.
778      */
779     @Deprecated
780     public void setSessionTimeoutMillis(final FileSystemOptions options, final Integer timeout) {
781         setSessionTimeout(options, Duration.ofMillis(timeout));
782     }
783 
784     /**
785      * Configures the host key checking to use.
786      * <p>
787      * Valid arguments are: {@code "yes"}, {@code "no"} and {@code "ask"}.
788      * </p>
789      * <p>
790      * See the jsch documentation for details.
791      * </p>
792      *
793      * @param options            The FileSystem options.
794      * @param hostKeyChecking The host key checking to use.
795      * @throws FileSystemException if an error occurs.
796      */
797     public void setStrictHostKeyChecking(final FileSystemOptions options, final String hostKeyChecking)
798             throws FileSystemException {
799         if (hostKeyChecking == null || !hostKeyChecking.equals(HOST_KEY_CHECK_ASK)
800                 && !hostKeyChecking.equals(HOST_KEY_CHECK_NO) && !hostKeyChecking.equals(HOST_KEY_CHECK_YES)) {
801             throw new FileSystemException("vfs.provider.sftp/StrictHostKeyChecking-arg.error", hostKeyChecking);
802         }
803 
804         this.setParam(options, STRICT_HOST_KEY_CHECKING, hostKeyChecking);
805     }
806 
807     /**
808      * Sets the timeout value on Jsch session.
809      *
810      * @param options    The FileSystem options.
811      * @param timeout The timeout in milliseconds.
812      * @deprecated Use {@link #setSessionTimeout(FileSystemOptions, Duration)}
813      */
814     @Deprecated
815     public void setTimeout(final FileSystemOptions options, final Integer timeout) {
816         this.setParam(options, SESSION_TIMEOUT, timeout);
817     }
818 
819     /**
820      * Sets the whether to use the user directory as root (do not change to file system root).
821      *
822      * @param options          The FileSystem options.
823      * @param userDirIsRoot true if the user directory is the root directory.
824      */
825     public void setUserDirIsRoot(final FileSystemOptions options, final boolean userDirIsRoot) {
826         this.setParam(options, USER_DIR_IS_ROOT, toBooleanObject(userDirIsRoot));
827     }
828 
829     /**
830      * Sets the Jsch UserInfo class to use.
831      *
832      * @param options The FileSystem options.
833      * @param info User information.
834      */
835     public void setUserInfo(final FileSystemOptions options, final UserInfo info) {
836         this.setParam(options, UserInfo.class.getName(), info);
837     }
838 
839 }