Subversion Repositories Kolibri OS

Rev

Rev 9990 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9106 hidnplayr 1
;    sshlib_connection.inc - SSH connection
2
;
9987 hidnplayr 3
;    Copyright (C) 2016-2024 Jeffrey Amelynck
9106 hidnplayr 4
;
5
;    This program is free software: you can redistribute it and/or modify
6
;    it under the terms of the GNU General Public License as published by
7
;    the Free Software Foundation, either version 3 of the License, or
8
;    (at your option) any later version.
9
;
10
;    This program is distributed in the hope that it will be useful,
11
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;    GNU General Public License for more details.
14
;
15
;    You should have received a copy of the GNU General Public License
16
;    along with this program.  If not, see .
17
 
9987 hidnplayr 18
; https://www.ietf.org/rfc/rfc4253.txt
19
 
9106 hidnplayr 20
proc sshlib_connect con_ptr, hostname_sz
21
 
22
locals
23
        socketnum       dd ?
24
        sockaddr        sockaddr_in
25
        ctx_ptr         dd ?
26
endl
27
 
28
        mov     edi, [con_ptr]
29
        lea     eax, [edi + sshlib_connection.part_ex_hash_ctx]
30
        mov     [ctx_ptr], eax
31
 
32
; Set default values in sockaddr struct
33
        mov     [sockaddr.sin_family], AF_INET4
34
        mov     [sockaddr.sin_port], 22 shl 8
35
 
36
; Parse hostname_sz
37
; Verify length, extract port number if given and copy base url to sshlib_connection struct
38
; Port number, if provided, will be written in sockaddr struct.
39
; Hostname ends with any character equal to 0x20 or lower
40
 
41
        mov     esi, [hostname_sz]
42
        lea     edi, [edi + sshlib_connection.hostname_sz]
43
        mov     ecx, MAX_HOSTNAME_LENGTH
44
  @@:
45
        dec     ecx
46
        jz      .err_hostname
47
        lodsb
48
        cmp     al, ':'
49
        je      .do_port
50
        stosb
51
        cmp     al, 0x20
52
        ja      @r
53
        mov     byte[edi-1], 0
54
        jmp     .hostname_ok
55
 
56
  .do_port:
57
        xor     eax, eax
58
        xor     ebx, ebx
59
        mov     byte[edi-1], 0
60
  .portloop:
61
        lodsb
62
        cmp     al, 0x20
63
        jbe     .port_done
64
        sub     al, '0'
65
        jb      .err_hostname
66
        cmp     al, 9
67
        ja      .err_hostname
68
        lea     ebx, [ebx*4+ebx]
69
        shl     ebx, 1
70
        add     ebx, eax
71
        jmp     .portloop
72
  .port_done:
73
        xchg    bl, bh
74
        mov     [sockaddr.sin_port], bx
75
 
76
  .hostname_ok:
77
; resolve name
78
        push    esp     ; reserve stack place
79
        push    esp
80
        mov     eax, [con_ptr]
81
        lea     eax, [eax+sshlib_connection.hostname_sz]
82
        invoke  getaddrinfo, eax, 0, 0
83
        pop     esi
84
; test for error
85
        test    eax, eax
86
        jnz     .err_hostname
87
 
88
; convert IP address to decimal notation
89
        mov     eax, [esi+addrinfo.ai_addr]
90
        mov     eax, [eax+sockaddr_in.sin_addr]
91
        mov     [sockaddr.sin_addr], eax
92
        invoke  inet_ntoa, eax
93
; write result
94
        stdcall sshlib_callback_connecting, [con_ptr], eax
95
; free allocated memory
96
        invoke  freeaddrinfo, esi
97
 
98
; Create socket
99
        mcall   socket, AF_INET4, SOCK_STREAM, 0
100
        cmp     eax, -1
101
        jz      .err_sock
102
        mov     [socketnum], eax
103
        mov     ebx, [con_ptr]
104
        mov     [ebx + sshlib_connection.socketnum], eax
105
 
106
; Connect
107
        DEBUGF  2, "Connecting to server\n"
108
        lea     edx, [sockaddr]
109
        mcall   connect, [socketnum], , sizeof.sockaddr_in
110
        test    eax, eax
111
        jnz     .err_sock
112
 
113
; Start calculating hash
9990 hidnplayr 114
        invoke  sha2_256.init, [ctx_ptr]
9106 hidnplayr 115
; HASH: string  V_C, the client's version string (CR and NL excluded)
9990 hidnplayr 116
        invoke  sha2_256.update, [ctx_ptr], ssh_ident_ha, ssh_msg_ident.length+4-2
9106 hidnplayr 117
 
118
; >> Send our identification string
119
        DEBUGF  2, "Sending ID string\n"
120
        mcall   send, [socketnum], ssh_msg_ident, ssh_msg_ident.length, 0
121
        cmp     eax, -1
122
        je      .err_sock
123
 
124
; << Check protocol version of server
125
        mov     edx, [con_ptr]
126
        lea     edx, [edx + sshlib_connection.rx_buffer + 4]
127
        mcall   recv, [socketnum], , PACKETSIZE, 0
128
        cmp     eax, -1
129
        je      .err_sock
130
 
131
        DEBUGF  2, "Received ID string\n"
132
        cmp     dword[edx], "SSH-"
133
        jne     .err_proto
134
        cmp     dword[edx+4], "2.0-"
135
        jne     .err_proto
136
 
137
; HASH: string  V_S, the server's version string (CR and NL excluded)
138
        lea     ecx, [eax+2]
139
        sub     eax, 2
140
        bswap   eax
141
        sub     edx, 4
142
        mov     dword[edx], eax
9990 hidnplayr 143
        invoke  sha2_256.update, [ctx_ptr], edx, ecx
9106 hidnplayr 144
 
145
; >> Key Exchange init
146
        mov     eax, [con_ptr]
147
        mov     [eax + sshlib_connection.status], SSHLIB_CON_STAT_INIT
148
 
149
        mov     [eax + sshlib_connection.algo_kex], SSHLIB_ALGO_NONE
150
        mov     [eax + sshlib_connection.algo_hostkey], SSHLIB_ALGO_NONE
151
        mov     [eax + sshlib_connection.algo_crypt_rx], SSHLIB_ALGO_NONE
152
        mov     [eax + sshlib_connection.algo_crypt_tx], SSHLIB_ALGO_NONE
153
        mov     [eax + sshlib_connection.algo_mac_rx], SSHLIB_ALGO_NONE
154
        mov     [eax + sshlib_connection.algo_mac_tx], SSHLIB_ALGO_NONE
155
        mov     [eax + sshlib_connection.algo_compr_rx], SSHLIB_ALGO_NONE
156
        mov     [eax + sshlib_connection.algo_compr_tx], SSHLIB_ALGO_NONE
157
 
158
        mov     [eax + sshlib_connection.rx_mac_seqnr], 0
159
        mov     [eax + sshlib_connection.tx_mac_seqnr], 0
160
        mov     [eax + sshlib_connection.rx_crypt_blocksize], 4             ; minimum blocksize
161
        mov     [eax + sshlib_connection.tx_crypt_blocksize], 4
9987 hidnplayr 162
        mov     [eax + sshlib_connection.rx_crypt_proc], 0
163
        mov     [eax + sshlib_connection.tx_crypt_proc], 0
9106 hidnplayr 164
        mov     [eax + sshlib_connection.rx_mac_proc], 0
165
        mov     [eax + sshlib_connection.tx_mac_proc], 0
166
        mov     [eax + sshlib_connection.rx_mac_length], 0
167
        mov     [eax + sshlib_connection.tx_mac_length], 0
168
        mov     [eax + sshlib_connection.tx_pad_size], 8
169
 
9987 hidnplayr 170
        mov     [eax + sshlib_connection.rx_proc], sshlib_recv_packet_clear
171
        mov     [eax + sshlib_connection.tx_proc], sshlib_send_packet_clear
172
 
9106 hidnplayr 173
        DEBUGF  2, "Sending KEX init\n"
174
        mov     edi, ssh_msg_kex.cookie
175
        call    MBRandom
176
        stosd
177
        call    MBRandom
178
        stosd
179
        call    MBRandom
180
        stosd
181
        call    MBRandom
182
        stosd
183
        stdcall sshlib_send_packet, [con_ptr], ssh_msg_kex, ssh_msg_kex.length, 0
184
        cmp     eax, -1
185
        je      .err_sock
186
 
187
; HASH: string  I_C, the payload of the client's SSH_MSG_KEXINIT
188
        mov     esi, [con_ptr]
189
        mov     eax, [esi+sshlib_connection.tx_buffer.packet_length]
190
        bswap   eax
191
        movzx   ebx, [esi+sshlib_connection.tx_buffer.padding_length]
192
        sub     eax, ebx
193
        dec     eax
194
        lea     edx, [eax+4]
195
        bswap   eax
196
        lea     esi, [esi+sshlib_connection.tx_buffer+1]
197
        mov     dword[esi], eax
9990 hidnplayr 198
        invoke  sha2_256.update, [ctx_ptr], esi, edx
9106 hidnplayr 199
 
200
; << Check key exchange init of server
201
        stdcall sshlib_recv_packet, [con_ptr], 0
202
        cmp     eax, -1
203
        je      .err_sock
204
 
9991 hidnplayr 205
        mov     ebx, [con_ptr]
206
        cmp     [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_KEXINIT
9106 hidnplayr 207
        jne     .err_proto
208
        DEBUGF  2, "Received KEX init\n"
9991 hidnplayr 209
        lea     esi, [ebx + sshlib_connection.rx_buffer + sizeof.ssh_packet_header + 16]
9106 hidnplayr 210
 
9991 hidnplayr 211
        DEBUGF  2, "kex_algorithm "
212
        stdcall sshlib_algo_find_match, ssh_msg_kex.kex_algorithms, algorithms_kex
213
        test    eax, eax
214
        jz      .err_no_algo
215
        mov     [ebx + sshlib_connection.algo_kex], eax
216
 
217
        DEBUGF  2, "server_host_key_algorithm "
218
        stdcall sshlib_algo_find_match, ssh_msg_kex.server_host_key_algorithms, algorithms_hostkey
219
        test    eax, eax
220
        jz      .err_no_algo
221
        mov     [ebx + sshlib_connection.algo_hostkey], eax
222
 
223
        DEBUGF  2, "encryption_algorithm_client_to_server "
224
        stdcall sshlib_algo_find_match, ssh_msg_kex.encryption_algorithms_client_to_server, algorithms_crypt
225
        test    eax, eax
226
        jz      .err_no_algo
227
        mov     [ebx + sshlib_connection.algo_crypt_tx], eax
228
 
229
        DEBUGF  2, "encryption_algorithm_server_to_client ",
230
        stdcall sshlib_algo_find_match, ssh_msg_kex.encryption_algorithms_server_to_client, algorithms_crypt
231
        test    eax, eax
232
        jz      .err_no_algo
233
        mov     [ebx + sshlib_connection.algo_crypt_rx], eax
234
 
235
        DEBUGF  2, "mac_algorithm_client_to_server "
236
        stdcall sshlib_algo_find_match, ssh_msg_kex.mac_algorithms_client_to_server, algorithms_mac
237
        test    eax, eax
238
        jz      .err_no_algo
239
        mov     [ebx + sshlib_connection.algo_mac_tx], eax
240
 
241
        DEBUGF  2, "mac_algorithm_server_to_client "
242
        stdcall sshlib_algo_find_match, ssh_msg_kex.mac_algorithms_server_to_client, algorithms_mac
243
        test    eax, eax
244
        jz      .err_no_algo
245
        mov     [ebx + sshlib_connection.algo_mac_rx], eax
246
 
247
        DEBUGF  2, "compression_algorithm_client_to_server "
248
        stdcall sshlib_algo_find_match, ssh_msg_kex.compression_algorithms_client_to_server, algorithms_compression
249
        test    eax, eax
250
        jz      .err_no_algo
251
        mov     [ebx + sshlib_connection.algo_compr_tx], eax
252
 
253
        DEBUGF  2, "compression_algorithm_server_to_client "
254
        stdcall sshlib_algo_find_match, ssh_msg_kex.compression_algorithms_server_to_client, algorithms_compression
255
        test    eax, eax
256
        jz      .err_no_algo
257
        mov     [ebx + sshlib_connection.algo_compr_rx], eax
258
 
259
        DEBUGF  2, "language_client_to_server "
260
        stdcall sshlib_algo_find_match, ssh_msg_kex.languages_client_to_server, languages
261
 
262
        DEBUGF  2, "language_server_to_client "
263
        stdcall sshlib_algo_find_match, ssh_msg_kex.languages_server_to_client, languages
264
 
9106 hidnplayr 265
        lodsb
9991 hidnplayr 266
        DEBUGF  2, "KEX First Packet Follows: %u\n", al
9106 hidnplayr 267
 
268
; HASH: string I_S, the payload of the servers's SSH_MSG_KEXINIT
269
        mov     esi, [con_ptr]
9991 hidnplayr 270
        mov     eax, [esi + sshlib_connection.rx_buffer.packet_length]
271
        movzx   ebx, [esi + sshlib_connection.rx_buffer.padding_length]
9106 hidnplayr 272
        sub     eax, ebx
273
        dec     eax
274
        lea     edx, [eax+4]
275
        bswap   eax
9991 hidnplayr 276
        lea     esi, [esi + sshlib_connection.rx_buffer+1]
9106 hidnplayr 277
        mov     dword[esi], eax
9990 hidnplayr 278
        invoke  sha2_256.update, [ctx_ptr], esi, edx
9106 hidnplayr 279
 
280
; Exchange keys with the server
281
 
9991 hidnplayr 282
        mov     ebx, [con_ptr]
283
        cmp     [ebx + sshlib_connection.algo_kex], SSHLIB_KEX_DH_SHA256        ; only kex algo supported for now
284
        jne     .err_no_algo
285
 
9106 hidnplayr 286
        stdcall sshlib_dh_gex, [con_ptr]
287
        test    eax, eax
288
        jnz     .err
289
 
9987 hidnplayr 290
; Set keys and initialize transport subroutines
291
 
292
        DEBUGF  2, "SSH: Setting encryption keys\n"
293
 
294
        mov     ebx, [con_ptr]
295
 
9990 hidnplayr 296
        cmp     [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_AES256_CTR
297
        je      .rx_crypt_aes256_ctr
298
        cmp     [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_AES256_CBC
299
        je      .rx_crypt_aes256_cbc
300
        cmp     [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_CHACHA20_POLY1305
301
        je      .rx_crypt_poly1305_chacha20
9987 hidnplayr 302
 
9990 hidnplayr 303
        jmp     .err_proto
304
 
305
  .rx_crypt_aes256_ctr:
306
        lea     ecx, [ebx + sshlib_connection.rx_crypt_ctx]
307
        lea     edx, [ebx + sshlib_connection.rx_enc_key]
308
        lea     esi, [ebx + sshlib_connection.rx_iv]
309
        invoke  aes256ctr.init, ecx, edx, esi, 0
310
        push    [aes256ctr.update]
311
        pop     [ebx + sshlib_connection.rx_crypt_proc]
312
        mov     [ebx + sshlib_connection.rx_crypt_blocksize], 16        ; AES_BLOCKSIZE
313
        jmp     .have_rx_crypt
314
 
315
  .rx_crypt_aes256_cbc:
316
        lea     ecx, [ebx + sshlib_connection.rx_crypt_ctx]
317
        lea     edx, [ebx + sshlib_connection.rx_enc_key]
318
        lea     esi, [ebx + sshlib_connection.rx_iv]
319
        invoke  aes256cbc.init, ecx, edx, esi, 0
320
        push    [aes256cbc.update]
321
        pop     [ebx + sshlib_connection.rx_crypt_proc]
322
        mov     [ebx + sshlib_connection.rx_crypt_blocksize], 16        ; AES_BLOCKSIZE
323
        jmp     .have_rx_crypt
324
 
325
  .rx_crypt_poly1305_chacha20:
9987 hidnplayr 326
        mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_poly1305chacha20
9990 hidnplayr 327
        jmp     .have_rx_crypt_and_mac
328
 
329
 
330
 
331
  .have_rx_crypt:
9991 hidnplayr 332
        cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256
9990 hidnplayr 333
        je      .rx_hmac_sha2_256
9991 hidnplayr 334
        cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512
9990 hidnplayr 335
        je      .rx_hmac_sha2_512
9991 hidnplayr 336
        cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256_ETM
9990 hidnplayr 337
        je      .rx_hmac_sha2_256_etm
9991 hidnplayr 338
        cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512_ETM
9990 hidnplayr 339
        je      .rx_hmac_sha2_512_etm
340
 
341
        jmp     .err_proto
342
 
343
  .rx_hmac_sha2_256:
344
        push    [hmac_sha2_256.oneshot]
345
        pop     [ebx + sshlib_connection.rx_mac_proc]
346
        mov     [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN
347
        mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac
348
        jmp     .have_rx_crypt_and_mac
349
 
350
  .rx_hmac_sha2_512:
351
        push    [hmac_sha2_512.oneshot]
352
        pop     [ebx + sshlib_connection.rx_mac_proc]
353
        mov     [ebx + sshlib_connection.rx_mac_length], SHA2_512_LEN
354
        mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac
355
        jmp     .have_rx_crypt_and_mac
356
 
357
  .rx_hmac_sha2_256_etm:
358
        push    [hmac_sha2_256.oneshot]
359
        pop     [ebx + sshlib_connection.rx_mac_proc]
360
        mov     [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN
361
        mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac_etm
362
        jmp     .have_rx_crypt_and_mac
363
 
364
  .rx_hmac_sha2_512_etm:
365
        push    [hmac_sha2_512.oneshot]
366
        pop     [ebx + sshlib_connection.rx_mac_proc]
367
        mov     [ebx + sshlib_connection.rx_mac_length], SHA2_512_LEN
368
        mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac_etm
369
        jmp     .have_rx_crypt_and_mac
370
 
371
 
372
  .have_rx_crypt_and_mac:
373
 
374
        cmp     [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CTR
375
        je      .tx_crypt_aes256_ctr
376
        cmp     [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CBC
377
        je      .tx_crypt_aes256_cbc
378
        cmp     [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_CHACHA20_POLY1305
379
        je      .tx_crypt_poly1305_chacha20
380
 
381
        jmp     .err_proto
382
 
383
  .tx_crypt_aes256_ctr:
384
        lea     ecx, [ebx + sshlib_connection.tx_crypt_ctx]
385
        lea     edx, [ebx + sshlib_connection.tx_enc_key]
386
        lea     esi, [ebx + sshlib_connection.tx_iv]
387
        invoke  aes256ctr.init, ecx, edx, esi, 0
388
        push    [aes256ctr.update]
389
        pop     [ebx + sshlib_connection.tx_crypt_proc]
390
        mov     [ebx + sshlib_connection.tx_crypt_blocksize], 16        ; AES_BLOCKSIZE
391
        mov     [ebx + sshlib_connection.tx_pad_size], 16               ; AES_BLOCKSIZE
392
        jmp     .have_tx_crypt
393
 
394
  .tx_crypt_aes256_cbc:
395
        lea     ecx, [ebx + sshlib_connection.tx_crypt_ctx]
396
        lea     edx, [ebx + sshlib_connection.tx_enc_key]
397
        lea     esi, [ebx + sshlib_connection.tx_iv]
398
        invoke  aes256cbc.init, ecx, edx, esi, 0
399
        push    [aes256cbc.update]
400
        pop     [ebx + sshlib_connection.tx_crypt_proc]
401
        mov     [ebx + sshlib_connection.tx_crypt_blocksize], 16        ; AES_BLOCKSIZE
402
        mov     [ebx + sshlib_connection.tx_pad_size], 16               ; AES_BLOCKSIZE
403
        jmp     .have_tx_crypt
404
 
405
  .tx_crypt_poly1305_chacha20:
9987 hidnplayr 406
        mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_poly1305chacha20
9990 hidnplayr 407
        jmp     .have_tx_crypt_and_mac
9987 hidnplayr 408
 
9990 hidnplayr 409
 
410
 
411
  .have_tx_crypt:
9991 hidnplayr 412
        cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256
9990 hidnplayr 413
        je      .tx_hmac_sha2_256
9991 hidnplayr 414
        cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512
9990 hidnplayr 415
        je      .tx_hmac_sha2_512
9991 hidnplayr 416
        cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256_ETM
9990 hidnplayr 417
        je      .tx_hmac_sha2_256_etm
9991 hidnplayr 418
        cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512_ETM
9990 hidnplayr 419
        je      .tx_hmac_sha2_512_etm
420
 
421
        jmp     .err_proto
422
 
423
  .tx_hmac_sha2_256:
424
        push    [hmac_sha2_256.oneshot]
425
        pop     [ebx + sshlib_connection.tx_mac_proc]
426
        mov     [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN
427
        mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac
428
        jmp     .have_tx_crypt_and_mac
429
 
430
  .tx_hmac_sha2_512:
431
        push    [hmac_sha2_512.oneshot]
432
        pop     [ebx + sshlib_connection.tx_mac_proc]
433
        mov     [ebx + sshlib_connection.tx_mac_length], SHA2_512_LEN
434
        mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac
435
        jmp     .have_tx_crypt_and_mac
436
 
437
  .tx_hmac_sha2_256_etm:
438
        push    [hmac_sha2_256.oneshot]
439
        pop     [ebx + sshlib_connection.tx_mac_proc]
440
        mov     [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN
441
        mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac_etm
442
        jmp     .have_tx_crypt_and_mac
443
 
444
  .tx_hmac_sha2_512_etm:
445
        push    [hmac_sha2_512.oneshot]
446
        pop     [ebx + sshlib_connection.tx_mac_proc]
447
        mov     [ebx + sshlib_connection.tx_mac_length], SHA2_512_LEN
448
        mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac_etm
449
        jmp     .have_tx_crypt_and_mac
450
 
451
 
452
  .have_tx_crypt_and_mac:
453
 
9106 hidnplayr 454
; Re-seed RNG for padding bytes
455
 
456
        call    create_seed
457
        call    init_random
458
 
459
        xor     eax, eax
460
        ret
461
 
9991 hidnplayr 462
  .err_no_algo:
463
        mov     eax, SSHLIB_ERR_NO_ALGO
464
        ret
465
 
9106 hidnplayr 466
  .err_hostname:
467
        mov     eax, SSHLIB_ERR_HOSTNAME
468
        ret
469
 
470
  .err_sock:
471
        mov     eax, SSHLIB_ERR_SOCKET
472
        ret
473
 
474
  .err_proto:
475
        mov     eax, SSHLIB_ERR_PROTOCOL
476
        ret
477
 
478
  .err:
479
        ret
480
 
481
endp
482
 
483
 
484
 
9991 hidnplayr 485
proc sshlib_algo_find_match uses ebx ecx edx edi, client_str, algo_list
9106 hidnplayr 486
 
9991 hidnplayr 487
locals
488
        server_str      dd ?
489
        next_str        dd ?
490
        current         dd ?
491
endl
492
 
493
        lodsd
494
        mov     [server_str], esi
495
        bswap   eax
496
        lea     ecx, [esi + eax]
497
        mov     [next_str], ecx
498
 
499
        mov     edi, [client_str]
500
        mov     edx, dword[edi]
501
        bswap   edx
502
        add     edi, 4
503
        add     edx, edi        ; end of string
504
 
505
  .go:
506
        mov     [current], edi
507
  .cmp:
508
        cmp     esi, ecx
509
        jae     .end_of_s
510
        mov     al, byte[esi]
511
        inc     esi
512
  .cmp_1:
513
        cmp     edi, edx
514
        jae     .end_of_c
515
        mov     bl, byte[edi]
516
        inc     edi
517
  .cmp_2:
518
        cmp     al, bl
519
        jne     .mismatch
520
 
521
        cmp     al, ','
522
        jne     .cmp
523
 
524
; algo matches, print it to debug board
525
        DEBUGF  2, "= "
526
        mov     edi, [current]
527
  @@:
528
        cmp     edi, edx
529
        jae     @f
530
        mov     cl, byte[edi]
531
        cmp     cl, ','
532
        je      @f
533
        mcall   63, 1
534
        inc     edi
535
        jmp     @r
536
  @@:
537
;        mcall   63, 1, 10       ; print newline
538
 
539
; and now find it in algo list
540
        mov     esi, [algo_list]
541
  .algo_loop:
542
        mov     edi, [current]
543
        lodsd
544
        mov     ebx, eax        ; algo code
545
        test    eax, eax
546
        jz      .no_match
547
 
548
  .algo_charloop:
549
        lodsb
550
        test    al, al
551
        jz      .check_end
552
        cmp     al, byte[edi]
553
        jne     .next_algo
554
        inc     edi
555
        cmp     edi, edx
556
        jb      .algo_charloop
557
; we reached end of input, check end of algo token
558
        cmp     byte[esi], 0
559
        je      .algo_match
560
        jmp     .next_algo
561
; we reached end of algo token, check end of input
562
  .check_end:
563
        cmp     byte[edi], ','
564
        je      .algo_match
565
 
566
  .next_algo_loop:
567
        lodsb
568
  .next_algo:
569
        test    al, al
570
        jnz     .next_algo_loop
571
        jmp     .algo_loop
572
 
573
  .algo_match:
574
        mov     eax, ebx
575
        mov     esi, [next_str]
576
        DEBUGF  2," (%u)\n", eax
577
        ret
578
 
579
  .end_of_s:
580
        mov     al, ','
581
        jmp     .cmp_1
582
 
583
  .end_of_c:
584
        mov     bl, ','
585
        jmp     .cmp_2
586
 
587
  .mismatch:
588
; character mismatch, reset client str and go to next server token
589
        mov     edi, [current]
590
  @@:
591
        mov     al, byte[esi]
592
        inc     esi
593
 
594
        cmp     al, ','
595
        je      .cmp
596
 
597
        cmp     esi, ecx
598
        jb      @r
599
 
600
; end of server str, reset it and go to next client token
601
        mov     esi, [server_str]
602
  @@:
603
        mov     bl, byte[edi]
604
        inc     edi
605
 
606
        cmp     bl, ','
607
        je     .go
608
 
609
        cmp     edi, edx
610
        jb      @r
611
 
612
; end of client str, no match found
613
  .no_match:
614
        xor     eax, eax
615
        mov     esi, [next_str]
616
        DEBUGF  2," (%u)\n", eax
617
        ret
618
 
619
endp
620
 
621
 
622
 
623
 
9106 hidnplayr 624
; Handle common messages and return to caller for specific ones
625
proc sshlib_msg_handler, con_ptr, flags
626
 
627
  .recv:
628
; Send a window update if advertised window drops below half
629
        cmp     [ssh_chan.rcv_wnd], BUFFERSIZE/2
630
        ja      .no_wnd
631
        mov     eax, BUFFERSIZE
632
        bswap   eax
633
        mov     [ssh_msg_channel_window_adjust.wnd], eax
634
        stdcall sshlib_send_packet, [con_ptr], ssh_msg_channel_window_adjust, ssh_msg_channel_window_adjust.length, 0
635
        mov     [ssh_chan.rcv_wnd], BUFFERSIZE
636
  .no_wnd:
637
 
638
; Receive 1 SSH packet
639
        stdcall sshlib_recv_packet, [con_ptr], [flags]
640
        cmp     eax, 0
641
        jle     .ret
642
 
643
        mov     esi, [con_ptr]
644
        lea     esi, [esi + sshlib_connection.rx_buffer]
645
        mov     al, [esi + ssh_packet_header.message_code]
9987 hidnplayr 646
        add     esi, sizeof.ssh_packet_header
9106 hidnplayr 647
 
648
        cmp     al, SSH_MSG_DISCONNECT
649
        je      .disc
650
        cmp     al, SSH_MSG_IGNORE
651
        je      .ign
652
        cmp     al, SSH_MSG_DEBUG
653
        je      .dbg
654
        cmp     al, SSH_MSG_GLOBAL_REQUEST
655
        je      .glob_req
656
        cmp     al, SSH_MSG_CHANNEL_WINDOW_ADJUST
657
        je      .chan_win_adj
658
;        cmp     al, SSH_MSG_CHANNEL_REQUEST
659
;        je      .chan_req
660
        cmp     al, SSH_MSG_CHANNEL_EOF
661
        je      .chan_eof
662
        cmp     al, SSH_MSG_CHANNEL_CLOSE
663
        je      .chan_close
664
 
9987 hidnplayr 665
        DEBUGF  3, "SSH: Message type: %u\n", al
666
 
9106 hidnplayr 667
  .ret:
668
        ret
669
 
670
  .disc:
671
        DEBUGF  3, "SSH: Disconnect message received\n"
672
        mov     eax, SSHLIB_ERR_DISCONNECTING
673
        ret
674
 
675
  .ign:
676
        DEBUGF  3, "SSH: Ignore MSG received\n"
677
        jmp     .recv
678
 
679
  .dbg:
680
        DEBUGF  3, "SSH: Debug MSG received\n"
681
        ;TODO
682
        jmp     .recv
683
 
684
  .glob_req:
9987 hidnplayr 685
        add     esi, 4
686
        DEBUGF  3, "SSH: Global MSG received: %s\n", esi
9106 hidnplayr 687
        ;TODO
688
        jmp     .recv
689
 
690
  .chan_win_adj:
691
        mov     eax, dword[esi]
692
        bswap   eax
693
        mov     [ssh_chan.snd_wnd], eax
694
        ; TODO: validate channel number, act accordingly
695
        DEBUGF  3, "SSH: Channel %u window update received\n", eax
696
        jmp     .recv
697
 
698
  .chan_eof:
699
        mov     eax, dword[esi]
700
        bswap   eax
701
        ; TODO: validate channel number, act accordingly
702
        DEBUGF  3, "SSH: Channel %u EOF received\n", eax
703
        jmp     .recv
704
 
705
  .chan_close:
706
        mov     eax, dword[esi]
707
        bswap   eax
708
        ; TODO: validate channel number
709
        DEBUGF  3, "SSH: Channel %u close received\n", eax
710
        ; Reply with close message
711
        stdcall sshlib_send_packet, [con_ptr], ssh_msg_channel_close, ssh_msg_channel_close.length, 0
712
        xor     eax, eax
713
        ret
714
 
9216 dunkaist 715
endp