You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tw...@apache.org on 2021/11/22 21:09:26 UTC

[mina-sshd] branch master updated (c7d83d0 -> c80b88f)

This is an automated email from the ASF dual-hosted git repository.

twolf pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git.


    from c7d83d0  Fix creationTime in SftpHelper#writeAttrsV4
     new 067e734  SFTP: support file timestamps with sub-millisecond resolution
     new c80b88f  Fix Buffer.putRawPublicKey() for hardware keys

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/sshd/common/config/keys/KeyUtils.java   |  6 +++-
 .../org/apache/sshd/common/util/buffer/Buffer.java |  4 +++
 .../org/apache/sshd/sftp/common/SftpHelper.java    | 42 +++++++++++++---------
 3 files changed, 35 insertions(+), 17 deletions(-)

[mina-sshd] 01/02: SFTP: support file timestamps with sub-millisecond resolution

Posted by tw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

twolf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 067e734ae9ded8391a7ecd35e631b6144783236b
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Mon Nov 22 14:40:54 2021 +0100

    SFTP: support file timestamps with sub-millisecond resolution
    
    Refactor the reading and writing of FileTimes to avoid manual nanosecond
    calculations. Go through Instant instead. On writing, this may saturate,
    but for times that far in the past or future nanos are irrelevant. On
    reading, drop nanos if the value would be outside the range of Instant.
    
    The advantage of doing it this way is that we can actually report and
    recover sub-millisecond timestamps (for SFTP version >= 4). Newer Java
    does report file timestamps with the OS resolution (100ns on Windows/
    NTFS, may be even lower on other OSes depending on the file system).
---
 .../org/apache/sshd/sftp/common/SftpHelper.java    | 42 +++++++++++++---------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
index 1bf606b..5de859d 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
@@ -40,6 +40,8 @@ import java.nio.file.attribute.PosixFilePermissions;
 import java.nio.file.attribute.UserPrincipal;
 import java.nio.file.attribute.UserPrincipalNotFoundException;
 import java.security.Principal;
+import java.time.DateTimeException;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -375,8 +377,8 @@ public final class SftpHelper {
             }
 
             if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
-                buffer = SftpHelper.writeTime(buffer, sftpVersion, flagsMask, attributes.getAccessTime());
-                buffer = SftpHelper.writeTime(buffer, sftpVersion, flagsMask, attributes.getModifyTime());
+                buffer = writeTime(buffer, sftpVersion, flagsMask, attributes.getAccessTime());
+                buffer = writeTime(buffer, sftpVersion, flagsMask, attributes.getModifyTime());
             }
         } else if (sftpVersion >= SftpConstants.SFTP_V4) {
             for (Attribute a : flags) {
@@ -437,16 +439,16 @@ public final class SftpHelper {
                 buffer.putInt(attributes.getPermissions());
             }
             if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACCESSTIME) != 0) {
-                buffer = SftpHelper.writeTime(buffer, sftpVersion, flagsMask, attributes.getAccessTime());
+                buffer = writeTime(buffer, sftpVersion, flagsMask, attributes.getAccessTime());
             }
             if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_CREATETIME) != 0) {
-                buffer = SftpHelper.writeTime(buffer, sftpVersion, flagsMask, attributes.getCreateTime());
+                buffer = writeTime(buffer, sftpVersion, flagsMask, attributes.getCreateTime());
             }
             if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME) != 0) {
-                buffer = SftpHelper.writeTime(buffer, sftpVersion, flagsMask, attributes.getModifyTime());
+                buffer = writeTime(buffer, sftpVersion, flagsMask, attributes.getModifyTime());
             }
             if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACL) != 0) {
-                buffer = SftpHelper.writeACLs(buffer, sftpVersion, attributes.getAcl());
+                buffer = writeACLs(buffer, sftpVersion, attributes.getAcl());
             }
 
             // TODO: for v5 ? 6? add CTIME (see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-16 - v6)
@@ -455,7 +457,7 @@ public final class SftpHelper {
         }
 
         if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_EXTENDED) != 0) {
-            buffer = SftpHelper.writeExtensions(buffer, attributes.getExtensions());
+            buffer = writeExtensions(buffer, attributes.getExtensions());
         }
 
         return buffer;
@@ -1165,9 +1167,7 @@ public final class SftpHelper {
         if (version >= SftpConstants.SFTP_V4) {
             buffer.putLong(time.to(TimeUnit.SECONDS));
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_SUBSECOND_TIMES) != 0) {
-                long nanos = time.to(TimeUnit.NANOSECONDS);
-                nanos = nanos % TimeUnit.SECONDS.toNanos(1);
-                buffer.putInt((int) nanos);
+                buffer.putInt(time.toInstant().getNano());
             }
         } else {
             buffer.putInt(time.to(TimeUnit.SECONDS));
@@ -1187,13 +1187,23 @@ public final class SftpHelper {
     public static FileTime readTime(Buffer buffer, int version, int flags) {
         // for v3 see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#page-8
         // for v6 see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-16
-        long secs = (version >= SftpConstants.SFTP_V4) ? buffer.getLong() : buffer.getUInt();
-        long millis = TimeUnit.SECONDS.toMillis(secs);
-        if ((version >= SftpConstants.SFTP_V4) && ((flags & SftpConstants.SSH_FILEXFER_ATTR_SUBSECOND_TIMES) != 0)) {
-            long nanoseconds = buffer.getUInt();
-            millis += TimeUnit.NANOSECONDS.toMillis(nanoseconds);
+        long secs;
+        if (version >= SftpConstants.SFTP_V4) {
+            secs = buffer.getLong();
+            if ((flags & SftpConstants.SSH_FILEXFER_ATTR_SUBSECOND_TIMES) != 0) {
+                long nanos = buffer.getUInt();
+                if (nanos != 0) {
+                    try {
+                        return FileTime.from(Instant.ofEpochSecond(secs, nanos));
+                    } catch (DateTimeException | ArithmeticException e) {
+                        // Beyond Instant range; drop nanos
+                    }
+                }
+            }
+        } else {
+            secs = buffer.getUInt();
         }
-        return FileTime.from(millis, TimeUnit.MILLISECONDS);
+        return FileTime.from(secs, TimeUnit.SECONDS);
     }
 
     /**

[mina-sshd] 02/02: Fix Buffer.putRawPublicKey() for hardware keys

Posted by tw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

twolf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit c80b88f933c8aadca2e4d908bf3bcab1f03065c5
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Mon Nov 22 19:52:53 2021 +0100

    Fix Buffer.putRawPublicKey() for hardware keys
    
    Buffer.putRawPublicKey() did not account for sk-* keys. Apache MINA
    sshd supports these keys only on the server side; so the worst effect
    was that the fingerprint was reported as "BufferException". (Supporting
    these keys on the client side would involve calling a dynamic native
    library (with address space protection, i.e., via a separate process)).
    
    Also make KeyUtils.getKeyType return the correct string for sk-* keys,
    and at least report the exception and its message in the fingerprint
    when computing the fingerprint fails.
    
    Note that Apache MINA sshd does not support the sk-* certificate key
    types yet.
---
 .../src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java  | 6 +++++-
 .../src/main/java/org/apache/sshd/common/util/buffer/Buffer.java    | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
index 0e711b0..5d5502e 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
@@ -651,7 +651,7 @@ public final class KeyUtils {
             buffer.putRawPublicKey(key);
             return DigestUtils.getFingerPrint(d, buffer.array(), 0, buffer.wpos());
         } catch (Exception e) {
-            return e.getClass().getSimpleName();
+            return e.toString();
         }
     }
 
@@ -841,8 +841,12 @@ public final class KeyUtils {
             } else {
                 return curve.getKeyType();
             }
+        } else if (key instanceof SkEcdsaPublicKey) {
+            return SkECDSAPublicKeyEntryDecoder.KEY_TYPE;
         } else if (SecurityUtils.EDDSA.equalsIgnoreCase(key.getAlgorithm())) {
             return KeyPairProvider.SSH_ED25519;
+        } else if (key instanceof SkED25519PublicKey) {
+            return SkED25519PublicKeyEntryDecoder.KEY_TYPE;
         } else if (key instanceof OpenSshCertificate) {
             return ((OpenSshCertificate) key).getKeyType();
         }
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
index 55e419f..4c30537 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
@@ -61,6 +61,7 @@ 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.config.keys.OpenSshCertificate;
+import org.apache.sshd.common.config.keys.u2f.SecurityKeyPublicKey;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.NumberUtils;
@@ -990,6 +991,9 @@ public abstract class Buffer implements Readable {
             putBytes(ecPoint);
         } else if (SecurityUtils.EDDSA.equals(key.getAlgorithm())) {
             SecurityUtils.putRawEDDSAPublicKey(this, key);
+        } else if (key instanceof SecurityKeyPublicKey) {
+            putRawPublicKeyBytes(((SecurityKeyPublicKey<?>) key).getDelegatePublicKey());
+            putString(((SecurityKeyPublicKey<?>) key).getAppName());
         } else if (key instanceof OpenSshCertificate) {
             OpenSshCertificate cert = (OpenSshCertificate) key;