forked from KolibriOS/kolibrios
Implemented local storage and checking of remote host keys. (only ssh-rsa for now)
Known public keys will be stored in /sys/settings/known_hosts.ini git-svn-id: svn://kolibrios.org@9112 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
9438fa3384
commit
33d98adcfa
@ -142,7 +142,7 @@ start:
|
||||
|
||||
DEBUGF 2, "SSH: Init Console\n"
|
||||
invoke con_start, 1
|
||||
invoke con_init, 80, 25, 800, 250, title
|
||||
invoke con_init, 80, 25, 80, 250, title
|
||||
|
||||
cmp byte[params], 0
|
||||
jne main.connect
|
||||
@ -388,8 +388,9 @@ proc sshlib_callback_hostkey_problem, con_ptr, problem_type, hostkey_sz
|
||||
invoke con_write_asciiz, str23
|
||||
; jmp .ask
|
||||
.ask:
|
||||
;;; TODO: print hostkey
|
||||
invoke con_write_asciiz, str24
|
||||
invoke con_write_asciiz, str24a
|
||||
invoke con_write_asciiz, [hostkey_sz]
|
||||
invoke con_write_asciiz, str24b
|
||||
.getansw:
|
||||
invoke con_getch2
|
||||
or al, 0x20 ; convert to lowercase
|
||||
@ -471,7 +472,8 @@ str22 db "The host key for the server was not found in the cache.", 10
|
||||
str23 db "The host key provided by the host does not match the cached one.", 10
|
||||
db "This may indicate that the remote server has been compromised!", 10, 0
|
||||
|
||||
str24 db 10, "If you trust this host, press A to accept and store the (new) key.", 10
|
||||
str24a db 10, "The remote host key is: ", 10, 0
|
||||
str24b db 10, 10, "If you trust this host, press A to accept and store the (new) key.", 10
|
||||
db "Press C to connect to the host but don't store the (new) key.", 10
|
||||
db "Press X to abort.", 10, 0
|
||||
|
||||
@ -479,7 +481,7 @@ str24 db 10, "If you trust this host, press A to accept and store the (new) ke
|
||||
ssh_ident_ha:
|
||||
dd_n (ssh_msg_ident.length-2)
|
||||
ssh_msg_ident:
|
||||
db "SSH-2.0-KolibriOS_SSH_0.05",13,10
|
||||
db "SSH-2.0-KolibriOS_SSH_0.06",13,10
|
||||
.length = $ - ssh_msg_ident
|
||||
|
||||
|
||||
@ -592,7 +594,8 @@ align 4
|
||||
|
||||
library network, 'network.obj', \
|
||||
console, 'console.obj', \
|
||||
libcrash, 'libcrash.obj'
|
||||
libcrash, 'libcrash.obj', \
|
||||
libini, 'libini.obj'
|
||||
|
||||
import network, \
|
||||
getaddrinfo, 'getaddrinfo', \
|
||||
@ -622,6 +625,10 @@ import libcrash, \
|
||||
md5_update, 'md5_update', \
|
||||
md5_final, 'md5_final'
|
||||
|
||||
import libini, \
|
||||
ini_get_str, 'ini_get_str', \
|
||||
ini_set_str, 'ini_set_str'
|
||||
|
||||
IncludeIGlobals
|
||||
|
||||
i_end:
|
||||
|
@ -18,13 +18,21 @@
|
||||
; https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
|
||||
; https://datatracker.ietf.org/doc/html/rfc3447
|
||||
|
||||
; https://datatracker.ietf.org/doc/html/rfc4716
|
||||
|
||||
proc sshlib_host_verify con_ptr, str_host_key, str_signature, message, message_len
|
||||
|
||||
locals
|
||||
known_key_sz rb MAX_PUBLIC_KEY_SIZE
|
||||
current_hkb64 rb MAX_PUBLIC_KEY_SIZE*4 ; Current Host key in Base64
|
||||
cached_hkb64 rb MAX_PUBLIC_KEY_SIZE*4 ; Cached Host key in Base64
|
||||
key_name_sz dd ?
|
||||
hostname_sz dd ?
|
||||
current_hk64_end dd ?
|
||||
endl
|
||||
|
||||
mov eax, [con_ptr]
|
||||
lea ebx, [eax + sshlib_connection.hostname_sz]
|
||||
mov [hostname_sz], ebx
|
||||
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA
|
||||
je .rsa
|
||||
; ..add more here
|
||||
@ -35,40 +43,65 @@ endl
|
||||
stdcall sshlib_host_verify_rsa, [str_host_key], [str_signature], [message], [message_len]
|
||||
test eax, eax
|
||||
jnz .err
|
||||
mov [key_name_sz], ssh_rsa_sz
|
||||
|
||||
.lookup:
|
||||
; lea eax, [known_key_sz]
|
||||
; mov ebx, [con_ptr]
|
||||
; lea ebx, [ebx + sshlib_connection.hostname_sz]
|
||||
; invoke ini_get_str, known_hosts_file, ebx, ssh_rsa_sz, eax, MAX_PUBLIC_KEY_SIZE, null_sz
|
||||
; test eax, eax
|
||||
; jnz .unknown
|
||||
; Convert the current host key to base64
|
||||
mov esi, [str_host_key]
|
||||
mov ecx, [esi]
|
||||
bswap ecx
|
||||
add esi, 4
|
||||
lea edi, [current_hkb64]
|
||||
call base64_encode
|
||||
mov [current_hk64_end], edi
|
||||
|
||||
; TODO: verify cached host key
|
||||
; jne .mismatch
|
||||
|
||||
jmp .unknown ; FIXME
|
||||
; Try to read the cached key for this host and key type
|
||||
lea edi, [cached_hkb64]
|
||||
invoke ini_get_str, known_hostsfile, [hostname_sz], [key_name_sz], edi, MAX_PUBLIC_KEY_SIZE*4, 0
|
||||
test eax, eax
|
||||
jnz .unknown
|
||||
; If the cached key is empty, return SSHLIB_HOSTKEY_PROBLEM_UNKNOWN
|
||||
lea esi, [cached_hkb64]
|
||||
cmp byte[esi], 0
|
||||
je .unknown
|
||||
; Else, compare it to the current one
|
||||
lea edi, [current_hkb64]
|
||||
mov ecx, MAX_PUBLIC_KEY_SIZE*4
|
||||
.cmploop:
|
||||
lodsb
|
||||
scasb
|
||||
jne .mismatch
|
||||
test al, al
|
||||
jz .match
|
||||
dec ecx
|
||||
jnz .cmploop
|
||||
jmp .mismatch
|
||||
|
||||
.match:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.mismatch:
|
||||
lea eax, [known_key_sz]
|
||||
int3
|
||||
lea eax, [current_hkb64]
|
||||
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_MISMATCH, eax
|
||||
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
||||
je .store
|
||||
ret
|
||||
|
||||
.unknown:
|
||||
lea eax, [known_key_sz]
|
||||
lea eax, [current_hkb64]
|
||||
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_UNKNOWN, eax
|
||||
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
||||
je .store
|
||||
ret
|
||||
|
||||
.store:
|
||||
; TODO: write to know_hosts file and fall-through
|
||||
|
||||
lea esi, [current_hkb64]
|
||||
mov ecx, [current_hk64_end]
|
||||
sub ecx, esi
|
||||
invoke ini_set_str, known_hostsfile, [hostname_sz], [key_name_sz], esi, ecx
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.err:
|
||||
@ -234,10 +267,64 @@ endl
|
||||
endp
|
||||
|
||||
|
||||
base64_encode:
|
||||
|
||||
xor ebx, ebx
|
||||
.loop:
|
||||
lodsb
|
||||
call .byte
|
||||
dec ecx
|
||||
jnz .loop
|
||||
|
||||
.final:
|
||||
mov al, 0
|
||||
test ebx, ebx
|
||||
jz .f000
|
||||
call .byte
|
||||
test ebx, ebx
|
||||
jz .f001
|
||||
call .byte
|
||||
mov byte[edi-2], '='
|
||||
|
||||
.f001:
|
||||
mov byte[edi-1], '='
|
||||
|
||||
.f000:
|
||||
mov byte[edi], 0
|
||||
ret
|
||||
|
||||
.byte:
|
||||
inc ebx
|
||||
shl edx, 8
|
||||
mov dl, al
|
||||
cmp ebx, 3
|
||||
je .b001
|
||||
ret
|
||||
|
||||
.b001:
|
||||
shl edx, 8
|
||||
inc ebx
|
||||
|
||||
.b002:
|
||||
rol edx, 6
|
||||
xor eax, eax
|
||||
xchg al, dl
|
||||
mov al, [base64_table+eax]
|
||||
stosb
|
||||
dec ebx
|
||||
jnz .b002
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
iglobal
|
||||
|
||||
known_hostsfile db '/sys/settings/known_hosts.ini', 0
|
||||
base64_table db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
rsa_sha1_t db 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14
|
||||
.len = $ - rsa_sha1_t
|
||||
ssh_rsa_sz db 'ssh-rsa', 0
|
||||
|
||||
endg
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user