示例#1
0
  /**
   * @param props The {@link Properties} holding the server's configuration - ignored if {@code
   *     null}/empty
   * @param options The {@link LinkOption}s to use when checking files existence
   * @return A {@link Map} of the found identities where key=the identity type (case
   *     <U>insensitive</U>) and value=the {@link Path} of the file holding the specific type key
   * @throws IOException If failed to access the file system
   * @see #getIdentityType(String)
   * @see #HOST_KEY_CONFIG_PROP
   * @see org.apache.sshd.common.config.SshConfigFileReader#readConfigFile(File)
   */
  public static Map<String, Path> findIdentities(Properties props, LinkOption... options)
      throws IOException {
    if (GenericUtils.isEmpty(props)) {
      return Collections.emptyMap();
    }

    String keyList = props.getProperty(HOST_KEY_CONFIG_PROP);
    String[] paths = GenericUtils.split(keyList, ',');
    if (GenericUtils.isEmpty(paths)) {
      return Collections.emptyMap();
    }

    Map<String, Path> ids = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
    for (String p : paths) {
      File file = new File(p);
      Path path = file.toPath();
      if (!Files.exists(path, options)) {
        continue;
      }

      String type = getIdentityType(path.getFileName().toString());
      if (GenericUtils.isEmpty(type)) {
        type = p; // just in case the file name does not adhere to the standard naming convention
      }
      Path prev = ids.put(type, path);
      ValidateUtils.checkTrue(prev == null, "Multiple mappings for type=%s", type);
    }

    return ids;
  }
示例#2
0
 @Override
 public void download(String[] remote, Path local, Option... options) throws IOException {
   download(
       remote,
       local,
       GenericUtils.isEmpty(options) ? Collections.<Option>emptySet() : GenericUtils.of(options));
 }
示例#3
0
 @Override
 public void upload(Path[] local, String remote, Option... options) throws IOException {
   upload(
       local,
       remote,
       GenericUtils.isEmpty(options) ? Collections.<Option>emptySet() : GenericUtils.of(options));
 }
示例#4
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));
 }
示例#5
0
  @Override
  public T getPath(String first, String... more) {
    StringBuilder sb = new StringBuilder();
    if (!GenericUtils.isEmpty(first)) {
      appendDedupSep(sb, first.replace('\\', '/')); // in case we are running on Windows
    }

    if (GenericUtils.length(more) > 0) {
      for (String segment : more) {
        if ((sb.length() > 0) && (sb.charAt(sb.length() - 1) != '/')) {
          sb.append('/');
        }
        // in case we are running on Windows
        appendDedupSep(sb, segment.replace('\\', '/'));
      }
    }

    if ((sb.length() > 1) && (sb.charAt(sb.length() - 1) == '/')) {
      sb.setLength(sb.length() - 1);
    }

    String path = sb.toString();
    String root = null;
    if (path.startsWith("/")) {
      root = "/";
      path = path.substring(1);
    }

    String[] names = GenericUtils.split(path, '/');
    return create(root, names);
  }
示例#6
0
  protected Collection<Option> addTargetIsDirectory(Collection<Option> options) {
    if (GenericUtils.isEmpty(options) || (!options.contains(Option.TargetIsDirectory))) {
      // create a copy in case the original collection is un-modifiable
      options =
          GenericUtils.isEmpty(options) ? EnumSet.noneOf(Option.class) : GenericUtils.of(options);
      options.add(Option.TargetIsDirectory);
    }

    return options;
  }
示例#7
0
  protected <T> void setOption(
      NetworkChannel socket, String property, SocketOption<T> option, T defaultValue)
      throws IOException {
    PropertyResolver manager = getFactoryManager();
    String valStr = PropertyResolverUtils.getString(manager, property);
    T val = defaultValue;
    if (!GenericUtils.isEmpty(valStr)) {
      Class<T> type = option.type();
      if (type == Integer.class) {
        val = type.cast(Integer.valueOf(valStr));
      } else if (type == Boolean.class) {
        val = type.cast(Boolean.valueOf(valStr));
      } else {
        throw new IllegalStateException("Unsupported socket option type " + type);
      }
    }

    if (val != null) {
      Collection<? extends SocketOption<?>> supported = socket.supportedOptions();
      if ((GenericUtils.size(supported) <= 0) || (!supported.contains(option))) {
        log.warn(
            "Unsupported socket option ("
                + option
                + ") to set using property '"
                + property
                + "' value="
                + val);
        return;
      }

      try {
        socket.setOption(option, val);
        if (log.isDebugEnabled()) {
          log.debug("setOption({})[{}] from property={}", option, val, property);
        }
      } catch (IOException | RuntimeException e) {
        log.warn(
            "Unable ("
                + e.getClass().getSimpleName()
                + ")"
                + " to set socket option "
                + option
                + " using property '"
                + property
                + "' value="
                + val
                + ": "
                + e.getMessage());
      }
    }
  }
示例#8
0
  @Test
  public void testLoadClientIdentities() throws Exception {
    Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());

    Path resFolder = getClassResourcesFolder(TEST_SUBFOLDER, getClass()).toPath();
    LinkOption[] options = IoUtils.getLinkOptions(false);
    Collection<BuiltinIdentities> expected = EnumSet.noneOf(BuiltinIdentities.class);
    for (BuiltinIdentities type : BuiltinIdentities.VALUES) {
      String fileName = ClientIdentity.getIdentityFileName(type);
      Path file = resFolder.resolve(fileName);
      if (!Files.exists(file, options)) {
        System.out.println("Skip non-existing identity file " + file);
        continue;
      }

      if (!type.isSupported()) {
        System.out.println("Skip unsupported identity file " + file);
        continue;
      }

      expected.add(type);
    }

    Map<String, KeyPair> ids =
        ClientIdentity.loadDefaultIdentities(
            resFolder, false, // don't be strict
            null, // none of the files is password protected
            options);
    assertEquals(
        "Mismatched loaded ids count", GenericUtils.size(expected), GenericUtils.size(ids));

    Collection<KeyPair> pairs = new ArrayList<KeyPair>(ids.size());
    for (BuiltinIdentities type : BuiltinIdentities.VALUES) {
      if (expected.contains(type)) {
        KeyPair kp = ids.get(type.getName());
        assertNotNull("No key pair loaded for " + type, kp);
        pairs.add(kp);
      }
    }

    KeyPairProvider provider = IdentityUtils.createKeyPairProvider(ids, true /* supported only */);
    assertNotNull("No provider generated", provider);

    Iterable<KeyPair> keys = provider.loadKeys();
    for (KeyPair kp : keys) {
      assertTrue("Unexpected loaded key: " + kp, pairs.remove(kp));
    }

    assertEquals("Not all pairs listed", 0, pairs.size());
  }
示例#9
0
  /**
   * Reads configuration entries
   *
   * @param rdr The {@link BufferedReader} to use
   * @return The {@link List} of read {@link KnownHostEntry}-ies
   * @throws IOException If failed to parse the read configuration
   */
  public static List<KnownHostEntry> readKnownHostEntries(BufferedReader rdr) throws IOException {
    List<KnownHostEntry> entries = null;

    int lineNumber = 1;
    for (String line = rdr.readLine(); line != null; line = rdr.readLine(), lineNumber++) {
      line = GenericUtils.trimToEmpty(line);
      if (GenericUtils.isEmpty(line)) {
        continue;
      }

      int pos = line.indexOf(SshConfigFileReader.COMMENT_CHAR);
      if (pos == 0) {
        continue;
      }

      if (pos > 0) {
        line = line.substring(0, pos);
        line = line.trim();
      }

      try {
        KnownHostEntry entry = parseKnownHostEntry(line);
        if (entry == null) {
          continue;
        }

        if (entries == null) {
          entries = new ArrayList<>();
        }
        entries.add(entry);
      } catch (RuntimeException | Error e) { // TODO consider consulting a user callback
        throw new StreamCorruptedException(
            "Failed ("
                + e.getClass().getSimpleName()
                + ")"
                + " to parse line #"
                + lineNumber
                + " '"
                + line
                + "': "
                + e.getMessage());
      }
    }

    if (entries == null) {
      return Collections.emptyList();
    } else {
      return entries;
    }
  }
  public Collection<KeyPair> loadKeyPairs(
      String resourceKey,
      String pubData,
      String prvData,
      String prvEncryption,
      FilePasswordProvider passwordProvider)
      throws IOException, GeneralSecurityException {
    Decoder b64Decoder = Base64.getDecoder();
    byte[] pubBytes = b64Decoder.decode(pubData);
    byte[] prvBytes = b64Decoder.decode(prvData);
    String password = null;
    if ((GenericUtils.length(prvEncryption) > 0)
        && (!NO_PRIVATE_KEY_ENCRYPTION_VALUE.equalsIgnoreCase(prvEncryption))) {
      password = passwordProvider.getPassword(resourceKey);
    }

    if (GenericUtils.isEmpty(prvEncryption)
        || NO_PRIVATE_KEY_ENCRYPTION_VALUE.equalsIgnoreCase(prvEncryption)
        || GenericUtils.isEmpty(password)) {
      return loadKeyPairs(resourceKey, pubBytes, prvBytes);
    }

    // format is "<cipher><bits>-<mode>" - e.g., "aes256-cbc"
    int pos = prvEncryption.indexOf('-');
    if (pos <= 0) {
      throw new StreamCorruptedException("Missing private key encryption mode in " + prvEncryption);
    }

    String mode = prvEncryption.substring(pos + 1).toUpperCase();
    String algName = null;
    int numBits = 0;
    for (int index = 0; index < pos; index++) {
      char ch = prvEncryption.charAt(index);
      if ((ch >= '0') && (ch <= '9')) {
        algName = prvEncryption.substring(0, index).toUpperCase();
        numBits = Integer.parseInt(prvEncryption.substring(index, pos));
        break;
      }
    }

    if (GenericUtils.isEmpty(algName) || (numBits <= 0)) {
      throw new StreamCorruptedException(
          "Missing private key encryption algorithm details in " + prvEncryption);
    }

    prvBytes =
        PuttyKeyPairResourceParser.decodePrivateKeyBytes(
            prvBytes, algName, numBits, mode, password);
    return loadKeyPairs(resourceKey, pubBytes, prvBytes);
  }
  private void closeImmediately0() {
    // We need to close the channel immediately to remove it from the
    // server session's channel table and *not* send a packet to the
    // client.  A notification was already sent by our caller, or will
    // be sent after we return.
    //
    super.close(true);

    // We also need to close the socket.
    Socket.close(handle);

    try {
      if ((forwarder != null) && (!forwarder.isDone())) {
        forwarder.cancel(true);
      }
    } finally {
      forwarder = null;
    }

    try {
      if ((forwardService != null) && shutdownForwarder) {
        Collection<?> runners = forwardService.shutdownNow();
        if (log.isDebugEnabled()) {
          log.debug("Shut down runners count=" + GenericUtils.size(runners));
        }
      }
    } finally {
      forwardService = null;
      shutdownForwarder = false;
    }
  }
示例#12
0
  /**
   * @param <E> The generic entry type
   * @param entry The {@link PublicKeyEntry} whose contents are to be updated - ignored if {@code
   *     null}
   * @param data Assumed to contain at least {@code key-type base64-data} (anything beyond the
   *     BASE64 data is ignored) - ignored if {@code null}/empty
   * @return The updated entry instance
   * @throws IllegalArgumentException if bad format found
   */
  public static final <E extends PublicKeyEntry> E parsePublicKeyEntry(E entry, String data)
      throws IllegalArgumentException {
    if (GenericUtils.isEmpty(data) || (entry == null)) {
      return entry;
    }

    int startPos = data.indexOf(' ');
    if (startPos <= 0) {
      throw new IllegalArgumentException("Bad format (no key data delimiter): " + data);
    }

    int endPos = data.indexOf(' ', startPos + 1);
    if (endPos <= startPos) { // OK if no continuation beyond the BASE64 encoded data
      endPos = data.length();
    }

    String keyType = data.substring(0, startPos);
    String b64Data = data.substring(startPos + 1, endPos).trim();
    byte[] keyData = Base64.decodeString(b64Data);
    if (NumberUtils.isEmpty(keyData)) {
      throw new IllegalArgumentException("Bad format (no BASE64 key data): " + data);
    }

    entry.setKeyType(keyType);
    entry.setKeyData(keyData);
    return entry;
  }
示例#13
0
    /**
     * @param <R> The generic resource type
     * @param name Name of the resource - ignored if {@code null}/empty
     * @param c The {@link Comparator} to decide whether the {@link NamedResource#getName()} matches
     *     the <tt>name</tt> parameter
     * @param resources The {@link NamedResource} to check - ignored if {@code null}/empty
     * @return The <U>first</U> resource whose name matches the parameter (by invoking {@link
     *     Comparator#compare(Object, Object)} - {@code null} if no match found
     */
    public static <R extends NamedResource> R findByName(
        String name, Comparator<? super String> c, Collection<? extends R> resources) {
      if (GenericUtils.isEmpty(name) || GenericUtils.isEmpty(resources)) {
        return null;
      }

      for (R r : resources) {
        String n = r.getName();
        int nRes = c.compare(name, n);
        if (nRes == 0) {
          return r;
        }
      }

      return null;
    }
示例#14
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;
  }
  public static List<String> extractDataLines(
      String resourceKey,
      List<String> lines,
      int startIndex,
      String hdrName,
      String hdrValue,
      List<String> curLines)
      throws IOException {
    if (GenericUtils.size(curLines) > 0) {
      throw new StreamCorruptedException("Duplicate " + hdrName + " in " + resourceKey);
    }

    int numLines;
    try {
      numLines = Integer.parseInt(hdrValue);
    } catch (NumberFormatException e) {
      throw new StreamCorruptedException(
          "Bad " + hdrName + " value (" + hdrValue + ") in " + resourceKey);
    }

    int endIndex = startIndex + numLines;
    int totalLines = lines.size();
    if (endIndex > totalLines) {
      throw new StreamCorruptedException(
          "Excessive " + hdrName + " value (" + hdrValue + ") in " + resourceKey);
    }

    return lines.subList(startIndex, endIndex);
  }
示例#16
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();
    }
  }
示例#17
0
    private static CharSequence trimToLength(CharSequence csq, int maxLen) {
      if (GenericUtils.length(csq) <= maxLen) {
        return csq;
      }

      return csq.subSequence(0, maxLen) + "...";
    }
示例#18
0
 /**
  * @param data Assumed to contain at least {@code key-type base64-data} (anything beyond the
  *     BASE64 data is ignored) - ignored if {@code null}/empty
  * @return A {@link PublicKeyEntry} or {@code null} if no data
  * @throws IllegalArgumentException if bad format found
  * @see #parsePublicKeyEntry(PublicKeyEntry, String)
  */
 public static final PublicKeyEntry parsePublicKeyEntry(String data)
     throws IllegalArgumentException {
   if (GenericUtils.isEmpty(data)) {
     return null;
   } else {
     return parsePublicKeyEntry(new PublicKeyEntry(), data);
   }
 }
 /**
  * @param extraSize Extra size - besides the extension name
  * @return A {@link Buffer} with the extension name set
  */
 protected Buffer getCommandBuffer(int extraSize) {
   String opcode = getName();
   Buffer buffer =
       new ByteArrayBuffer(
           (Integer.SIZE / Byte.SIZE) + GenericUtils.length(opcode) + extraSize + Byte.SIZE);
   buffer.putString(opcode);
   return buffer;
 }
示例#20
0
  /**
   * Unregisters specified extension
   *
   * @param name The factory name - ignored if {@code null}/empty
   * @return The registered extension - {@code null} if not found
   */
  public static SignatureFactory unregisterExtension(String name) {
    if (GenericUtils.isEmpty(name)) {
      return null;
    }

    synchronized (EXTENSIONS) {
      return EXTENSIONS.remove(name);
    }
  }
  @Override
  protected OpenFuture doInit(Buffer buffer) {
    OpenFuture f = new DefaultOpenFuture(this);
    try {
      out =
          new ChannelOutputStream(
              this, getRemoteWindow(), log, SshConstants.SSH_MSG_CHANNEL_DATA, true);
      authSocket = PropertyResolverUtils.getString(this, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
      pool = Pool.create(AprLibrary.getInstance().getRootPool());
      handle = Local.create(authSocket, pool);
      int result = Local.connect(handle, 0);
      if (result != Status.APR_SUCCESS) {
        throwException(result);
      }

      ExecutorService service = getExecutorService();
      forwardService =
          (service == null)
              ? ThreadUtils.newSingleThreadExecutor("ChannelAgentForwarding[" + authSocket + "]")
              : service;
      shutdownForwarder = service != forwardService || isShutdownOnExit();

      final int copyBufSize =
          PropertyResolverUtils.getIntProperty(
              this, FORWARDER_BUFFER_SIZE, DEFAULT_FORWARDER_BUF_SIZE);
      ValidateUtils.checkTrue(
          copyBufSize >= MIN_FORWARDER_BUF_SIZE, "Copy buf size below min.: %d", copyBufSize);
      ValidateUtils.checkTrue(
          copyBufSize <= MAX_FORWARDER_BUF_SIZE, "Copy buf size above max.: %d", copyBufSize);

      forwarder =
          forwardService.submit(
              () -> {
                try {
                  byte[] buf = new byte[copyBufSize];
                  while (true) {
                    int len = Socket.recv(handle, buf, 0, buf.length);
                    if (len > 0) {
                      out.write(buf, 0, len);
                      out.flush();
                    }
                  }
                } catch (IOException e) {
                  close(true);
                }
              });

      signalChannelOpenSuccess();
      f.setOpened();
    } catch (Throwable t) {
      Throwable e = GenericUtils.peelException(t);
      signalChannelOpenFailure(e);
      f.setException(e);
    }

    return f;
  }
示例#22
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;
  }
示例#23
0
 @Override
 public SftpSubsystemFactory build() {
   SftpSubsystemFactory factory = new SftpSubsystemFactory();
   factory.setExecutorService(executors);
   factory.setShutdownOnExit(shutdownExecutor);
   factory.setUnsupportedAttributePolicy(policy);
   factory.setFileSystemAccessor(fileSystemAccessor);
   GenericUtils.forEach(getRegisteredListeners(), factory::addSftpEventListener);
   return factory;
 }
示例#24
0
 /**
  * @param name The file name - ignored if {@code null}/empty
  * @return The identity type - {@code null} if cannot determine it - e.g., does not start/end with
  *     the {@link #ID_FILE_PREFIX}/{@link #ID_FILE_SUFFIX}
  */
 public static String getIdentityType(String name) {
   if (GenericUtils.isEmpty(name)
       || (name.length() <= (ID_FILE_PREFIX.length() + ID_FILE_SUFFIX.length()))
       || (!name.startsWith(ID_FILE_PREFIX))
       || (!name.endsWith(ID_FILE_SUFFIX))) {
     return null;
   } else {
     return name.substring(ID_FILE_PREFIX.length(), name.length() - ID_FILE_SUFFIX.length());
   }
 }
示例#25
0
 @Override
 public Command create() {
   SftpSubsystem subsystem =
       new SftpSubsystem(
           getExecutorService(),
           isShutdownOnExit(),
           getUnsupportedAttributePolicy(),
           getFileSystemAccessor());
   GenericUtils.forEach(getRegisteredListeners(), subsystem::addSftpEventListener);
   return subsystem;
 }
  /**
   * Checks if a path has strict permissions
   *
   * <UL>
   *   <LI>
   *       <p>(For {@code Unix}) The path may not have group or others write permissions
   *   <LI>
   *       <p>The path must be owned by current user.
   *   <LI>
   *       <p>(For {@code Unix}) The path may be owned by root.
   * </UL>
   *
   * @param path The {@link Path} to be checked - ignored if {@code null} or does not exist
   * @param options The {@link LinkOption}s to use to query the file's permissions
   * @return The violated permission as {@link Pair} where {@link Pair#getClass()} is a loggable
   *     message and {@link Pair#getSecond()} is the offending object - e.g., {@link
   *     PosixFilePermission} or {@link String} for owner. Return value is {@code null} if no
   *     violations detected
   * @throws IOException If failed to retrieve the permissions
   * @see #STRICTLY_PROHIBITED_FILE_PERMISSION
   */
  public static Pair<String, Object> validateStrictConfigFilePermissions(
      Path path, LinkOption... options) throws IOException {
    if ((path == null) || (!Files.exists(path, options))) {
      return null;
    }

    Collection<PosixFilePermission> perms = IoUtils.getPermissions(path, options);
    if (GenericUtils.isEmpty(perms)) {
      return null;
    }

    if (OsUtils.isUNIX()) {
      PosixFilePermission p =
          IoUtils.validateExcludedPermissions(perms, STRICTLY_PROHIBITED_FILE_PERMISSION);
      if (p != null) {
        return new Pair<String, Object>(String.format("Permissions violation (%s)", p), p);
      }
    }

    String owner = IoUtils.getFileOwner(path, options);
    if (GenericUtils.isEmpty(owner)) {
      // we cannot get owner
      // general issue: jvm does not support permissions
      // security issue: specific filesystem does not support permissions
      return null;
    }

    String current = OsUtils.getCurrentUser();
    Set<String> expected = new HashSet<>();
    expected.add(current);
    if (OsUtils.isUNIX()) {
      // Windows "Administrator" was considered however in Windows most likely a group is used.
      expected.add(OsUtils.ROOT_USER);
    }

    if (!expected.contains(owner)) {
      return new Pair<String, Object>(String.format("Owner violation (%s)", owner), owner);
    }

    return null;
  }
示例#27
0
    /**
     * @param resources The named resources
     * @return A {@link List} of all the factories names - in same order as they appear in the input
     *     collection
     */
    public static List<String> getNameList(Collection<? extends NamedResource> resources) {
      if (GenericUtils.isEmpty(resources)) {
        return Collections.emptyList();
      }

      List<String> names = new ArrayList<>(resources.size());
      for (NamedResource r : resources) {
        names.add(r.getName());
      }

      return names;
    }
示例#28
0
  /**
   * @param s The {@link Enum}'s name - ignored if {@code null}/empty
   * @return The matching {@link org.apache.sshd.common.signature.BuiltinSignatures} whose {@link
   *     Enum#name()} matches (case <U>insensitive</U>) the provided argument - {@code null} if no
   *     match
   */
  public static BuiltinSignatures fromString(String s) {
    if (GenericUtils.isEmpty(s)) {
      return null;
    }

    for (BuiltinSignatures c : VALUES) {
      if (s.equalsIgnoreCase(c.name())) {
        return c;
      }
    }

    return null;
  }
示例#29
0
    /**
     * @param name The result name - ignored if {@code null}/empty
     * @return The matching {@link Result} value (case <U>insensitive</U>) or {@code null} if no
     *     match found
     */
    public static Result fromName(String name) {
      if (GenericUtils.isEmpty(name)) {
        return null;
      }

      for (Result r : VALUES) {
        if (name.equalsIgnoreCase(r.name())) {
          return r;
        }
      }

      return null;
    }
  /**
   * @param address The request bind address
   * @param handlerFactory A {@link Factory} to create an {@link IoHandler} if necessary
   * @return The {@link InetSocketAddress} to which the binding occurred
   * @throws IOException If failed to bind
   */
  private InetSocketAddress doBind(
      SshdSocketAddress address, Factory<? extends IoHandler> handlerFactory) throws IOException {
    if (acceptor == null) {
      FactoryManager manager = session.getFactoryManager();
      IoServiceFactory factory = manager.getIoServiceFactory();
      IoHandler handler = handlerFactory.create();
      acceptor = factory.createAcceptor(handler);
    }

    // TODO find a better way to determine the resulting bind address - what if multi-threaded
    // calls...
    Set<SocketAddress> before = acceptor.getBoundAddresses();
    try {
      InetSocketAddress bindAddress = address.toInetSocketAddress();
      acceptor.bind(bindAddress);

      Set<SocketAddress> after = acceptor.getBoundAddresses();
      if (GenericUtils.size(after) > 0) {
        after.removeAll(before);
      }
      if (GenericUtils.isEmpty(after)) {
        throw new IOException(
            "Error binding to " + address + "[" + bindAddress + "]: no local addresses bound");
      }

      if (after.size() > 1) {
        throw new IOException(
            "Multiple local addresses have been bound for " + address + "[" + bindAddress + "]");
      }
      return (InetSocketAddress) after.iterator().next();
    } catch (IOException bindErr) {
      Set<SocketAddress> after = acceptor.getBoundAddresses();
      if (GenericUtils.isEmpty(after)) {
        close();
      }
      throw bindErr;
    }
  }