001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.vfs2.provider.sftp; 018 019import java.io.File; 020import java.io.Serializable; 021 022import org.apache.commons.vfs2.FileSystem; 023import org.apache.commons.vfs2.FileSystemConfigBuilder; 024import org.apache.commons.vfs2.FileSystemException; 025import org.apache.commons.vfs2.FileSystemOptions; 026 027import com.jcraft.jsch.UserInfo; 028 029/** 030 * The config builder for various SFTP configuration options. 031 */ 032public final class SftpFileSystemConfigBuilder extends FileSystemConfigBuilder { 033 /** 034 * Proxy type. 035 */ 036 public static final class ProxyType implements Serializable, Comparable<ProxyType> { 037 /** 038 * serialVersionUID format is YYYYMMDD for the date of the last binary change. 039 */ 040 private static final long serialVersionUID = 20101208L; 041 042 private final String proxyType; 043 044 private ProxyType(final String proxyType) { 045 this.proxyType = proxyType; 046 } 047 048 @Override 049 public int compareTo(final ProxyType pType) { 050 return this.proxyType.compareTo(pType.proxyType); 051 } 052 053 @Override 054 public boolean equals(final Object obj) { 055 if (this == obj) { 056 return true; 057 } 058 if (obj == null || this.getClass() != obj.getClass()) { 059 return false; 060 } 061 062 final ProxyType pType = (ProxyType) obj; 063 064 if (this.proxyType != null ? !this.proxyType.equals(pType.proxyType) : pType.proxyType != null) { 065 return false; 066 } 067 068 return true; 069 } 070 071 /** 072 * @return a hash code value for this object. 073 * @since 2.0 074 */ 075 @Override 076 public int hashCode() { 077 return this.proxyType.hashCode(); 078 } 079 } 080 081 /** HTTP Proxy. */ 082 public static final ProxyType PROXY_HTTP = new ProxyType("http"); 083 084 /** SOCKS Proxy. */ 085 public static final ProxyType PROXY_SOCKS5 = new ProxyType("socks"); 086 087 /** 088 * Connects to the SFTP server through a remote host reached by SSH. 089 * <p> 090 * On this proxy host, a command (e.g. {@linkplain SftpStreamProxy#NETCAT_COMMAND} or 091 * {@linkplain SftpStreamProxy#NETCAT_COMMAND}) is run to forward input/output streams between the target host and 092 * the VFS host. 093 * <p> 094 * When used, the proxy username ({@linkplain #setProxyUser}) and hostname ({@linkplain #setProxyHost}) <b>must</b> 095 * be set. Optionnaly, the command ({@linkplain #setProxyCommand}), password ({@linkplain #setProxyPassword}) and 096 * connection options ({@linkplain #setProxyOptions}) can be set. 097 */ 098 public static final ProxyType PROXY_STREAM = new ProxyType("stream"); 099 100 private static final String _PREFIX = SftpFileSystemConfigBuilder.class.getName(); 101 private static final SftpFileSystemConfigBuilder BUILDER = new SftpFileSystemConfigBuilder(); 102 private static final String COMPRESSION = _PREFIX + "COMPRESSION"; 103 private static final String HOST_KEY_CHECK_ASK = "ask"; 104 private static final String HOST_KEY_CHECK_NO = "no"; 105 private static final String HOST_KEY_CHECK_YES = "yes"; 106 private static final String IDENTITIES = _PREFIX + ".IDENTITIES"; 107 private static final String IDENTITY_REPOSITORY_FACTORY = _PREFIX + "IDENTITY_REPOSITORY_FACTORY"; 108 private static final String KNOWN_HOSTS = _PREFIX + ".KNOWN_HOSTS"; 109 private static final String PREFERRED_AUTHENTICATIONS = _PREFIX + ".PREFERRED_AUTHENTICATIONS"; 110 111 private static final String PROXY_HOST = _PREFIX + ".PROXY_HOST"; 112 private static final String PROXY_USER = _PREFIX + ".PROXY_USER"; 113 private static final String PROXY_OPTIONS = _PREFIX + ".PROXY_OPTIONS"; 114 private static final String PROXY_TYPE = _PREFIX + ".PROXY_TYPE"; 115 private static final String PROXY_PORT = _PREFIX + ".PROXY_PORT"; 116 private static final String PROXY_PASSWORD = _PREFIX + ".PROXY_PASSWORD"; 117 private static final String PROXY_COMMAND = _PREFIX + ".PROXY_COMMAND"; 118 119 private static final String STRICT_HOST_KEY_CHECKING = _PREFIX + ".STRICT_HOST_KEY_CHECKING"; 120 private static final String TIMEOUT = _PREFIX + ".TIMEOUT"; 121 private static final String USER_DIR_IS_ROOT = _PREFIX + ".USER_DIR_IS_ROOT"; 122 private static final String ENCODING = _PREFIX + ".ENCODING"; 123 124 private SftpFileSystemConfigBuilder() { 125 super("sftp."); 126 } 127 128 /** 129 * Gets the singleton builder. 130 * 131 * @return the singleton builder. 132 */ 133 public static SftpFileSystemConfigBuilder getInstance() { 134 return BUILDER; 135 } 136 137 /** 138 * @param opts The FileSystem options. 139 * @return The names of the compression algorithms, comma-separated. 140 * @see #setCompression 141 */ 142 public String getCompression(final FileSystemOptions opts) { 143 return this.getString(opts, COMPRESSION); 144 } 145 146 @Override 147 protected Class<? extends FileSystem> getConfigClass() { 148 return SftpFileSystem.class; 149 } 150 151 /** 152 * Gets the file name encoding. 153 * 154 * @param opts The FileSystem options. 155 * @return the file name encoding 156 */ 157 public String getFileNameEncoding(final FileSystemOptions opts) { 158 return this.getString(opts, ENCODING); 159 } 160 161 /** 162 * Gets the identity files (your private key files). 163 * <p> 164 * We use java.io.File because JSch cannot deal with VFS FileObjects. 165 * 166 * @param opts The FileSystem options. 167 * @return the array of identity Files. 168 * @see #setIdentities 169 * @deprecated As of 2.1 use {@link #getIdentityInfo(FileSystemOptions)} 170 */ 171 @Deprecated 172 public File[] getIdentities(final FileSystemOptions opts) { 173 final IdentityInfo[] info = getIdentityInfo(opts); 174 if (info != null) { 175 final File[] files = new File[info.length]; 176 for (int i = 0; i < files.length; ++i) { 177 files[i] = info[i].getPrivateKey(); 178 } 179 return files; 180 } 181 return null; 182 } 183 184 /** 185 * Gets the identity info. 186 * 187 * @param opts The FileSystem options. 188 * @return the array of identity info instances. 189 * @see #setIdentityInfo 190 */ 191 public IdentityInfo[] getIdentityInfo(final FileSystemOptions opts) { 192 return (IdentityInfo[]) this.getParam(opts, IDENTITIES); 193 } 194 195 /** 196 * Get the identity repository factory. 197 * 198 * @param opts The FileSystem options. 199 * @return the IdentityRepositoryFactory 200 */ 201 public IdentityRepositoryFactory getIdentityRepositoryFactory(final FileSystemOptions opts) { 202 return (IdentityRepositoryFactory) this.getParam(opts, IDENTITY_REPOSITORY_FACTORY); 203 } 204 205 /** 206 * @param opts The FileSystem options. 207 * @return the known hosts File. 208 * @see #setKnownHosts 209 */ 210 public File getKnownHosts(final FileSystemOptions opts) { 211 return (File) this.getParam(opts, KNOWN_HOSTS); 212 } 213 214 /** 215 * Gets authentication order. 216 * 217 * @param opts The FileSystem options. 218 * @return The authentication order. 219 * @since 2.0 220 */ 221 public String getPreferredAuthentications(final FileSystemOptions opts) { 222 return getString(opts, PREFERRED_AUTHENTICATIONS); 223 } 224 225 /** 226 * Gets the command that will be run on the proxy host when using a {@linkplain SftpStreamProxy}. The command 227 * defaults to {@linkplain SftpStreamProxy#NETCAT_COMMAND}. 228 * 229 * @param opts The FileSystem options. 230 * @return proxyOptions 231 * @see SftpStreamProxy 232 * @see #setProxyOptions 233 * @since 2.1 234 */ 235 public String getProxyCommand(final FileSystemOptions opts) { 236 return this.getString(opts, PROXY_COMMAND, SftpStreamProxy.NETCAT_COMMAND); 237 } 238 239 /** 240 * Gets the proxy to use for the SFTP connection. 241 * 242 * @param opts The FileSystem options. 243 * @return proxyHost 244 * @see #getProxyPort 245 * @see #setProxyHost 246 */ 247 public String getProxyHost(final FileSystemOptions opts) { 248 return this.getString(opts, PROXY_HOST); 249 } 250 251 /** 252 * Gets the proxy options that are used to connect to the proxy host. 253 * 254 * @param opts The FileSystem options. 255 * @return proxyOptions 256 * @see SftpStreamProxy 257 * @see #setProxyOptions 258 * @since 2.1 259 */ 260 public FileSystemOptions getProxyOptions(final FileSystemOptions opts) { 261 return (FileSystemOptions) this.getParam(opts, PROXY_OPTIONS); 262 } 263 264 /** 265 * Gets the proxy password that are used to connect to the proxy host. 266 * 267 * @param opts The FileSystem options. 268 * @return proxyOptions 269 * @see SftpStreamProxy 270 * @see #setProxyPassword 271 * @since 2.1 272 */ 273 public String getProxyPassword(final FileSystemOptions opts) { 274 return this.getString(opts, PROXY_PASSWORD); 275 } 276 277 /** 278 * Gets the proxy-port to use for the SFTP the connection. 279 * 280 * @param opts The FileSystem options. 281 * @return proxyPort: the port number or 0 if it is not set 282 * @see #setProxyPort 283 * @see #getProxyHost 284 */ 285 public int getProxyPort(final FileSystemOptions opts) { 286 return this.getInteger(opts, PROXY_PORT, 0); 287 } 288 289 /** 290 * Gets the proxy type to use for the SFTP connection. 291 * 292 * @param opts The FileSystem options. 293 * @return The ProxyType. 294 */ 295 public ProxyType getProxyType(final FileSystemOptions opts) { 296 return (ProxyType) this.getParam(opts, PROXY_TYPE); 297 } 298 299 /** 300 * Gets the user name for the proxy used for the SFTP connection. 301 * 302 * @param opts The FileSystem options. 303 * @return proxyUser 304 * @see #setProxyUser 305 * @since 2.1 306 */ 307 public String getProxyUser(final FileSystemOptions opts) { 308 return this.getString(opts, PROXY_USER); 309 } 310 311 /** 312 * @param opts The FileSystem options. 313 * @return the option value The host key checking. 314 * @see #setStrictHostKeyChecking(FileSystemOptions, String) 315 */ 316 public String getStrictHostKeyChecking(final FileSystemOptions opts) { 317 return this.getString(opts, STRICT_HOST_KEY_CHECKING, HOST_KEY_CHECK_NO); 318 } 319 320 /** 321 * @param opts The FileSystem options. 322 * @return The timeout value in milliseconds. 323 * @see #setTimeout 324 */ 325 public Integer getTimeout(final FileSystemOptions opts) { 326 return this.getInteger(opts, TIMEOUT); 327 } 328 329 /** 330 * Returns {@link Boolean#TRUE} if VFS should treat the user directory as the root directory. Defaults to 331 * <code>Boolean.TRUE</code> if the method {@link #setUserDirIsRoot(FileSystemOptions, boolean)} has not been 332 * invoked. 333 * 334 * @param opts The FileSystemOptions. 335 * @return <code>Boolean.TRUE</code> if VFS treats the user directory as the root directory. 336 * @see #setUserDirIsRoot 337 */ 338 public Boolean getUserDirIsRoot(final FileSystemOptions opts) { 339 return this.getBoolean(opts, USER_DIR_IS_ROOT, Boolean.TRUE); 340 } 341 342 /** 343 * @param opts The FileSystem options. 344 * @return The UserInfo. 345 * @see #setUserInfo 346 */ 347 public UserInfo getUserInfo(final FileSystemOptions opts) { 348 return (UserInfo) this.getParam(opts, UserInfo.class.getName()); 349 } 350 351 /** 352 * Configures the compression algorithms to use. 353 * <p> 354 * For example, use {@code "zlib,none"} to enable compression. 355 * <p> 356 * See the Jsch documentation (in particular the README file) for details. 357 * 358 * @param opts The FileSystem options. 359 * @param compression The names of the compression algorithms, comma-separated. 360 * @throws FileSystemException if an error occurs. 361 */ 362 public void setCompression(final FileSystemOptions opts, final String compression) throws FileSystemException { 363 this.setParam(opts, COMPRESSION, compression); 364 } 365 366 /** 367 * Sets the file name encoding. 368 * 369 * @param opts The FileSystem options. 370 * @param fileNameEncoding The name of the encoding to use for file names. 371 */ 372 public void setFileNameEncoding(final FileSystemOptions opts, final String fileNameEncoding) { 373 this.setParam(opts, ENCODING, fileNameEncoding); 374 } 375 376 /** 377 * Sets the identity files (your private key files). 378 * <p> 379 * We use {@link java.io.File} because JSch cannot deal with VFS FileObjects. 380 * 381 * @param opts The FileSystem options. 382 * @param identityFiles An array of identity Files. 383 * @throws FileSystemException if an error occurs. 384 * @deprecated As of 2.1 use {@link #setIdentityInfo(FileSystemOptions, IdentityInfo...)} 385 */ 386 @Deprecated 387 public void setIdentities(final FileSystemOptions opts, final File... identityFiles) throws FileSystemException { 388 IdentityInfo[] info = null; 389 if (identityFiles != null) { 390 info = new IdentityInfo[identityFiles.length]; 391 for (int i = 0; i < identityFiles.length; i++) { 392 info[i] = new IdentityInfo(identityFiles[i]); 393 } 394 } 395 this.setParam(opts, IDENTITIES, info); 396 } 397 398 /** 399 * Sets the identity info (your private key files). 400 * 401 * @param opts The FileSystem options. 402 * @param identites An array of identity info. 403 * @throws FileSystemException if an error occurs. 404 * @since 2.1 405 */ 406 public void setIdentityInfo(final FileSystemOptions opts, final IdentityInfo... identites) 407 throws FileSystemException { 408 this.setParam(opts, IDENTITIES, identites); 409 } 410 411 /** 412 * Set the identity repository. 413 * <p> 414 * This is useful when you want to use e.g. an SSH agent as provided. 415 * 416 * @param opts The FileSystem options. 417 * @param factory An identity repository. 418 * @throws FileSystemException if an error occurs. 419 * @see <a href="http://www.jcraft.com/jsch-agent-proxy/">JSch agent proxy</a> 420 */ 421 public void setIdentityRepositoryFactory(final FileSystemOptions opts, final IdentityRepositoryFactory factory) 422 throws FileSystemException { 423 this.setParam(opts, IDENTITY_REPOSITORY_FACTORY, factory); 424 } 425 426 /** 427 * Sets the known_hosts file. e.g. {@code /home/user/.ssh/known_hosts2}. 428 * <p> 429 * We use {@link java.io.File} because JSch cannot deal with VFS FileObjects. 430 * 431 * @param opts The FileSystem options. 432 * @param knownHosts The known hosts file. 433 * @throws FileSystemException if an error occurs. 434 */ 435 public void setKnownHosts(final FileSystemOptions opts, final File knownHosts) throws FileSystemException { 436 this.setParam(opts, KNOWN_HOSTS, knownHosts); 437 } 438 439 /** 440 * Configures authentication order. 441 * 442 * @param opts The FileSystem options. 443 * @param preferredAuthentications The authentication order. 444 * @since 2.0 445 */ 446 public void setPreferredAuthentications(final FileSystemOptions opts, final String preferredAuthentications) { 447 this.setParam(opts, PREFERRED_AUTHENTICATIONS, preferredAuthentications); 448 } 449 450 /** 451 * Sets the proxy username to use for the SFTP connection. 452 * 453 * @param opts The FileSystem options. 454 * @param proxyCommand the port 455 * @see #getProxyOptions 456 * @since 2.1 457 */ 458 public void setProxyCommand(final FileSystemOptions opts, final String proxyCommand) { 459 this.setParam(opts, PROXY_COMMAND, proxyCommand); 460 } 461 462 /** 463 * Sets the proxy to use for the SFTP connection. 464 * 465 * You MUST also set the proxy port to use the proxy. 466 * 467 * @param opts The FileSystem options. 468 * @param proxyHost the host 469 * @see #setProxyPort 470 */ 471 public void setProxyHost(final FileSystemOptions opts, final String proxyHost) { 472 this.setParam(opts, PROXY_HOST, proxyHost); 473 } 474 475 /** 476 * Sets the proxy username to use for the SFTP connection. 477 * 478 * @param opts The FileSystem options. 479 * @param proxyOptions the options 480 * @see #getProxyOptions 481 * @since 2.1 482 */ 483 public void setProxyOptions(final FileSystemOptions opts, final FileSystemOptions proxyOptions) { 484 this.setParam(opts, PROXY_OPTIONS, proxyOptions); 485 } 486 487 /** 488 * Sets the proxy password to use for the SFTP connection. 489 * 490 * @param opts The FileSystem options. 491 * @param proxyPassword the username used to connect to the proxy 492 * @see #getProxyPassword 493 * @since 2.1 494 */ 495 public void setProxyPassword(final FileSystemOptions opts, final String proxyPassword) { 496 this.setParam(opts, PROXY_PASSWORD, proxyPassword); 497 } 498 499 /** 500 * Sets the proxy port to use for the SFTP connection. 501 * <p> 502 * You MUST also set the proxy host to use the proxy. 503 * 504 * @param opts The FileSystem options. 505 * @param proxyPort the port 506 * @see #setProxyHost 507 */ 508 public void setProxyPort(final FileSystemOptions opts, final int proxyPort) { 509 this.setParam(opts, PROXY_PORT, Integer.valueOf(proxyPort)); 510 } 511 512 /** 513 * Sets the proxy type to use for the SFTP connection. 514 * 515 * The possibles values are: 516 * <ul> 517 * <li>{@linkplain #PROXY_HTTP} connects using an HTTP proxy</li> 518 * <li>{@linkplain #PROXY_SOCKS5} connects using an Socket5 proxy</li> 519 * <li>{@linkplain #PROXY_STREAM} connects through a remote host stream command</li> 520 * </ul> 521 * 522 * @param opts The FileSystem options. 523 * @param proxyType the type of the proxy to use. 524 */ 525 public void setProxyType(final FileSystemOptions opts, final ProxyType proxyType) { 526 this.setParam(opts, PROXY_TYPE, proxyType); 527 } 528 529 /** 530 * Sets the proxy username to use for the SFTP connection. 531 * 532 * @param opts The FileSystem options. 533 * @param proxyUser the username used to connect to the proxy 534 * @see #getProxyUser 535 * @since 2.1 536 */ 537 public void setProxyUser(final FileSystemOptions opts, final String proxyUser) { 538 this.setParam(opts, PROXY_USER, proxyUser); 539 } 540 541 /** 542 * Configures the host key checking to use. 543 * <p> 544 * Valid arguments are: {@code "yes"}, {@code "no"} and {@code "ask"}. 545 * </p> 546 * <p> 547 * See the jsch documentation for details. 548 * </p> 549 * 550 * @param opts The FileSystem options. 551 * @param hostKeyChecking The host key checking to use. 552 * @throws FileSystemException if an error occurs. 553 */ 554 public void setStrictHostKeyChecking(final FileSystemOptions opts, final String hostKeyChecking) 555 throws FileSystemException { 556 if (hostKeyChecking == null || (!hostKeyChecking.equals(HOST_KEY_CHECK_ASK) 557 && !hostKeyChecking.equals(HOST_KEY_CHECK_NO) && !hostKeyChecking.equals(HOST_KEY_CHECK_YES))) { 558 throw new FileSystemException("vfs.provider.sftp/StrictHostKeyChecking-arg.error", hostKeyChecking); 559 } 560 561 this.setParam(opts, STRICT_HOST_KEY_CHECKING, hostKeyChecking); 562 } 563 564 /** 565 * Sets the timeout value on Jsch session. 566 * 567 * @param opts The FileSystem options. 568 * @param timeout The timeout in milliseconds. 569 */ 570 public void setTimeout(final FileSystemOptions opts, final Integer timeout) { 571 this.setParam(opts, TIMEOUT, timeout); 572 } 573 574 /** 575 * Sets the whether to use the user directory as root (do not change to file system root). 576 * 577 * @param opts The FileSystem options. 578 * @param userDirIsRoot true if the user directory is the root directory. 579 */ 580 public void setUserDirIsRoot(final FileSystemOptions opts, final boolean userDirIsRoot) { 581 this.setParam(opts, USER_DIR_IS_ROOT, userDirIsRoot ? Boolean.TRUE : Boolean.FALSE); 582 } 583 584 /** 585 * Sets the Jsch UserInfo class to use. 586 * 587 * @param opts The FileSystem options. 588 * @param info User information. 589 */ 590 public void setUserInfo(final FileSystemOptions opts, final UserInfo info) { 591 this.setParam(opts, UserInfo.class.getName(), info); 592 } 593}