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"
|
DEBUGF 2, "SSH: Init Console\n"
|
||||||
invoke con_start, 1
|
invoke con_start, 1
|
||||||
invoke con_init, 80, 25, 800, 250, title
|
invoke con_init, 80, 25, 80, 250, title
|
||||||
|
|
||||||
cmp byte[params], 0
|
cmp byte[params], 0
|
||||||
jne main.connect
|
jne main.connect
|
||||||
@ -388,8 +388,9 @@ proc sshlib_callback_hostkey_problem, con_ptr, problem_type, hostkey_sz
|
|||||||
invoke con_write_asciiz, str23
|
invoke con_write_asciiz, str23
|
||||||
; jmp .ask
|
; jmp .ask
|
||||||
.ask:
|
.ask:
|
||||||
;;; TODO: print hostkey
|
invoke con_write_asciiz, str24a
|
||||||
invoke con_write_asciiz, str24
|
invoke con_write_asciiz, [hostkey_sz]
|
||||||
|
invoke con_write_asciiz, str24b
|
||||||
.getansw:
|
.getansw:
|
||||||
invoke con_getch2
|
invoke con_getch2
|
||||||
or al, 0x20 ; convert to lowercase
|
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
|
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
|
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 C to connect to the host but don't store the (new) key.", 10
|
||||||
db "Press X to abort.", 10, 0
|
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:
|
ssh_ident_ha:
|
||||||
dd_n (ssh_msg_ident.length-2)
|
dd_n (ssh_msg_ident.length-2)
|
||||||
ssh_msg_ident:
|
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
|
.length = $ - ssh_msg_ident
|
||||||
|
|
||||||
|
|
||||||
@ -592,7 +594,8 @@ align 4
|
|||||||
|
|
||||||
library network, 'network.obj', \
|
library network, 'network.obj', \
|
||||||
console, 'console.obj', \
|
console, 'console.obj', \
|
||||||
libcrash, 'libcrash.obj'
|
libcrash, 'libcrash.obj', \
|
||||||
|
libini, 'libini.obj'
|
||||||
|
|
||||||
import network, \
|
import network, \
|
||||||
getaddrinfo, 'getaddrinfo', \
|
getaddrinfo, 'getaddrinfo', \
|
||||||
@ -622,6 +625,10 @@ import libcrash, \
|
|||||||
md5_update, 'md5_update', \
|
md5_update, 'md5_update', \
|
||||||
md5_final, 'md5_final'
|
md5_final, 'md5_final'
|
||||||
|
|
||||||
|
import libini, \
|
||||||
|
ini_get_str, 'ini_get_str', \
|
||||||
|
ini_set_str, 'ini_set_str'
|
||||||
|
|
||||||
IncludeIGlobals
|
IncludeIGlobals
|
||||||
|
|
||||||
i_end:
|
i_end:
|
||||||
|
@ -18,13 +18,21 @@
|
|||||||
; https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
|
; https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
|
||||||
; https://datatracker.ietf.org/doc/html/rfc3447
|
; 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
|
proc sshlib_host_verify con_ptr, str_host_key, str_signature, message, message_len
|
||||||
|
|
||||||
locals
|
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
|
endl
|
||||||
|
|
||||||
mov eax, [con_ptr]
|
mov eax, [con_ptr]
|
||||||
|
lea ebx, [eax + sshlib_connection.hostname_sz]
|
||||||
|
mov [hostname_sz], ebx
|
||||||
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA
|
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA
|
||||||
je .rsa
|
je .rsa
|
||||||
; ..add more here
|
; ..add more here
|
||||||
@ -35,40 +43,65 @@ endl
|
|||||||
stdcall sshlib_host_verify_rsa, [str_host_key], [str_signature], [message], [message_len]
|
stdcall sshlib_host_verify_rsa, [str_host_key], [str_signature], [message], [message_len]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .err
|
jnz .err
|
||||||
|
mov [key_name_sz], ssh_rsa_sz
|
||||||
|
|
||||||
.lookup:
|
.lookup:
|
||||||
; lea eax, [known_key_sz]
|
; Convert the current host key to base64
|
||||||
; mov ebx, [con_ptr]
|
mov esi, [str_host_key]
|
||||||
; lea ebx, [ebx + sshlib_connection.hostname_sz]
|
mov ecx, [esi]
|
||||||
; invoke ini_get_str, known_hosts_file, ebx, ssh_rsa_sz, eax, MAX_PUBLIC_KEY_SIZE, null_sz
|
bswap ecx
|
||||||
; test eax, eax
|
add esi, 4
|
||||||
; jnz .unknown
|
lea edi, [current_hkb64]
|
||||||
|
call base64_encode
|
||||||
|
mov [current_hk64_end], edi
|
||||||
|
|
||||||
; TODO: verify cached host key
|
; Try to read the cached key for this host and key type
|
||||||
; jne .mismatch
|
lea edi, [cached_hkb64]
|
||||||
|
invoke ini_get_str, known_hostsfile, [hostname_sz], [key_name_sz], edi, MAX_PUBLIC_KEY_SIZE*4, 0
|
||||||
jmp .unknown ; FIXME
|
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
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.mismatch:
|
.mismatch:
|
||||||
lea eax, [known_key_sz]
|
int3
|
||||||
|
lea eax, [current_hkb64]
|
||||||
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_MISMATCH, eax
|
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_MISMATCH, eax
|
||||||
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
||||||
je .store
|
je .store
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.unknown:
|
.unknown:
|
||||||
lea eax, [known_key_sz]
|
lea eax, [current_hkb64]
|
||||||
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_UNKNOWN, eax
|
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_UNKNOWN, eax
|
||||||
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
cmp eax, SSHLIB_HOSTKEY_ACCEPT
|
||||||
je .store
|
je .store
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.store:
|
.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
|
ret
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
@ -234,10 +267,64 @@ endl
|
|||||||
endp
|
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
|
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
|
rsa_sha1_t db 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14
|
||||||
.len = $ - rsa_sha1_t
|
.len = $ - rsa_sha1_t
|
||||||
|
ssh_rsa_sz db 'ssh-rsa', 0
|
||||||
|
|
||||||
endg
|
endg
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user