http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/Readable.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Readable.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Readable.java deleted file mode 100644 index 3075eb3..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/Readable.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util; - -import java.nio.ByteBuffer; -import java.util.Objects; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface Readable { - - int available(); - - void getRawBytes(byte[] data, int offset, int len); - - /** - * Wrap a {@link ByteBuffer} as a {@link Readable} instance - * - * @param buffer The {@link ByteBuffer} to wrap - never {@code null} - * @return The {@link Readable} wrapper - */ - static Readable readable(ByteBuffer buffer) { - Objects.requireNonNull(buffer, "No buffer to wrap"); - return new Readable() { - @Override - public int available() { - return buffer.remaining(); - } - - @Override - public void getRawBytes(byte[] data, int offset, int len) { - buffer.get(data, offset, len); - } - }; - } -}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/ReflectionUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/ReflectionUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/ReflectionUtils.java deleted file mode 100644 index 84a84f9..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/ReflectionUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.sshd.common.util; - -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public final class ReflectionUtils { - public static final Function<Field, String> FIELD_NAME_EXTRACTOR = f -> (f == null) ? null : f.getName(); - - private ReflectionUtils() { - throw new UnsupportedOperationException("No instance"); - } - - public static Collection<Field> getMatchingFields(Class<?> clazz, Predicate<? super Field> acceptor) { - return GenericUtils.selectMatchingMembers(acceptor, clazz.getFields()); - } - - public static Collection<Field> getMatchingDeclaredFields(Class<?> clazz, Predicate<? super Field> acceptor) { - return GenericUtils.selectMatchingMembers(acceptor, clazz.getDeclaredFields()); - } - - public static boolean isClassAvailable(ClassLoader cl, String className) { - try { - cl.loadClass(className); - return true; - } catch (Throwable ignored) { - return false; - } - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java deleted file mode 100644 index 53bca90..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/SelectorUtils.java +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util; - -import java.io.File; -import java.nio.file.FileSystem; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.StringTokenizer; - -/** - * <p>This is a utility class used by selectors and DirectoryScanner. The - * functionality more properly belongs just to selectors, but unfortunately - * DirectoryScanner exposed these as protected methods. Thus we have to - * support any subclasses of DirectoryScanner that may access these methods. - * </p> - * <p>This is a Singleton.</p> - * - * @author Arnout J. Kuiper - * <a href="mailto:[email protected]">[email protected]</a> - * @author Magesh Umasankar - * @author <a href="mailto:[email protected]">Bruce Atherton</a> - * @version $Id$ - * @since 1.5 - */ -public final class SelectorUtils { - - public static final String PATTERN_HANDLER_PREFIX = "["; - - public static final String PATTERN_HANDLER_SUFFIX = "]"; - - public static final String REGEX_HANDLER_PREFIX = "%regex" + PATTERN_HANDLER_PREFIX; - - public static final String ANT_HANDLER_PREFIX = "%ant" + PATTERN_HANDLER_PREFIX; - - /** - * Private Constructor - */ - private SelectorUtils() { - throw new UnsupportedOperationException("No instance allowed"); - } - - /** - * <p>Tests whether or not a given path matches the start of a given - * pattern up to the first "**".</p> - * - * <p>This is not a general purpose test and should only be used if you - * can live with false positives. For example, <code>pattern=**\a</code> - * and <code>str=b</code> will yield <code>true</code>.</p> - * - * @param pattern The pattern to match against. Must not be - * {@code null}. - * @param str The path to match, as a String. Must not be - * {@code null}. - * @return whether or not a given path matches the start of a given - * pattern up to the first "**". - */ - public static boolean matchPatternStart(String pattern, String str) { - return matchPatternStart(pattern, str, true); - } - - /** - * <p>Tests whether or not a given path matches the start of a given - * pattern up to the first "**".</p> - * - * <p>This is not a general purpose test and should only be used if you - * can live with false positives. For example, <code>pattern=**\a</code> - * and <code>str=b</code> will yield <code>true</code>.</p> - * - * @param pattern The pattern to match against. Must not be - * {@code null}. - * @param str The path to match, as a String. Must not be - * {@code null}. - * @param isCaseSensitive Whether or not matching should be performed - * case sensitively. - * @return whether or not a given path matches the start of a given - * pattern up to the first "**". - */ - public static boolean matchPatternStart(String pattern, String str, - boolean isCaseSensitive) { - if (pattern.length() > (REGEX_HANDLER_PREFIX.length() + PATTERN_HANDLER_SUFFIX.length() + 1) - && pattern.startsWith(REGEX_HANDLER_PREFIX) && pattern.endsWith(PATTERN_HANDLER_SUFFIX)) { - // FIXME: ICK! But we can't do partial matches for regex, so we have to reserve judgement until we have - // a file to deal with, or we can definitely say this is an exclusion... - return true; - } else { - if (pattern.length() > (ANT_HANDLER_PREFIX.length() + PATTERN_HANDLER_SUFFIX.length() + 1) - && pattern.startsWith(ANT_HANDLER_PREFIX) && pattern.endsWith(PATTERN_HANDLER_SUFFIX)) { - pattern = - pattern.substring(ANT_HANDLER_PREFIX.length(), pattern.length() - PATTERN_HANDLER_SUFFIX.length()); - } - - String altStr = str.replace('\\', '/'); - - return matchAntPathPatternStart(pattern, str, File.separator, isCaseSensitive) - || matchAntPathPatternStart(pattern, altStr, "/", isCaseSensitive); - } - } - - private static boolean matchAntPathPatternStart(String pattern, String str, String separator, boolean isCaseSensitive) { - // When str starts with a File.separator, pattern has to start with a - // File.separator. - // When pattern starts with a File.separator, str has to start with a - // File.separator. - if (str.startsWith(separator) != pattern.startsWith(separator)) { - return false; - } - - List<String> patDirs = tokenizePath(pattern, separator); - List<String> strDirs = tokenizePath(str, separator); - - int patIdxStart = 0; - int patIdxEnd = patDirs.size() - 1; - int strIdxStart = 0; - int strIdxEnd = strDirs.size() - 1; - - // up to first '**' - while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { - String patDir = patDirs.get(patIdxStart); - if (patDir.equals("**")) { - break; - } - if (!match(patDir, strDirs.get(strIdxStart), - isCaseSensitive)) { - return false; - } - patIdxStart++; - strIdxStart++; - } - - // CHECKSTYLE:OFF - if (strIdxStart > strIdxEnd) { - // String is exhausted - return true; - } else { - return patIdxStart <= patIdxEnd; - } - // CHECKSTYLE:ON - } - - /** - * Tests whether or not a given path matches a given pattern. - * - * @param pattern The pattern to match against. Must not be - * {@code null}. - * @param str The path to match, as a String. Must not be - * {@code null}. - * @return <code>true</code> if the pattern matches against the string, - * or <code>false</code> otherwise. - */ - public static boolean matchPath(String pattern, String str) { - return matchPath(pattern, str, true); - } - - /** - * Tests whether or not a given path matches a given pattern. - * - * @param pattern The pattern to match against. Must not be - * {@code null}. - * @param str The path to match, as a String. Must not be - * {@code null}. - * @param isCaseSensitive Whether or not matching should be performed - * case sensitively. - * @return <code>true</code> if the pattern matches against the string, - * or <code>false</code> otherwise. - */ - public static boolean matchPath(String pattern, String str, boolean isCaseSensitive) { - if (pattern.length() > (REGEX_HANDLER_PREFIX.length() + PATTERN_HANDLER_SUFFIX.length() + 1) - && pattern.startsWith(REGEX_HANDLER_PREFIX) && pattern.endsWith(PATTERN_HANDLER_SUFFIX)) { - pattern = pattern.substring(REGEX_HANDLER_PREFIX.length(), pattern.length() - - PATTERN_HANDLER_SUFFIX.length()); - - return str.matches(pattern); - } else { - if (pattern.length() > (ANT_HANDLER_PREFIX.length() + PATTERN_HANDLER_SUFFIX.length() + 1) - && pattern.startsWith(ANT_HANDLER_PREFIX) && pattern.endsWith(PATTERN_HANDLER_SUFFIX)) { - pattern = - pattern.substring(ANT_HANDLER_PREFIX.length(), pattern.length() - PATTERN_HANDLER_SUFFIX.length()); - } - - return matchAntPathPattern(pattern, str, isCaseSensitive); - } - } - - private static boolean matchAntPathPattern(String pattern, String str, boolean isCaseSensitive) { - // When str starts with a File.separator, pattern has to start with a - // File.separator. - // When pattern starts with a File.separator, str has to start with a - // File.separator. - if (str.startsWith(File.separator) != pattern.startsWith(File.separator)) { - return false; - } - - List<String> patDirs = tokenizePath(pattern, File.separator); - List<String> strDirs = tokenizePath(str, File.separator); - - int patIdxStart = 0; - int patIdxEnd = patDirs.size() - 1; - int strIdxStart = 0; - int strIdxEnd = strDirs.size() - 1; - - // up to first '**' - while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { - String patDir = patDirs.get(patIdxStart); - if (patDir.equals("**")) { - break; - } - if (!match(patDir, strDirs.get(strIdxStart), - isCaseSensitive)) { - patDirs = null; - strDirs = null; - return false; - } - patIdxStart++; - strIdxStart++; - } - if (strIdxStart > strIdxEnd) { - // String is exhausted - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!patDirs.get(i).equals("**")) { - patDirs = null; - strDirs = null; - return false; - } - } - return true; - } else { - if (patIdxStart > patIdxEnd) { - // String not exhausted, but pattern is. Failure. - patDirs = null; - strDirs = null; - return false; - } - } - - // up to last '**' - while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { - String patDir = patDirs.get(patIdxEnd); - if (patDir.equals("**")) { - break; - } - if (!match(patDir, strDirs.get(strIdxEnd), - isCaseSensitive)) { - patDirs = null; - strDirs = null; - return false; - } - patIdxEnd--; - strIdxEnd--; - } - if (strIdxStart > strIdxEnd) { - // String is exhausted - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!patDirs.get(i).equals("**")) { - patDirs = null; - strDirs = null; - return false; - } - } - return true; - } - - while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { - int patIdxTmp = -1; - for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { - if (patDirs.get(i).equals("**")) { - patIdxTmp = i; - break; - } - } - if (patIdxTmp == patIdxStart + 1) { - // '**/**' situation, so skip one - patIdxStart++; - continue; - } - // Find the pattern between padIdxStart & padIdxTmp in str between - // strIdxStart & strIdxEnd - int patLength = patIdxTmp - patIdxStart - 1; - int strLength = strIdxEnd - strIdxStart + 1; - int foundIdx = -1; - strLoop: - for (int i = 0; i <= strLength - patLength; i++) { - for (int j = 0; j < patLength; j++) { - String subPat = patDirs.get(patIdxStart + j + 1); - String subStr = strDirs.get(strIdxStart + i + j); - if (!match(subPat, subStr, isCaseSensitive)) { - continue strLoop; - } - } - - foundIdx = strIdxStart + i; - break; - } - - if (foundIdx == -1) { - patDirs = null; - strDirs = null; - return false; - } - - patIdxStart = patIdxTmp; - strIdxStart = foundIdx + patLength; - } - - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!patDirs.get(i).equals("**")) { - patDirs = null; - strDirs = null; - return false; - } - } - - return true; - } - - /** - * Tests whether or not a string matches against a pattern. - * The pattern may contain two special characters:<br> - * '*' means zero or more characters<br> - * '?' means one and only one character - * - * @param pattern The pattern to match against. - * Must not be {@code null}. - * @param str The string which must be matched against the pattern. - * Must not be {@code null}. - * @return <code>true</code> if the string matches against the pattern, - * or <code>false</code> otherwise. - */ - public static boolean match(String pattern, String str) { - return match(pattern, str, true); - } - - /** - * Tests whether or not a string matches against a pattern. - * The pattern may contain two special characters:<br> - * '*' means zero or more characters<br> - * '?' means one and only one character - * - * @param pattern The pattern to match against. - * Must not be {@code null}. - * @param str The string which must be matched against the pattern. - * Must not be {@code null}. - * @param isCaseSensitive Whether or not matching should be performed - * case sensitively. - * @return <code>true</code> if the string matches against the pattern, - * or <code>false</code> otherwise. - */ - @SuppressWarnings("PMD.AssignmentInOperand") - public static boolean match(String pattern, String str, boolean isCaseSensitive) { - char[] patArr = pattern.toCharArray(); - char[] strArr = str.toCharArray(); - int patIdxStart = 0; - int patIdxEnd = patArr.length - 1; - int strIdxStart = 0; - int strIdxEnd = strArr.length - 1; - char ch; - - boolean containsStar = false; - for (char aPatArr : patArr) { - if (aPatArr == '*') { - containsStar = true; - break; - } - } - - if (!containsStar) { - // No '*'s, so we make a shortcut - if (patIdxEnd != strIdxEnd) { - return false; // Pattern and string do not have the same size - } - for (int i = 0; i <= patIdxEnd; i++) { - ch = patArr[i]; - if ((ch != '?') && (!equals(ch, strArr[i], isCaseSensitive))) { - return false; // Character mismatch - } - } - return true; // String matches against pattern - } - - if (patIdxEnd == 0) { - return true; // Pattern contains only '*', which matches anything - } - - // Process characters before first star - // CHECKSTYLE:OFF - while (((ch = patArr[patIdxStart]) != '*') && (strIdxStart <= strIdxEnd)) { - if ((ch != '?') && (!equals(ch, strArr[strIdxStart], isCaseSensitive))) { - return false; // Character mismatch - } - patIdxStart++; - strIdxStart++; - } - // CHECKSTYLE:ON - - if (strIdxStart > strIdxEnd) { - // All characters in the string are used. Check if only '*'s are - // left in the pattern. If so, we succeeded. Otherwise failure. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - return true; - } - - // Process characters after last star - // CHECKSTYLE:OFF - while (((ch = patArr[patIdxEnd]) != '*') && (strIdxStart <= strIdxEnd)) { - if ((ch != '?') && (!equals(ch, strArr[strIdxEnd], isCaseSensitive))) { - return false; // Character mismatch - } - patIdxEnd--; - strIdxEnd--; - } - // CHECKSTYLE:ON - - if (strIdxStart > strIdxEnd) { - // All characters in the string are used. Check if only '*'s are - // left in the pattern. If so, we succeeded. Otherwise failure. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - return true; - } - - // process pattern between stars. padIdxStart and patIdxEnd point always to a '*'. - while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) { - int patIdxTmp = -1; - for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { - if (patArr[i] == '*') { - patIdxTmp = i; - break; - } - } - if (patIdxTmp == patIdxStart + 1) { - // Two stars next to each other, skip the first one. - patIdxStart++; - continue; - } - // Find the pattern between padIdxStart & padIdxTmp in str between - // strIdxStart & strIdxEnd - int patLength = patIdxTmp - patIdxStart - 1; - int strLength = strIdxEnd - strIdxStart + 1; - int foundIdx = -1; - strLoop: - for (int i = 0; i <= strLength - patLength; i++) { - for (int j = 0; j < patLength; j++) { - ch = patArr[patIdxStart + j + 1]; - if (ch != '?' && !equals(ch, strArr[strIdxStart + i + j], isCaseSensitive)) { - continue strLoop; - } - } - - foundIdx = strIdxStart + i; - break; - } - - if (foundIdx == -1) { - return false; - } - - patIdxStart = patIdxTmp; - strIdxStart = foundIdx + patLength; - } - - // All characters in the string are used. Check if only '*'s are left - // in the pattern. If so, we succeeded. Otherwise failure. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - return true; - } - - /** - * Tests whether two characters are equal. - * @param c1 1st character - * @param c2 2nd character - * @param isCaseSensitive Whether to compare case sensitive - * @return {@code true} if equal characters - */ - public static boolean equals(char c1, char c2, boolean isCaseSensitive) { - if (c1 == c2) { - return true; - } - if (!isCaseSensitive) { - // NOTE: Try both upper case and lower case as done by String.equalsIgnoreCase() - if (Character.toUpperCase(c1) == Character.toUpperCase(c2) - || Character.toLowerCase(c1) == Character.toLowerCase(c2)) { - return true; - } - } - return false; - } - - /** - * Breaks a path up into a Vector of path elements, tokenizing on - * <code>File.separator</code>. - * - * @param path Path to tokenize. Must not be {@code null}. - * @return a List of path elements from the tokenized path - */ - public static List<String> tokenizePath(String path) { - return tokenizePath(path, File.separator); - } - - public static List<String> tokenizePath(String path, String separator) { - List<String> ret = new ArrayList<>(); - StringTokenizer st = new StringTokenizer(path, separator); - while (st.hasMoreTokens()) { - ret.add(st.nextToken()); - } - return ret; - } - - /** /** - * Converts a path to one matching the target file system by applying the - * "slashification" rules, converting it to a local path and - * then translating its separator to the target file system one (if different - * than local one) - * @param path The input path - * @param pathSeparator The separator used to build the input path - * @param fs The target {@link FileSystem} - may not be {@code null} - * @return The transformed path - * @see #translateToLocalFileSystemPath(String, char, String) - */ - public static String translateToLocalFileSystemPath(String path, char pathSeparator, FileSystem fs) { - return translateToLocalFileSystemPath(path, pathSeparator, Objects.requireNonNull(fs, "No target file system").getSeparator()); - } - - /** - * Converts a path to one matching the target file system by applying the - * "slashification" rules, converting it to a local path and - * then translating its separator to the target file system one (if different - * than local one) - * @param path The input path - * @param pathSeparator The separator used to build the input path - * @param fsSeparator The target file system separator - * @return The transformed path - * @see #applySlashifyRules(String, char) - * @see #translateToLocalPath(String) - * @see #translateToFileSystemPath(String, String, String) - */ - public static String translateToLocalFileSystemPath(String path, char pathSeparator, String fsSeparator) { - // In case double slashes and other patterns are used - String slashified = applySlashifyRules(path, pathSeparator); - // In case we are running on Windows - String localPath = translateToLocalPath(slashified); - return translateToFileSystemPath(localPath, File.separator, fsSeparator); - } - - /** - * Applies the "slashification" rules as specified in - * <A HREF="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266">Single Unix Specification version 3, section 3.266</A> - * and <A HREF="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11">section 4.11 - Pathname resolution</A> - * @param path The original path - ignored if {@code null}/empty or does - * not contain any slashes - * @param sepChar The "slash" character - * @return The effective path - may be same as input if no changes required - */ - public static String applySlashifyRules(String path, char sepChar) { - if (GenericUtils.isEmpty(path)) { - return path; - } - - int curPos = path.indexOf(sepChar); - if (curPos < 0) { - return path; // no slashes to handle - } - - int lastPos = 0; - StringBuilder sb = null; - while (curPos < path.length()) { - curPos++; // skip the 1st '/' - - /* - * As per Single Unix Specification version 3, section 3.266: - * - * Multiple successive slashes are considered to be the - * same as one slash - */ - int nextPos = curPos; - while ((nextPos < path.length()) && (path.charAt(nextPos) == sepChar)) { - nextPos++; - } - - /* - * At this stage, nextPos is the first non-slash character after a - * possibly 'seqLen' sequence of consecutive slashes. - */ - int seqLen = nextPos - curPos; - if (seqLen > 0) { - if (sb == null) { - sb = new StringBuilder(path.length() - seqLen); - } - - if (lastPos < curPos) { - String clrText = path.substring(lastPos, curPos); - sb.append(clrText); - } - - lastPos = nextPos; - } - - if (nextPos >= path.length()) { - break; // no more data - } - - curPos = path.indexOf(sepChar, nextPos); - if (curPos < nextPos) { - break; // no more slashes - } - } - - // check if any leftovers for the modified path - if (sb != null) { - if (lastPos < path.length()) { - String clrText = path.substring(lastPos); - sb.append(clrText); - } - - path = sb.toString(); - } - - /* - * At this point we know for sure that 'path' contains only SINGLE - * slashes. According to section 4.11 - Pathname resolution - * - * A pathname that contains at least one non-slash character - * and that ends with one or more trailing slashes shall be - * resolved as if a single dot character ( '.' ) were appended - * to the pathname. - */ - if ((path.length() > 1) && (path.charAt(path.length() - 1) == sepChar)) { - return path + "."; - } else { - return path; - } - } - - /** - * Converts a possibly '/' separated path to a local path. <B>Note:</B> - * takes special care of Windows drive paths - e.g., {@code C:} - * by converting them to "C:\" - * - * @param path The original path - ignored if {@code null}/empty - * @return The local path - */ - public static String translateToLocalPath(String path) { - if (GenericUtils.isEmpty(path) || (File.separatorChar == '/')) { - return path; - } - - // This code is reached if we are running on Windows - String localPath = path.replace('/', File.separatorChar); - // check if '/c:' prefix - if ((localPath.charAt(0) == File.separatorChar) && isWindowsDriveSpecified(localPath, 1, localPath.length() - 1)) { - localPath = localPath.substring(1); - } - if (!isWindowsDriveSpecified(localPath)) { - return localPath; // assume a relative path - } - - /* - * Here we know that we have at least a "C:" string - make sure it - * is followed by the local file separator. Note: if all we have is - * just the drive, we will create a "C:\" path since this is the - * preferred Windows way to refer to root drives in the file system - */ - if (localPath.length() == 2) { - return localPath + File.separator; // all we have is "C:" - } else if (localPath.charAt(2) != File.separatorChar) { - // be nice and add the missing file separator - C:foo => C:\foo - return localPath.substring(0, 2) + File.separator + localPath.substring(2); - } else { - return localPath; - } - } - - public static boolean isWindowsDriveSpecified(CharSequence cs) { - return isWindowsDriveSpecified(cs, 0, GenericUtils.length(cs)); - } - - public static boolean isWindowsDriveSpecified(CharSequence cs, int offset, int len) { - if ((len < 2) || (cs.charAt(offset + 1) != ':')) { - return false; - } - - char drive = cs.charAt(offset); - return ((drive >= 'a') && (drive <= 'z')) || ((drive >= 'A') && (drive <= 'Z')); - } - - /** - * Converts a path containing a specific separator to one using the - * specified file-system one - * @param path The input path - ignored if {@code null}/empty - * @param pathSeparator The separator used to build the input path - may not - * be {@code null}/empty - * @param fs The target {@link FileSystem} - may not be {@code null} - * @return The path where the separator used to build it is replaced by - * the file-system one (if different) - * @see FileSystem#getSeparator() - * @see #translateToFileSystemPath(String, String, String) - */ - public static String translateToFileSystemPath(String path, String pathSeparator, FileSystem fs) { - return translateToFileSystemPath(path, pathSeparator, Objects.requireNonNull(fs, "No target file system").getSeparator()); - } - - /** - * Converts a path containing a specific separator to one using the - * specified file-system one - * @param path The input path - ignored if {@code null}/empty - * @param pathSeparator The separator used to build the input path - may not - * be {@code null}/empty - * @param fsSeparator The target file system separator - may not be {@code null}/empty - * @return The path where the separator used to build it is replaced by - * the file-system one (if different) - * @throws IllegalArgumentException if path or file-system separator are {@code null}/empty - * or if the separators are different and the path contains the target - * file-system separator as it would create an ambiguity - */ - public static String translateToFileSystemPath(String path, String pathSeparator, String fsSeparator) { - ValidateUtils.checkNotNullAndNotEmpty(pathSeparator, "Missing path separator"); - ValidateUtils.checkNotNullAndNotEmpty(fsSeparator, "Missing file-system separator"); - - if (GenericUtils.isEmpty(path) || Objects.equals(pathSeparator, fsSeparator)) { - return path; - } - - // make sure path does not contain the target separator - if (path.contains(fsSeparator)) { - ValidateUtils.throwIllegalArgumentException("File system replacement may yield ambiguous result for %s with separator=%s", path, fsSeparator); - } - - // check most likely case - if ((pathSeparator.length() == 1) && (fsSeparator.length() == 1)) { - return path.replace(pathSeparator.charAt(0), fsSeparator.charAt(0)); - } else { - return path.replace(pathSeparator, fsSeparator); - } - } - - /** - * Returns dependency information on these two files. If src has been - * modified later than target, it returns true. If target doesn't exist, - * it likewise returns true. Otherwise, target is newer than src and - * is not out of date, thus the method returns false. It also returns - * false if the src file doesn't even exist, since how could the - * target then be out of date. - * - * @param src the original file - * @param target the file being compared against - * @param granularity the amount in seconds of slack we will give in - * determining out of dateness - * @return whether the target is out of date - */ - public static boolean isOutOfDate(File src, File target, int granularity) { - if (!src.exists()) { - return false; - } - if (!target.exists()) { - return true; - } - return (src.lastModified() - granularity) > target.lastModified(); - } - - /** - * "Flattens" a string by removing all whitespace (space, tab, linefeed, - * carriage return, and formfeed). This uses StringTokenizer and the - * default set of tokens as documented in the single arguement constructor. - * - * @param input a String to remove all whitespace. - * @return a String that has had all whitespace removed. - */ - public static String removeWhitespace(String input) { - StringBuilder result = new StringBuilder(); - if (input != null) { - StringTokenizer st = new StringTokenizer(input); - while (st.hasMoreTokens()) { - result.append(st.nextToken()); - } - } - return result.toString(); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java deleted file mode 100644 index ea6a3dd..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.sshd.common.util; - -import java.lang.reflect.Proxy; -import java.util.EventListener; -import java.util.Objects; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface SshdEventListener extends EventListener { - - /** - * Makes sure that the listener is neither {@code null} nor a proxy - * - * @param <L> Type of {@link SshdEventListener} being validation - * @param listener The listener instance - * @param prefix Prefix text to be prepended to validation failure messages - * @return The validated instance - */ - static <L extends SshdEventListener> L validateListener(L listener, String prefix) { - Objects.requireNonNull(listener, prefix + ": no instance"); - ValidateUtils.checkTrue(!Proxy.isProxyClass(listener.getClass()), prefix + ": proxies N/A"); - return listener; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java deleted file mode 100644 index a55e5d6..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.sshd.common.util; - -import java.util.Collection; -import java.util.Map; -import java.util.function.Function; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public final class ValidateUtils { - private ValidateUtils() { - throw new UnsupportedOperationException("No instance"); - } - - public static <T> T checkNotNull(T t, String message) { - checkTrue(t != null, message); - return t; - } - - public static <T> T checkNotNull(T t, String message, Object arg) { - checkTrue(t != null, message, arg); - return t; - } - - public static <T> T checkNotNull(T t, String message, long value) { - checkTrue(t != null, message, value); - return t; - } - - public static <T> T checkNotNull(T t, String message, Object... args) { - checkTrue(t != null, message, args); - return t; - } - - public static String checkNotNullAndNotEmpty(String t, String message) { - t = checkNotNull(t, message).trim(); - checkTrue(GenericUtils.length(t) > 0, message); - return t; - } - - public static String checkNotNullAndNotEmpty(String t, String message, Object arg) { - t = checkNotNull(t, message, arg).trim(); - checkTrue(GenericUtils.length(t) > 0, message, arg); - return t; - } - - public static String checkNotNullAndNotEmpty(String t, String message, Object... args) { - t = checkNotNull(t, message, args).trim(); - checkTrue(GenericUtils.length(t) > 0, message, args); - return t; - } - - public static <K, V, M extends Map<K, V>> M checkNotNullAndNotEmpty(M t, String message, Object... args) { - t = checkNotNull(t, message, args); - checkTrue(GenericUtils.size(t) > 0, message, args); - return t; - } - - public static <T, C extends Collection<T>> C checkNotNullAndNotEmpty(C t, String message, Object... args) { - t = checkNotNull(t, message, args); - checkTrue(GenericUtils.size(t) > 0, message, args); - return t; - } - - public static <T, C extends Iterable<T>> C checkNotNullAndNotEmpty(C t, String message, Object... args) { - t = checkNotNull(t, message, args); - checkTrue(GenericUtils.isNotEmpty(t), message, args); - return t; - } - - public static byte[] checkNotNullAndNotEmpty(byte[] a, String message) { - a = checkNotNull(a, message); - checkTrue(NumberUtils.length(a) > 0, message); - return a; - } - - public static byte[] checkNotNullAndNotEmpty(byte[] a, String message, Object... args) { - a = checkNotNull(a, message, args); - checkTrue(NumberUtils.length(a) > 0, message, args); - return a; - } - - public static char[] checkNotNullAndNotEmpty(char[] a, String message) { - a = checkNotNull(a, message); - checkTrue(GenericUtils.length(a) > 0, message); - return a; - } - - public static char[] checkNotNullAndNotEmpty(char[] a, String message, Object... args) { - a = checkNotNull(a, message, args); - checkTrue(GenericUtils.length(a) > 0, message, args); - return a; - } - - public static int[] checkNotNullAndNotEmpty(int[] a, String message) { - a = checkNotNull(a, message); - checkTrue(NumberUtils.length(a) > 0, message); - return a; - } - - public static int[] checkNotNullAndNotEmpty(int[] a, String message, Object... args) { - a = checkNotNull(a, message, args); - checkTrue(NumberUtils.length(a) > 0, message, args); - return a; - } - - public static <T> T[] checkNotNullAndNotEmpty(T[] t, String message, Object... args) { - t = checkNotNull(t, message, args); - checkTrue(GenericUtils.length(t) > 0, message, args); - return t; - } - - public static <T> T checkInstanceOf(Object v, Class<T> expected, String message, long value) { - Class<?> actual = checkNotNull(v, message, value).getClass(); - checkTrue(expected.isAssignableFrom(actual), message, value); - return expected.cast(v); - } - - public static <T> T checkInstanceOf(Object v, Class<T> expected, String message) { - return checkInstanceOf(v, expected, message, GenericUtils.EMPTY_OBJECT_ARRAY); - } - - public static <T> T checkInstanceOf(Object v, Class<T> expected, String message, Object arg) { - Class<?> actual = checkNotNull(v, message, arg).getClass(); - checkTrue(expected.isAssignableFrom(actual), message, arg); - return expected.cast(v); - } - - public static <T> T checkInstanceOf(Object v, Class<T> expected, String message, Object... args) { - Class<?> actual = checkNotNull(v, message, args).getClass(); - checkTrue(expected.isAssignableFrom(actual), message, args); - return expected.cast(v); - } - - public static void checkTrue(boolean flag, String message) { - if (!flag) { - throwIllegalArgumentException(message, GenericUtils.EMPTY_OBJECT_ARRAY); - } - } - - public static void checkTrue(boolean flag, String message, long value) { - if (!flag) { - throwIllegalArgumentException(message, value); - } - } - - public static void checkTrue(boolean flag, String message, Object arg) { - if (!flag) { - throwIllegalArgumentException(message, arg); - } - } - - public static void checkTrue(boolean flag, String message, Object... args) { - if (!flag) { - throwIllegalArgumentException(message, args); - } - } - - public static void throwIllegalArgumentException(String format, Object... args) { - throw createFormattedException(IllegalArgumentException::new, format, args); - } - - public static void checkState(boolean flag, String message) { - if (!flag) { - throwIllegalStateException(message, GenericUtils.EMPTY_OBJECT_ARRAY); - } - } - - public static void checkState(boolean flag, String message, long value) { - if (!flag) { - throwIllegalStateException(message, value); - } - } - - public static void checkState(boolean flag, String message, Object arg) { - if (!flag) { - throwIllegalStateException(message, arg); - } - } - - public static void checkState(boolean flag, String message, Object... args) { - if (!flag) { - throwIllegalStateException(message, args); - } - } - - public static void throwIllegalStateException(String format, Object... args) { - throw createFormattedException(IllegalStateException::new, format, args); - } - - public static <T extends Throwable> T createFormattedException( - Function<? super String, ? extends T> constructor, String format, Object... args) { - String message = String.format(format, args); - return constructor.apply(message); - } - -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java b/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java deleted file mode 100644 index ed1aab7..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.sshd.common.util; - -import java.io.Serializable; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class VersionInfo implements Serializable, Comparable<VersionInfo> { - private static final long serialVersionUID = -9127482432228413836L; - - private final int majorVersion; - private final int minorVersion; - private final int release; - private final int buildNumber; - - public VersionInfo(int major, int minor) { - this(major, minor, 0, 0); - } - - public VersionInfo(int major, int minor, int release, int build) { - this.majorVersion = major; - this.minorVersion = minor; - this.release = release; - this.buildNumber = build; - } - - public final int getMajorVersion() { - return majorVersion; - } - - public final int getMinorVersion() { - return minorVersion; - } - - public final int getRelease() { - return release; - } - - public final int getBuildNumber() { - return buildNumber; - } - - @Override - public int hashCode() { - return NumberUtils.hashCode(getMajorVersion(), getMinorVersion(), getRelease(), getBuildNumber()); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (this == obj) { - return true; - } - if (getClass() != obj.getClass()) { - return false; - } - return compareTo((VersionInfo) obj) == 0; - } - - @Override - public int compareTo(VersionInfo o) { - if (o == null) { - return -1; // push nulls to end - } - if (o == this) { - return 0; - } - - int nRes = Integer.compare(getMajorVersion(), o.getMajorVersion()); - if (nRes == 0) { - nRes = Integer.compare(getMinorVersion(), o.getMinorVersion()); - } - if (nRes == 0) { - nRes = Integer.compare(getRelease(), o.getRelease()); - } - if (nRes == 0) { - nRes = Integer.compare(getBuildNumber(), o.getBuildNumber()); - } - - return nRes; - } - - @Override - public String toString() { - return NumberUtils.join('.', getMajorVersion(), getMinorVersion(), getRelease(), getBuildNumber()); - } - - /** - * Parses a version string - assumed to contain at most 4 non-negative - * components separated by a '.'. If less than 4 components are found, then - * the rest are assumed to be zero. If more than 4 components found, then - * only the 1st ones are parsed. - * - * @param version The version string - ignored if {@code null}/empty - * @return The parsed {@link VersionInfo} - or {@code null} if empty input - * @throws NumberFormatException If failed to parse any of the components - * @throws IllegalArgumentException If any of the parsed components is negative - */ - public static VersionInfo parse(String version) throws NumberFormatException { - String[] comps = GenericUtils.split(version, '.'); - if (GenericUtils.isEmpty(comps)) { - return null; - } - - int[] values = new int[4]; - int maxValues = Math.min(comps.length, values.length); - for (int index = 0; index < maxValues; index++) { - String c = comps[index]; - int v = Integer.parseInt(c); - ValidateUtils.checkTrue(v >= 0, "Invalid version component in %s", version); - values[index] = v; - } - - return new VersionInfo(values[0], values[1], values[2], values[3]); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java deleted file mode 100644 index dd61473..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util.buffer; - -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.interfaces.DSAParams; -import java.security.interfaces.DSAPrivateKey; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPrivateKeySpec; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.function.IntUnaryOperator; -import java.util.logging.Level; - -import org.apache.sshd.common.PropertyResolver; -import org.apache.sshd.common.SshException; -import org.apache.sshd.common.cipher.ECCurves; -import org.apache.sshd.common.config.keys.KeyUtils; -import org.apache.sshd.common.keyprovider.KeyPairProvider; -import org.apache.sshd.common.util.GenericUtils; -import org.apache.sshd.common.util.NumberUtils; -import org.apache.sshd.common.util.Readable; -import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser; -import org.apache.sshd.common.util.logging.SimplifiedLog; -import org.apache.sshd.common.util.security.SecurityUtils; - -/** - * Provides an abstract message buffer for encoding SSH messages - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public abstract class Buffer implements Readable { - protected final byte[] workBuf = new byte[Long.BYTES]; - - protected Buffer() { - super(); - } - - public abstract int rpos(); - - public abstract void rpos(int rpos); - - public abstract int wpos(); - - public abstract void wpos(int wpos); - - public abstract int capacity(); - - public abstract byte[] array(); - - public abstract void compact(); - - public byte[] getCompactData() { - int l = available(); - if (l > 0) { - byte[] b = new byte[l]; - System.arraycopy(array(), rpos(), b, 0, l); - return b; - } else { - return GenericUtils.EMPTY_BYTE_ARRAY; - } - } - - public void clear() { - clear(true); - } - - public abstract void clear(boolean wipeData); - - public boolean isValidMessageStructure(Class<?>... fieldTypes) { - return isValidMessageStructure(GenericUtils.isEmpty(fieldTypes) ? Collections.emptyList() : Arrays.asList(fieldTypes)); - } - - public boolean isValidMessageStructure(Collection<Class<?>> fieldTypes) { - if (GenericUtils.isEmpty(fieldTypes)) { - return true; - } - - int remainLen = available(); - int readOffset = 0; - for (Class<?> ft : fieldTypes) { - if ((ft == boolean.class) || (ft == Boolean.class) - || (ft == byte.class) || (ft == Byte.class)) { - if (remainLen < Byte.BYTES) { - return false; - } - - remainLen -= Byte.BYTES; - readOffset += Byte.BYTES; - } else if ((ft == short.class) || (ft == Short.class)) { - if (remainLen < Short.BYTES) { - return false; - } - - remainLen -= Short.BYTES; - readOffset += Short.BYTES; - } else if ((ft == int.class) || (ft == Integer.class)) { - if (remainLen < Integer.BYTES) { - return false; - } - - remainLen -= Integer.BYTES; - readOffset += Integer.BYTES; - } else if ((ft == long.class) || (ft == Long.class)) { - if (remainLen < Long.BYTES) { - return false; - } - - remainLen -= Long.BYTES; - readOffset += Long.BYTES; - } else if ((ft == byte[].class) || (ft == String.class)) { - if (remainLen < Integer.BYTES) { - return false; - } - - copyRawBytes(readOffset, workBuf, 0, Integer.BYTES); - remainLen -= Integer.BYTES; - readOffset += Integer.BYTES; - - long length = BufferUtils.getUInt(workBuf, 0, Integer.BYTES); - if (length > remainLen) { - return false; - } - - remainLen -= (int) length; - readOffset += (int) length; - } - } - - return true; - } - - protected abstract void copyRawBytes(int offset, byte[] buf, int pos, int len); - - public String toHex() { - return BufferUtils.toHex(array(), rpos(), available()); - } - - public void dumpHex(SimplifiedLog logger, String prefix, PropertyResolver resolver) { - dumpHex(logger, BufferUtils.DEFAULT_HEXDUMP_LEVEL, prefix, resolver); - } - - public void dumpHex(SimplifiedLog logger, Level level, String prefix, PropertyResolver resolver) { - BufferUtils.dumpHex(logger, level, prefix, resolver, BufferUtils.DEFAULT_HEX_SEPARATOR, array(), rpos(), available()); - } - - /*====================== - Read methods - ======================*/ - - public int getUByte() { - return getByte() & 0xFF; - } - - public byte getByte() { - ensureAvailable(Byte.BYTES); - getRawBytes(workBuf, 0, Byte.BYTES); - return workBuf[0]; - } - - public short getShort() { - ensureAvailable(Short.BYTES); - getRawBytes(workBuf, 0, Short.BYTES); - short v = (short) ((workBuf[1] << Byte.SIZE) & 0xFF00); - v |= (short) (workBuf[0] & 0xF); - return v; - } - - public int getInt() { - return (int) getUInt(); - } - - public long getUInt() { - ensureAvailable(Integer.BYTES); - getRawBytes(workBuf, 0, Integer.BYTES); - return BufferUtils.getUInt(workBuf, 0, Integer.BYTES); - } - - public long getLong() { - ensureAvailable(Long.BYTES); - getRawBytes(workBuf, 0, Long.BYTES); - long l = ((long) workBuf[0] << 56) & 0xff00000000000000L; - l |= ((long) workBuf[1] << 48) & 0x00ff000000000000L; - l |= ((long) workBuf[2] << 40) & 0x0000ff0000000000L; - l |= ((long) workBuf[3] << 32) & 0x000000ff00000000L; - l |= ((long) workBuf[4] << 24) & 0x00000000ff000000L; - l |= ((long) workBuf[5] << 16) & 0x0000000000ff0000L; - l |= ((long) workBuf[6] << 8) & 0x000000000000ff00L; - l |= (workBuf[7]) & 0x00000000000000ffL; - return l; - } - - @SuppressWarnings("PMD.BooleanGetMethodName") - public boolean getBoolean() { - return getByte() != 0; - } - - public String getString() { - return getString(StandardCharsets.UTF_8); - } - - /** - * @param usePrependedLength If {@code true} then there is a 32-bit - * value indicating the number of strings to read. Otherwise, the - * method will use a "greedy" reading of strings while more - * data available - * @return A {@link Collection} of the read strings - * @see #getStringList(boolean, Charset) - */ - public Collection<String> getStringList(boolean usePrependedLength) { - return getStringList(usePrependedLength, StandardCharsets.UTF_8); - } - - /** - * @param usePrependedLength If {@code true} then there is a 32-bit - * value indicating the number of strings to read. Otherwise, the - * method will use a "greedy" reading of strings while more - * data available - * @param charset The {@link Charset} to use for the string - * @return A {@link Collection} of the read strings - * @see #getStringList(int, Charset) - * @see #getAvailableStrings() - */ - public Collection<String> getStringList(boolean usePrependedLength, Charset charset) { - if (usePrependedLength) { - int count = getInt(); - return getStringList(count, charset); - } else { - return getAvailableStrings(charset); - } - } - - /** - * @return The remaining data as a list of strings - * @see #getAvailableStrings(Charset) - */ - public Collection<String> getAvailableStrings() { - return getAvailableStrings(StandardCharsets.UTF_8); - } - - /** - * @param charset The {@link Charset} to use for the strings - * @return The remaining data as a list of strings - * @see #available() - * @see #getString(Charset) - */ - public Collection<String> getAvailableStrings(Charset charset) { - Collection<String> list = new LinkedList<>(); - while (available() > 0) { - String s = getString(charset); - list.add(s); - } - - return list; - } - - /** - * @param count The <U>exact</U> number of strings to read - can be zero - * @return A {@link List} with the specified number of strings - * @see #getStringList(int, Charset) - */ - public List<String> getStringList(int count) { - return getStringList(count, StandardCharsets.UTF_8); - } - - /** - * @param count The <U>exact</U> number of strings to read - can be zero - * @param charset The {@link Charset} of the strings - * @return A {@link List} with the specified number of strings - * @see #getString(Charset) - */ - public List<String> getStringList(int count, Charset charset) { - if (count == 0) { - return Collections.emptyList(); - } - - List<String> list = new ArrayList<>(count); - for (int index = 0; index < count; index++) { - String s = getString(charset); - list.add(s); - } - - return list; - } - - public abstract String getString(Charset charset); - - public BigInteger getMPInt() { - return new BigInteger(getMPIntAsBytes()); - } - - public byte[] getMPIntAsBytes() { - return getBytes(); - } - - public byte[] getBytes() { - int len = getInt(); - if (len < 0) { - throw new BufferException("Bad item length: " + len); - } - ensureAvailable(len); - byte[] b = new byte[len]; - getRawBytes(b); - return b; - } - - public void getRawBytes(byte[] buf) { - getRawBytes(buf, 0, buf.length); - } - - public PublicKey getPublicKey() throws SshException { - return getPublicKey(BufferPublicKeyParser.DEFAULT); - } - - /** - * @param parser A {@link BufferPublicKeyParser} to extract the key from the buffer - * - never {@code null} - * @return The extracted {@link PublicKey} - may be {@code null} if the parser so decided - * @throws SshException If failed to extract the key - * @see #getRawPublicKey(BufferPublicKeyParser) - */ - public PublicKey getPublicKey(BufferPublicKeyParser<? extends PublicKey> parser) throws SshException { - int ow = wpos(); - int len = getInt(); - wpos(rpos() + len); - try { - return getRawPublicKey(parser); - } finally { - wpos(ow); - } - } - - public PublicKey getRawPublicKey() throws SshException { - return getRawPublicKey(BufferPublicKeyParser.DEFAULT); - } - - /** - * @param parser A {@link BufferPublicKeyParser} to extract the key from the buffer - * - never {@code null} - * @return The extracted {@link PublicKey} - may be {@code null} if the parser so decided - * @throws SshException If failed to extract the key - */ - public PublicKey getRawPublicKey(BufferPublicKeyParser<? extends PublicKey> parser) throws SshException { - Objects.requireNonNull(parser, "No key data parser"); - try { - String keyType = getString(); - if (!parser.isKeyTypeSupported(keyType)) { - throw new NoSuchAlgorithmException("Key type=" + keyType + ") not supported by parser=" + parser); - } - - return parser.getRawPublicKey(keyType, this); - } catch (GeneralSecurityException e) { - throw new SshException(e); - } - } - - public KeyPair getKeyPair() throws SshException { - try { - final PublicKey pub; - final PrivateKey prv; - final String keyAlg = getString(); - if (KeyPairProvider.SSH_RSA.equals(keyAlg)) { - BigInteger e = getMPInt(); - BigInteger n = getMPInt(); - BigInteger d = getMPInt(); - BigInteger qInv = getMPInt(); - BigInteger q = getMPInt(); - BigInteger p = getMPInt(); - BigInteger dP = d.remainder(p.subtract(BigInteger.valueOf(1))); - BigInteger dQ = d.remainder(q.subtract(BigInteger.valueOf(1))); - KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyUtils.RSA_ALGORITHM); - pub = keyFactory.generatePublic(new RSAPublicKeySpec(n, e)); - prv = keyFactory.generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv)); - } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) { - BigInteger p = getMPInt(); - BigInteger q = getMPInt(); - BigInteger g = getMPInt(); - BigInteger y = getMPInt(); - BigInteger x = getMPInt(); - KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyUtils.DSS_ALGORITHM); - pub = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); - prv = keyFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g)); - } else if (KeyPairProvider.SSH_ED25519.equals(keyAlg)) { - return SecurityUtils.extractEDDSAKeyPair(this, keyAlg); - } else { - ECCurves curve = ECCurves.fromKeyType(keyAlg); - if (curve == null) { - throw new NoSuchAlgorithmException("Unsupported key pair algorithm: " + keyAlg); - } - String curveName = curve.getName(); - ECParameterSpec params = curve.getParameters(); - return extractEC(curveName, params); - } - - return new KeyPair(pub, prv); - } catch (GeneralSecurityException e) { - throw new SshException(e); - } - } - - protected KeyPair extractEC(String expectedCurveName, ECParameterSpec spec) throws GeneralSecurityException { - String curveName = getString(); - if (!expectedCurveName.equals(curveName)) { - throw new InvalidKeySpecException("extractEC(" + expectedCurveName + ") mismatched curve name: " + curveName); - } - - byte[] groupBytes = getBytes(); - BigInteger exponent = getMPInt(); - - if (spec == null) { - throw new InvalidKeySpecException("extractEC(" + expectedCurveName + ") missing parameters for curve"); - } - - ECPoint group; - try { - group = ECCurves.octetStringToEcPoint(groupBytes); - } catch (RuntimeException e) { - throw new InvalidKeySpecException("extractEC(" + expectedCurveName + ")" - + " failed (" + e.getClass().getSimpleName() + ")" - + " to decode EC group for curve: " + e.getMessage(), - e); - } - - KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyUtils.EC_ALGORITHM); - PublicKey pubKey = keyFactory.generatePublic(new ECPublicKeySpec(group, spec)); - PrivateKey privKey = keyFactory.generatePrivate(new ECPrivateKeySpec(exponent, spec)); - return new KeyPair(pubKey, privKey); - } - - public void ensureAvailable(int reqLen) throws BufferException { - int availLen = available(); - if (availLen < reqLen) { - throw new BufferException("Underflow: requested=" + reqLen + ", available=" + availLen); - } - } - - /*====================== - Write methods - ======================*/ - - public void putByte(byte b) { - ensureCapacity(Byte.BYTES); - workBuf[0] = b; - putRawBytes(workBuf, 0, Byte.BYTES); - } - - public void putBuffer(Readable buffer) { - putBuffer(buffer, true); - } - - public abstract int putBuffer(Readable buffer, boolean expand); - - public abstract void putBuffer(ByteBuffer buffer); - - /** - * Writes 16 bits - * - * @param i The 16-bit value - */ - public void putShort(int i) { - ensureCapacity(Short.BYTES); - workBuf[0] = (byte) (i >> 8); - workBuf[1] = (byte) i; - putRawBytes(workBuf, 0, Short.BYTES); - } - - /** - * Writes 32 bits - * - * @param i The 32-bit value - */ - public void putInt(long i) { - BufferUtils.validateInt32Value(i, "Invalid 32-bit value: %d"); - ensureCapacity(Integer.BYTES); - BufferUtils.putUInt(i, workBuf, 0, Integer.BYTES); - putRawBytes(workBuf, 0, Integer.BYTES); - } - - /** - * Writes 64 bits - * - * @param i The 64-bit value - */ - public void putLong(long i) { - ensureCapacity(Long.BYTES); - workBuf[0] = (byte) (i >> 56); - workBuf[1] = (byte) (i >> 48); - workBuf[2] = (byte) (i >> 40); - workBuf[3] = (byte) (i >> 32); - workBuf[4] = (byte) (i >> 24); - workBuf[5] = (byte) (i >> 16); - workBuf[6] = (byte) (i >> 8); - workBuf[7] = (byte) i; - putRawBytes(workBuf, 0, Long.BYTES); - } - - public void putBoolean(boolean b) { - putByte(b ? (byte) 1 : (byte) 0); - } - - /** - * Adds the bytes to the buffer and wipes the data from the - * input buffer <U>after</U> having added it - useful for sensitive - * information such as password - * - * @param b The buffer to add - OK if {@code null} - */ - public void putAndWipeBytes(byte[] b) { - putAndWipeBytes(b, 0, NumberUtils.length(b)); - } - - public void putAndWipeBytes(byte[] b, int off, int len) { - putBytes(b, off, len); - - for (int pos = off, index = 0; index < len; pos++, index++) { - b[pos] = (byte) 0; - } - } - - public void putBytes(byte[] b) { - putBytes(b, 0, NumberUtils.length(b)); - } - - public void putBytes(byte[] b, int off, int len) { - putInt(len); - putRawBytes(b, off, len); - } - - /** - * Encodes the {@link Objects#toString(Object, String) toString} value of each member. - * - * @param objects The objects to be encoded in the buffer - OK if - * {@code null}/empty - * @param prependLength If {@code true} then the list is preceded by - * a 32-bit count of the number of members in the list - * @see #putStringList(Collection, Charset, boolean) - */ - public void putStringList(Collection<?> objects, boolean prependLength) { - putStringList(objects, StandardCharsets.UTF_8, prependLength); - } - - /** - * Encodes the {@link Objects#toString(Object, String) toString} value of each member - * - * @param objects The objects to be encoded in the buffer - OK if - * {@code null}/empty - * @param charset The {@link Charset} to use for encoding - * @param prependLength If {@code true} then the list is preceded by - * a 32-bit count of the number of members in the list - * @see #putString(String, Charset) - */ - public void putStringList(Collection<?> objects, Charset charset, boolean prependLength) { - int numObjects = GenericUtils.size(objects); - if (prependLength) { - putInt(numObjects); - } - - if (numObjects <= 0) { - return; - } - - objects.forEach(o -> putString(Objects.toString(o, null), charset)); - } - - public void putString(String string) { - putString(string, StandardCharsets.UTF_8); - } - - public void putString(String string, Charset charset) { - if (GenericUtils.isEmpty(string)) { - putBytes(GenericUtils.EMPTY_BYTE_ARRAY); - } else { - putBytes(string.getBytes(charset)); - } - } - - /** - * Zeroes the input array <U>after</U> having put the characters in the - * buffer - useful for sensitive information such as passwords - * - * @param chars The characters to put in the buffer - may be {@code null}/empty - * @see #putAndWipeChars(char[], Charset) - * @see #putChars(char[], Charset) - */ - public void putAndWipeChars(char[] chars) { - putAndWipeChars(chars, 0, GenericUtils.length(chars)); - } - - public void putAndWipeChars(char[] chars, int offset, int len) { - putAndWipeChars(chars, offset, len, StandardCharsets.UTF_8); - } - - public void putAndWipeChars(char[] chars, Charset charset) { - putAndWipeChars(chars, 0, GenericUtils.length(chars), charset); - } - - public void putAndWipeChars(char[] chars, int offset, int len, Charset charset) { - putChars(chars, offset, len, charset); - for (int pos = offset, index = 0; index < len; index++, pos++) { - chars[pos] = '\0'; - } - } - - public void putChars(char[] chars) { - putChars(chars, 0, GenericUtils.length(chars)); - } - - public void putChars(char[] chars, int offset, int len) { - putChars(chars, offset, len, StandardCharsets.UTF_8); - } - - public void putChars(char[] chars, Charset charset) { - putChars(chars, 0, GenericUtils.length(chars), charset); - } - - public void putChars(char[] chars, int offset, int len, Charset charset) { - if (len <= 0) { - putBytes(GenericUtils.EMPTY_BYTE_ARRAY); - } else { - putBuffer(charset.encode(CharBuffer.wrap(chars, offset, len))); - } - } - - public void putMPInt(BigInteger bi) { - putMPInt(bi.toByteArray()); - } - - public void putMPInt(byte[] foo) { - if ((foo[0] & 0x80) != 0) { - putInt(foo.length + 1 /* padding */); - putByte((byte) 0); - } else { - putInt(foo.length); - } - putRawBytes(foo); - } - - public void putRawBytes(byte[] d) { - putRawBytes(d, 0, d.length); - } - - public abstract void putRawBytes(byte[] d, int off, int len); - - public void putPublicKey(PublicKey key) { - int ow = wpos(); - putInt(0); - int ow1 = wpos(); - putRawPublicKey(key); - int ow2 = wpos(); - wpos(ow); - putInt(ow2 - ow1); - wpos(ow2); - } - - public void putRawPublicKey(PublicKey key) { - Objects.requireNonNull(key, "No key"); - if (key instanceof RSAPublicKey) { - RSAPublicKey rsaPub = (RSAPublicKey) key; - - putString(KeyPairProvider.SSH_RSA); - putMPInt(rsaPub.getPublicExponent()); - putMPInt(rsaPub.getModulus()); - } else if (key instanceof DSAPublicKey) { - DSAPublicKey dsaPub = (DSAPublicKey) key; - DSAParams dsaParams = dsaPub.getParams(); - - putString(KeyPairProvider.SSH_DSS); - putMPInt(dsaParams.getP()); - putMPInt(dsaParams.getQ()); - putMPInt(dsaParams.getG()); - putMPInt(dsaPub.getY()); - } else if (key instanceof ECPublicKey) { - ECPublicKey ecKey = (ECPublicKey) key; - ECParameterSpec ecParams = ecKey.getParams(); - ECCurves curve = ECCurves.fromCurveParameters(ecParams); - if (curve == null) { - throw new BufferException("Unsupported EC curve parameters"); - } - - putString(curve.getKeyType()); - putString(curve.getName()); - putBytes(ECCurves.encodeECPoint(ecKey.getW(), ecParams)); - } else if (SecurityUtils.EDDSA.equals(key.getAlgorithm())) { - SecurityUtils.putRawEDDSAPublicKey(this, key); - } else { - throw new BufferException("Unsupported raw public key algorithm: " + key.getAlgorithm()); - } - } - - public void putKeyPair(KeyPair kp) { - PublicKey pubKey = kp.getPublic(); - PrivateKey prvKey = kp.getPrivate(); - if (prvKey instanceof RSAPrivateCrtKey) { - RSAPublicKey rsaPub = (RSAPublicKey) pubKey; - RSAPrivateCrtKey rsaPrv = (RSAPrivateCrtKey) prvKey; - - putString(KeyPairProvider.SSH_RSA); - putMPInt(rsaPub.getPublicExponent()); - putMPInt(rsaPub.getModulus()); - putMPInt(rsaPrv.getPrivateExponent()); - putMPInt(rsaPrv.getCrtCoefficient()); - putMPInt(rsaPrv.getPrimeQ()); - putMPInt(rsaPrv.getPrimeP()); - } else if (pubKey instanceof DSAPublicKey) { - DSAPublicKey dsaPub = (DSAPublicKey) pubKey; - DSAParams dsaParams = dsaPub.getParams(); - DSAPrivateKey dsaPrv = (DSAPrivateKey) prvKey; - - putString(KeyPairProvider.SSH_DSS); - putMPInt(dsaParams.getP()); - putMPInt(dsaParams.getQ()); - putMPInt(dsaParams.getG()); - putMPInt(dsaPub.getY()); - putMPInt(dsaPrv.getX()); - } else if (pubKey instanceof ECPublicKey) { - ECPublicKey ecPub = (ECPublicKey) pubKey; - ECPrivateKey ecPriv = (ECPrivateKey) prvKey; - ECParameterSpec ecParams = ecPub.getParams(); - ECCurves curve = ECCurves.fromCurveParameters(ecParams); - if (curve == null) { - throw new BufferException("Unsupported EC curve parameters"); - } - - putString(curve.getKeyType()); - putString(curve.getName()); - putBytes(ECCurves.encodeECPoint(ecPub.getW(), ecParams)); - putMPInt(ecPriv.getS()); - } else if (SecurityUtils.EDDSA.equals(pubKey.getAlgorithm())) { - SecurityUtils.putEDDSAKeyPair(this, pubKey, prvKey); - } else { - throw new BufferException("Unsupported key pair algorithm: " + pubKey.getAlgorithm()); - } - } - - protected void ensureCapacity(int capacity) { - ensureCapacity(capacity, BufferUtils.DEFAULT_BUFFER_GROWTH_FACTOR); - } - - /** - * @param capacity The requires capacity - * @param growthFactor An {@link IntUnaryOperator} that is invoked - * if the current capacity is insufficient. The argument is the minimum - * required new data length, the function result should be the - * effective new data length to be allocated - if less than minimum - * then an exception is thrown - */ - public abstract void ensureCapacity(int capacity, IntUnaryOperator growthFactor); - - protected abstract int size(); - - @Override - public String toString() { - return "Buffer [rpos=" + rpos() + ", wpos=" + wpos() + ", size=" + size() + "]"; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java deleted file mode 100644 index 93f4e6b..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util.buffer; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class BufferException extends RuntimeException { - private static final long serialVersionUID = 658645233475011039L; - - public BufferException(String message) { - super(message); - } -} \ No newline at end of file
