Skip to content

Commit

Permalink
feat: add support for additional host key types
Browse files Browse the repository at this point in the history
also fixes up support for crystal 0.36.0
  • Loading branch information
stakach committed Jan 28, 2021
1 parent b8980e0 commit 5937c3b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 11 deletions.
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: ssh2
version: 1.4.2
version: 1.5.0

development_dependencies:
ameba:
Expand Down
14 changes: 13 additions & 1 deletion spec/ssh2_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,25 @@ describe SSH2::KnownHosts do
known_hosts = session.knownhosts
key, key_type = session.hostkey
typemask = LibSSH2::TypeMask::PLAIN

# NOTE:: technically the type mask can be generated programatically
# by shifting the key_type integer value by 18
# https://github.com/libssh2/libssh2/blob/6c7769dcc422250d14af1b06fce378b6ee009440/include/libssh2.h#L996
case key_type
when LibSSH2::HostKeyType::RSA
typemask |= LibSSH2::TypeMask::KEY_SSHRSA
when LibSSH2::HostKeyType::DSS
typemask |= LibSSH2::TypeMask::KEY_SSHDSS
when LibSSH2::HostKeyType::ECDSA_256
typemask |= LibSSH2::TypeMask::KEY_ECDSA_256
when LibSSH2::HostKeyType::ECDSA_384
typemask |= LibSSH2::TypeMask::KEY_ECDSA_384
when LibSSH2::HostKeyType::ECDSA_521
typemask |= LibSSH2::TypeMask::KEY_ECDSA_521
when LibSSH2::HostKeyType::ED25519
typemask |= LibSSH2::TypeMask::KEY_ED25519
else
fail "unknown key_type"
fail "unknown key_type: #{key_type}"
end
known_hosts.add("localhost", "", key, "comment", typemask)
known_hosts.add("127.0.0.1", "", key, "comment", typemask)
Expand Down
26 changes: 19 additions & 7 deletions src/lib_ssh2.cr
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,15 @@ lib LibSSH2
LANG_SC = 9
end

# https://github.com/libssh2/libssh2/blob/6c7769dcc422250d14af1b06fce378b6ee009440/include/libssh2.h#L423
enum HostKeyType
UNKNOWN = 0
RSA = 1
DSS = 2
UNKNOWN = 0
RSA = 1
DSS = 2
ECDSA_256 = 3
ECDSA_384 = 4
ECDSA_521 = 5
ED25519 = 6
end

enum DisconnectReason
Expand Down Expand Up @@ -191,6 +196,7 @@ Void*) -> Void

alias KnownHosts = Void*

# https://github.com/libssh2/libssh2/blob/6c7769dcc422250d14af1b06fce378b6ee009440/include/libssh2.h#L994
@[Flags]
enum TypeMask
PLAIN = 1
Expand All @@ -200,10 +206,16 @@ Void*) -> Void
KEYENC_RAW = (1 << 16)
KEYENC_BASE64 = (2 << 16)

KEY_RSA1 = (1 << 18)
KEY_SSHRSA = (2 << 18)
KEY_SSHDSS = (3 << 18)
KEY_UNKNOWN = (7 << 18)
KEY_RSA1 = (1 << 18)
KEY_SSHRSA = (2 << 18)
KEY_SSHDSS = (3 << 18)

KEY_ECDSA_256 = (4 << 18)
KEY_ECDSA_384 = (5 << 18)
KEY_ECDSA_521 = (6 << 18)
KEY_ED25519 = (7 << 18)

KEY_UNKNOWN = (15 << 18)
end

enum KnownHostCheck
Expand Down
6 changes: 4 additions & 2 deletions src/session.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class SSH2::Session
handshake
end

@handle : Pointer(Void) = Pointer(Void).new(0)

def self.connect(host, port = 22)
socket = TCPSocket.new(host, port)
new(socket)
Expand Down Expand Up @@ -92,8 +94,8 @@ class SSH2::Session
INTERACTIVE_CB = Proc(UInt8*, Int32, UInt8*, Int32, Int32, Void*, LibSSH2::Password*, Void*, Void).new do |name, name_len, instruction, instruction_len, num_prompts, _prompts, responses, data|
# This is the number of response structures we can fill
if num_prompts > 0
uname = String.new(name, name_len)
welcome = String.new(instruction, instruction_len)
uname = name.null? ? "" : String.new(name, name_len)
welcome = instruction.null? ? "" : String.new(instruction, instruction_len)

# Obtain the details of the object that made the request (passed in the initializer)
object_id = Pointer(Pointer(Void)).new(data.address)[0].address
Expand Down

0 comments on commit 5937c3b

Please sign in to comment.