protected AbstractSftpClientExtension(
     String name, SftpClient client, RawSftpClient raw, boolean supported) {
   this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No extension name");
   this.client = ValidateUtils.checkNotNull(client, "No client instance");
   this.raw = ValidateUtils.checkNotNull(raw, "No raw access");
   this.supported = supported;
 }
예제 #2
0
 public MacVectorsTest(VectorSeed seed, String factoryName, String expected) {
   this.seed = ValidateUtils.checkNotNull(seed, "No seed");
   this.macFactory =
       ValidateUtils.checkNotNull(
           BuiltinMacs.fromFactoryName(factoryName), "Unknown MAC: %s", factoryName);
   this.expected = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, expected);
 }
예제 #3
0
 protected Nio2Service(FactoryManager manager, IoHandler handler, AsynchronousChannelGroup group) {
   if (log.isTraceEnabled()) {
     log.trace("Creating {}", getClass().getSimpleName());
   }
   this.manager = ValidateUtils.checkNotNull(manager, "No factory manager provided");
   this.handler = ValidateUtils.checkNotNull(handler, "No I/O handler provided");
   this.group = ValidateUtils.checkNotNull(group, "No async. channel group provided");
   this.sessions = new ConcurrentHashMap<>();
 }
예제 #4
0
  @Override
  public Boolean doAuth(Buffer buffer, boolean init) throws Exception {
    ValidateUtils.checkTrue(init, "Instance not initialized");
    boolean hasSig = buffer.getBoolean();
    String alg = buffer.getString();

    int oldLim = buffer.wpos();
    int oldPos = buffer.rpos();
    int len = buffer.getInt();
    buffer.wpos(buffer.rpos() + len);
    PublicKey key = buffer.getRawPublicKey();
    ServerFactoryManager manager = session.getFactoryManager();
    Signature verif =
        ValidateUtils.checkNotNull(
            NamedFactory.Utils.create(manager.getSignatureFactories(), alg),
            "No verifier located for algorithm=%s",
            alg);
    verif.initVerifier(key);
    buffer.wpos(oldLim);

    byte[] sig = hasSig ? buffer.getBytes() : null;

    PublickeyAuthenticator authenticator =
        ValidateUtils.checkNotNull(
            manager.getPublickeyAuthenticator(), "No PublickeyAuthenticator configured");
    if (!authenticator.authenticate(username, key, session)) {
      return Boolean.FALSE;
    }

    if (!hasSig) {
      Buffer buf = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_PK_OK);
      buf.putString(alg);
      buf.putRawBytes(buffer.array(), oldPos, 4 + len);
      session.writePacket(buf);
      return null;
    } else {
      Buffer buf = new ByteArrayBuffer();
      buf.putBytes(session.getKex().getH());
      buf.putByte(SshConstants.SSH_MSG_USERAUTH_REQUEST);
      buf.putString(username);
      buf.putString(service);
      buf.putString(UserAuthPublicKeyFactory.NAME);
      buf.putBoolean(true);
      buf.putString(alg);
      buffer.rpos(oldPos);
      buffer.wpos(oldPos + 4 + len);
      buf.putBuffer(buffer);
      verif.update(buf.array(), buf.rpos(), buf.available());
      if (!verif.verify(sig)) {
        throw new Exception("Key verification failed");
      }
      return Boolean.TRUE;
    }
  }
예제 #5
0
 public Collection<KeyPair> loadKeyPairs(
     String resourceKey, InputStream pubData, InputStream prvData)
     throws IOException, GeneralSecurityException {
   try (PuttyKeyReader pubReader =
           new PuttyKeyReader(
               ValidateUtils.checkNotNull(pubData, "No public key data in %s", resourceKey));
       PuttyKeyReader prvReader =
           new PuttyKeyReader(
               ValidateUtils.checkNotNull(prvData, "No private key data in %s", resourceKey))) {
     return loadKeyPairs(resourceKey, pubReader, prvReader);
   }
 }
예제 #6
0
  @Override
  public void handleOpenSuccess(int recipient, int rwSize, int packetSize, Buffer buffer) {
    setRecipient(recipient);

    Session session = getSession();
    FactoryManager manager =
        ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
    this.remoteWindow.init(rwSize, packetSize, manager.getProperties());
    ChannelListener listener = getChannelListenerProxy();
    try {
      doOpen();

      listener.channelOpenSuccess(this);
      this.opened.set(true);
      this.openFuture.setOpened();
    } catch (Throwable t) {
      Throwable e = GenericUtils.peelException(t);
      try {
        listener.channelOpenFailure(this, e);
      } catch (Throwable ignored) {
        log.warn(
            "handleOpenSuccess({}) failed ({}) to inform listener of open failure={}: {}",
            this,
            ignored.getClass().getSimpleName(),
            e.getClass().getSimpleName(),
            ignored.getMessage());
      }

      this.openFuture.setException(e);
      this.closeFuture.setClosed();
      this.doCloseImmediately();
    } finally {
      notifyStateChanged();
    }
  }
예제 #7
0
 @Override
 public void upload(Path local, String remote, Collection<Option> options) throws IOException {
   upload(
       new Path[] {ValidateUtils.checkNotNull(local, "Invalid local argument: %s", local)},
       remote,
       GenericUtils.isEmpty(options) ? Collections.<Option>emptySet() : GenericUtils.of(options));
 }
예제 #8
0
  @Override
  public void download(String remote, Path local, Collection<Option> options) throws IOException {
    local = ValidateUtils.checkNotNull(local, "Invalid argument local: %s", local);
    remote = ValidateUtils.checkNotNullAndNotEmpty(remote, "Invalid argument remote: %s", remote);

    LinkOption[] opts = IoUtils.getLinkOptions(false);
    if (Files.isDirectory(local, opts)) {
      options = addTargetIsDirectory(options);
    }

    if (options.contains(Option.TargetIsDirectory)) {
      Boolean status = IoUtils.checkFileExists(local, opts);
      if (status == null) {
        throw new SshException("Target directory " + local.toString() + " is probaly inaccesible");
      }

      if (!status.booleanValue()) {
        throw new SshException("Target directory " + local.toString() + " does not exist");
      }

      if (!Files.isDirectory(local, opts)) {
        throw new SshException("Target directory " + local.toString() + " is not a directory");
      }
    }

    download(remote, local.getFileSystem(), local, options);
  }
예제 #9
0
  public SshdSocketAddress(String hostName, int port) {
    ValidateUtils.checkNotNull(hostName, "Host name may not be null");
    this.hostName = GenericUtils.isEmpty(hostName) ? "0.0.0.0" : hostName;

    ValidateUtils.checkTrue(port >= 0, "Port must be >= 0", Integer.valueOf(port));
    this.port = port;
  }
예제 #10
0
  public static <E extends KnownHostEntry> E parseKnownHostEntry(E entry, String data) {
    String line = data;
    if (GenericUtils.isEmpty(line) || (line.charAt(0) == PublicKeyEntry.COMMENT_CHAR)) {
      return entry;
    }

    entry.setConfigLine(line);

    if (line.charAt(0) == MARKER_INDICATOR) {
      int pos = line.indexOf(' ');
      ValidateUtils.checkTrue(pos > 0, "Missing marker name end delimiter in line=%s", data);
      ValidateUtils.checkTrue(pos > 1, "No marker name after indicator in line=%s", data);
      entry.setMarker(line.substring(1, pos));
      line = line.substring(pos + 1).trim();
    } else {
      entry.setMarker(null);
    }

    int pos = line.indexOf(' ');
    ValidateUtils.checkTrue(pos > 0, "Missing host patterns end delimiter in line=%s", data);
    String hostPattern = line.substring(0, pos);
    line = line.substring(pos + 1).trim();

    if (hostPattern.charAt(0) == KnownHostHashValue.HASHED_HOST_DELIMITER) {
      KnownHostHashValue hash =
          ValidateUtils.checkNotNull(
              KnownHostHashValue.parse(hostPattern),
              "Failed to extract host hash value from line=%s",
              data);
      entry.setHashedEntry(hash);
      entry.setPatterns(null);
    } else {
      entry.setHashedEntry(null);
      entry.setPatterns(parsePatterns(GenericUtils.split(hostPattern, ',')));
    }

    AuthorizedKeyEntry key =
        ValidateUtils.checkNotNull(
            AuthorizedKeyEntry.parseAuthorizedKeyEntry(line),
            "No valid key entry recovered from line=%s",
            data);
    entry.setKeyEntry(key);
    return entry;
  }
예제 #11
0
  @Override
  public synchronized SshdSocketAddress startRemotePortForwarding(
      SshdSocketAddress remote, SshdSocketAddress local) throws IOException {
    ValidateUtils.checkNotNull(local, "Local address is null");
    ValidateUtils.checkNotNull(remote, "Remote address is null");

    Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST);
    buffer.putString("tcpip-forward");
    buffer.putBoolean(true);
    buffer.putString(remote.getHostName());
    buffer.putInt(remote.getPort());
    Buffer result = session.request(buffer);
    if (result == null) {
      throw new SshException("Tcpip forwarding request denied by server");
    }
    int port = (remote.getPort() == 0) ? result.getInt() : remote.getPort();
    // TODO: Is it really safe to only store the local address after the request ?
    SshdSocketAddress prev;
    synchronized (remoteToLocal) {
      prev = remoteToLocal.put(port, local);
    }

    if (prev != null) {
      throw new IOException(
          "Multiple remote port forwarding bindings on port="
              + port
              + ": current="
              + remote
              + ", previous="
              + prev);
    }

    SshdSocketAddress bound = new SshdSocketAddress(remote.getHostName(), port);
    if (log.isDebugEnabled()) {
      log.debug("startRemotePortForwarding(" + remote + " -> " + local + "): " + bound);
    }

    return bound;
  }
예제 #12
0
  @Override
  public synchronized SshdSocketAddress startLocalPortForwarding(
      SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
    ValidateUtils.checkNotNull(local, "Local address is null");
    ValidateUtils.checkTrue(local.getPort() >= 0, "Invalid local port: %s", local);
    ValidateUtils.checkNotNull(remote, "Remote address is null");

    if (isClosed()) {
      throw new IllegalStateException("TcpipForwarder is closed");
    }
    if (isClosing()) {
      throw new IllegalStateException("TcpipForwarder is closing");
    }

    InetSocketAddress bound = doBind(local, staticIoHandlerFactory);
    int port = bound.getPort();
    SshdSocketAddress prev;
    synchronized (localToRemote) {
      prev = localToRemote.put(port, remote);
    }

    if (prev != null) {
      throw new IOException(
          "Multiple local port forwarding bindings on port="
              + port
              + ": current="
              + remote
              + ", previous="
              + prev);
    }

    SshdSocketAddress result = new SshdSocketAddress(bound.getHostString(), port);
    if (log.isDebugEnabled()) {
      log.debug("startLocalPortForwarding(" + local + " -> " + remote + "): " + result);
    }
    return result;
  }
예제 #13
0
  @Override
  public void addChannelListener(ChannelListener listener) {
    ValidateUtils.checkNotNull(listener, "addChannelListener(%s) null instance", this);
    // avoid race conditions on notifications while manager is being closed
    if (!isOpen()) {
      log.warn(
          "addChannelListener({})[{}] ignore registration while session is closing",
          this,
          listener);
      return;
    }

    if (this.channelListeners.add(listener)) {
      log.trace("addChannelListener({})[{}] registered", this, listener);
    } else {
      log.trace("addChannelListener({})[{}] ignored duplicate", this, listener);
    }
  }
예제 #14
0
  @Override
  public synchronized SshdSocketAddress localPortForwardingRequested(SshdSocketAddress local)
      throws IOException {
    ValidateUtils.checkNotNull(local, "Local address is null");
    ValidateUtils.checkTrue(local.getPort() >= 0, "Invalid local port: %s", local);

    FactoryManager manager = session.getFactoryManager();
    ForwardingFilter filter = manager.getTcpipForwardingFilter();
    if ((filter == null) || (!filter.canListen(local, session))) {
      if (log.isDebugEnabled()) {
        log.debug(
            "localPortForwardingRequested("
                + session
                + ")["
                + local
                + "][haveFilter="
                + (filter != null)
                + "] rejected");
      }
      throw new IOException("Rejected address: " + local);
    }
    InetSocketAddress bound = doBind(local, staticIoHandlerFactory);
    SshdSocketAddress result = new SshdSocketAddress(bound.getHostString(), bound.getPort());
    if (log.isDebugEnabled()) {
      log.debug("localPortForwardingRequested(" + local + "): " + result);
    }

    boolean added;
    synchronized (localForwards) {
      // NOTE !!! it is crucial to use the bound address host name first
      added =
          localForwards.add(
              new LocalForwardingEntry(
                  result.getHostName(), local.getHostName(), result.getPort()));
    }

    if (!added) {
      throw new IOException(
          "Failed to add local port forwarding entry for " + local + " -> " + result);
    }
    return result;
  }
예제 #15
0
  protected void checkConfig() {
    ValidateUtils.checkNotNullAndNotEmpty(
        getKeyExchangeFactories(), "KeyExchangeFactories not set");

    if (getScheduledExecutorService() == null) {
      setScheduledExecutorService(
          ThreadUtils.newSingleThreadScheduledExecutor(this.toString() + "-timer"), true);
    }

    ValidateUtils.checkNotNullAndNotEmpty(getCipherFactories(), "CipherFactories not set");
    ValidateUtils.checkNotNullAndNotEmpty(
        getCompressionFactories(), "CompressionFactories not set");
    ValidateUtils.checkNotNullAndNotEmpty(getMacFactories(), "MacFactories not set");

    ValidateUtils.checkNotNull(getRandomFactory(), "RandomFactory not set");

    if (getIoServiceFactoryFactory() == null) {
      setIoServiceFactoryFactory(new DefaultIoServiceFactoryFactory());
    }
  }
예제 #16
0
  @Override
  public synchronized void stopLocalPortForwarding(SshdSocketAddress local) throws IOException {
    ValidateUtils.checkNotNull(local, "Local address is null");

    SshdSocketAddress bound;
    synchronized (localToRemote) {
      bound = localToRemote.remove(local.getPort());
    }

    if ((bound != null) && (acceptor != null)) {
      if (log.isDebugEnabled()) {
        log.debug("stopLocalPortForwarding(" + local + ") unbind " + bound);
      }
      acceptor.unbind(bound.toInetSocketAddress());
    } else {
      if (log.isDebugEnabled()) {
        log.debug("stopLocalPortForwarding(" + local + ") no mapping/acceptor for " + bound);
      }
    }
  }
예제 #17
0
  @Override
  public synchronized SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress local)
      throws IOException {
    ValidateUtils.checkNotNull(local, "Local address is null");
    ValidateUtils.checkTrue(local.getPort() >= 0, "Invalid local port: %s", local);

    if (isClosed()) {
      throw new IllegalStateException("TcpipForwarder is closed");
    }
    if (isClosing()) {
      throw new IllegalStateException("TcpipForwarder is closing");
    }

    SocksProxy socksProxy = new SocksProxy(service);
    SocksProxy prev;
    InetSocketAddress bound = doBind(local, socksProxyIoHandlerFactory);
    int port = bound.getPort();
    synchronized (dynamicLocal) {
      prev = dynamicLocal.put(port, socksProxy);
    }

    if (prev != null) {
      throw new IOException(
          "Multiple dynamic port mappings found for port="
              + port
              + ": current="
              + socksProxy
              + ", previous="
              + prev);
    }

    SshdSocketAddress result = new SshdSocketAddress(bound.getHostString(), port);
    if (log.isDebugEnabled()) {
      log.debug("startDynamicPortForwarding(" + local + "): " + result);
    }

    return result;
  }
예제 #18
0
  @Override
  public PathMatcher getPathMatcher(String syntaxAndPattern) {
    int colonIndex = ValidateUtils.checkNotNull(syntaxAndPattern, "No argument").indexOf(':');
    if ((colonIndex <= 0) || (colonIndex == syntaxAndPattern.length() - 1)) {
      throw new IllegalArgumentException(
          "syntaxAndPattern must have form \"syntax:pattern\" but was \""
              + syntaxAndPattern
              + "\"");
    }

    String syntax = syntaxAndPattern.substring(0, colonIndex);
    String pattern = syntaxAndPattern.substring(colonIndex + 1);
    String expr;
    switch (syntax) {
      case "glob":
        expr = globToRegex(pattern);
        break;
      case "regex":
        expr = pattern;
        break;
      default:
        throw new UnsupportedOperationException(
            "Unsupported path matcher syntax: \'" + syntax + "\'");
    }
    if (log.isTraceEnabled()) {
      log.trace("getPathMatcher({}): {}", syntaxAndPattern, expr);
    }

    final Pattern regex = Pattern.compile(expr);
    return new PathMatcher() {
      @Override
      public boolean matches(Path path) {
        Matcher m = regex.matcher(path.toString());
        return m.matches();
      }
    };
  }
예제 #19
0
 public void setProperties(Map<String, Object> properties) {
   this.properties = ValidateUtils.checkNotNull(properties, "Null properties not allowed");
 }
예제 #20
0
 public DefaultTcpipForwarder(ConnectionService service) {
   this.service = ValidateUtils.checkNotNull(service, "No connection service");
   this.session = ValidateUtils.checkNotNull(service.getSession(), "No session");
 }
예제 #21
0
  protected String globToRegex(String pattern) {
    StringBuilder sb = new StringBuilder(ValidateUtils.checkNotNull(pattern, "No patern").length());
    int inGroup = 0;
    int inClass = 0;
    int firstIndexInClass = -1;
    char[] arr = pattern.toCharArray();
    for (int i = 0; i < arr.length; i++) {
      char ch = arr[i];
      switch (ch) {
        case '\\':
          if (++i >= arr.length) {
            sb.append('\\');
          } else {
            char next = arr[i];
            switch (next) {
              case ',':
                // escape not needed
                break;
              case 'Q':
              case 'E':
                // extra escape needed
                sb.append("\\\\");
                break;
              default:
                sb.append('\\');
                break;
            }
            sb.append(next);
          }
          break;
        case '*':
          sb.append(inClass == 0 ? ".*" : "*");
          break;
        case '?':
          sb.append(inClass == 0 ? '.' : '?');
          break;
        case '[':
          inClass++;
          firstIndexInClass = i + 1;
          sb.append('[');
          break;
        case ']':
          inClass--;
          sb.append(']');
          break;
        case '.':
        case '(':
        case ')':
        case '+':
        case '|':
        case '^':
        case '$':
        case '@':
        case '%':
          if (inClass == 0 || (firstIndexInClass == i && ch == '^')) {
            sb.append('\\');
          }
          sb.append(ch);
          break;
        case '!':
          sb.append(firstIndexInClass == i ? '^' : '!');
          break;
        case '{':
          inGroup++;
          sb.append('(');
          break;
        case '}':
          inGroup--;
          sb.append(')');
          break;
        case ',':
          sb.append(inGroup > 0 ? '|' : ',');
          break;
        default:
          sb.append(ch);
      }
    }

    String regex = sb.toString();
    if (log.isTraceEnabled()) {
      log.trace("globToRegex({}): {}", pattern, regex);
    }

    return regex;
  }
예제 #22
0
  @Override
  public Set<ClientChannelEvent> waitFor(Collection<ClientChannelEvent> mask, long timeout) {
    ValidateUtils.checkNotNull(mask, "No mask specified");
    long t = 0;
    synchronized (lock) {
      for (Set<ClientChannelEvent> cond = EnumSet.noneOf(ClientChannelEvent.class);
          ;
          cond.clear()) {
        if (openFuture != null && openFuture.isOpened()) {
          cond.add(ClientChannelEvent.OPENED);
        }
        if (closeFuture.isClosed()) {
          cond.add(ClientChannelEvent.CLOSED);
          cond.add(ClientChannelEvent.EOF);
        }
        if (isEofSignalled()) {
          cond.add(ClientChannelEvent.EOF);
        }
        if (exitStatusHolder.get() != null) {
          if (log.isDebugEnabled()) {
            log.debug("waitFor({}) mask={} - exit status={}", this, mask, exitStatusHolder);
          }
          cond.add(ClientChannelEvent.EXIT_STATUS);
        }
        if (exitSignalHolder.get() != null) {
          if (log.isDebugEnabled()) {
            log.debug("waitFor({}) mask={} - exit signal={}", this, mask, exitSignalHolder);
          }
          cond.add(ClientChannelEvent.EXIT_SIGNAL);
        }

        boolean nothingInCommon = Collections.disjoint(mask, cond);
        if (!nothingInCommon) {
          if (log.isTraceEnabled()) {
            log.trace("WaitFor call returning on channel {}, mask={}, cond={}", this, mask, cond);
          }
          return cond;
        }

        if (timeout > 0L) {
          if (t == 0L) {
            t = System.currentTimeMillis() + timeout;
          } else {
            timeout = t - System.currentTimeMillis();
            if (timeout <= 0L) {
              if (log.isTraceEnabled()) {
                log.trace("WaitFor call timeout on channel {}, mask={}", this, mask);
              }
              cond.add(ClientChannelEvent.TIMEOUT);
              return cond;
            }
          }
        }

        if (log.isTraceEnabled()) {
          log.trace(
              "Waiting {} millis for lock on channel {}, mask={}, cond={}",
              timeout,
              this,
              mask,
              cond);
        }

        long nanoStart = System.nanoTime();
        try {
          if (timeout > 0L) {
            lock.wait(timeout);
          } else {
            lock.wait();
          }

          long nanoEnd = System.nanoTime();
          long nanoDuration = nanoEnd - nanoStart;
          if (log.isTraceEnabled()) {
            log.trace("Lock notified on channel {} after {} nanos", this, nanoDuration);
          }
        } catch (InterruptedException e) {
          long nanoEnd = System.nanoTime();
          long nanoDuration = nanoEnd - nanoStart;
          if (log.isTraceEnabled()) {
            log.trace(
                "waitFor({}) mask={} - ignoring interrupted exception after {} nanos",
                this,
                mask,
                nanoDuration);
          }
        }
      }
    }
  }
예제 #23
0
 public TtyFilterInputStreamTest(PtyMode mode) {
   this.mode = ValidateUtils.checkNotNull(mode, "No test modes");
 }
예제 #24
0
 public BaseFileSystem(FileSystemProvider fileSystemProvider) {
   this.log = LoggerFactory.getLogger(getClass());
   this.fileSystemProvider =
       ValidateUtils.checkNotNull(fileSystemProvider, "No file system provider");
 }
 public ModifiableFileWatcher(File file) {
   this(ValidateUtils.checkNotNull(file, "No file to watch").toPath());
 }
 public ModifiableFileWatcher(Path file, LinkOption... options) {
   this.file = ValidateUtils.checkNotNull(file, "No path to watch");
   // use a clone to avoid being sensitive to changes in the passed array
   this.options = (options == null) ? IoUtils.EMPTY_LINK_OPTIONS : options.clone();
 }