Subversion Repositories Kolibri OS

Rev

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

  1. ;    sshlib_connection.inc - SSH connection
  2. ;
  3. ;    Copyright (C) 2016-2024 Jeffrey Amelynck
  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 <http://www.gnu.org/licenses/>.
  17.  
  18. ; https://www.ietf.org/rfc/rfc4253.txt
  19.  
  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
  114.         invoke  sha2_256.init, [ctx_ptr]
  115. ; HASH: string  V_C, the client's version string (CR and NL excluded)
  116.         invoke  sha2_256.update, [ctx_ptr], ssh_ident_ha, ssh_msg_ident.length+4-2
  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
  143.         invoke  sha2_256.update, [ctx_ptr], edx, ecx
  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
  162.         mov     [eax + sshlib_connection.rx_crypt_proc], 0
  163.         mov     [eax + sshlib_connection.tx_crypt_proc], 0
  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.  
  170.         mov     [eax + sshlib_connection.rx_proc], sshlib_recv_packet_clear
  171.         mov     [eax + sshlib_connection.tx_proc], sshlib_send_packet_clear
  172.  
  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
  198.         invoke  sha2_256.update, [ctx_ptr], esi, edx
  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.  
  205.         mov     ebx, [con_ptr]
  206.         cmp     [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_KEXINIT
  207.         jne     .err_proto
  208.         DEBUGF  2, "Received KEX init\n"
  209.         lea     esi, [ebx + sshlib_connection.rx_buffer + sizeof.ssh_packet_header + 16]
  210.  
  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.  
  265.         lodsb
  266.         DEBUGF  2, "KEX First Packet Follows: %u\n", al
  267.  
  268. ; HASH: string I_S, the payload of the servers's SSH_MSG_KEXINIT
  269.         mov     esi, [con_ptr]
  270.         mov     eax, [esi + sshlib_connection.rx_buffer.packet_length]
  271.         movzx   ebx, [esi + sshlib_connection.rx_buffer.padding_length]
  272.         sub     eax, ebx
  273.         dec     eax
  274.         lea     edx, [eax+4]
  275.         bswap   eax
  276.         lea     esi, [esi + sshlib_connection.rx_buffer+1]
  277.         mov     dword[esi], eax
  278.         invoke  sha2_256.update, [ctx_ptr], esi, edx
  279.  
  280. ; Exchange keys with the server
  281.  
  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.  
  286.         stdcall sshlib_dh_gex, [con_ptr]
  287.         test    eax, eax
  288.         jnz     .err
  289.  
  290. ; Set keys and initialize transport subroutines
  291.  
  292.         DEBUGF  2, "SSH: Setting encryption keys\n"
  293.  
  294.         mov     ebx, [con_ptr]
  295.  
  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
  302.  
  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:
  326.         mov     [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_poly1305chacha20
  327.         jmp     .have_rx_crypt_and_mac
  328.  
  329.  
  330.  
  331.   .have_rx_crypt:
  332.         cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256
  333.         je      .rx_hmac_sha2_256
  334.         cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512
  335.         je      .rx_hmac_sha2_512
  336.         cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256_ETM
  337.         je      .rx_hmac_sha2_256_etm
  338.         cmp     [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512_ETM
  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:
  406.         mov     [ebx + sshlib_connection.tx_proc], sshlib_send_packet_poly1305chacha20
  407.         jmp     .have_tx_crypt_and_mac
  408.  
  409.  
  410.  
  411.   .have_tx_crypt:
  412.         cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256
  413.         je      .tx_hmac_sha2_256
  414.         cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512
  415.         je      .tx_hmac_sha2_512
  416.         cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256_ETM
  417.         je      .tx_hmac_sha2_256_etm
  418.         cmp     [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512_ETM
  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.  
  454. ; Re-seed RNG for padding bytes
  455.  
  456.         call    create_seed
  457.         call    init_random
  458.  
  459.         xor     eax, eax
  460.         ret
  461.  
  462.   .err_no_algo:
  463.         mov     eax, SSHLIB_ERR_NO_ALGO
  464.         ret
  465.  
  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.  
  485. proc sshlib_algo_find_match uses ebx ecx edx edi, client_str, algo_list
  486.  
  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.  
  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]
  646.         add     esi, sizeof.ssh_packet_header
  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.  
  665.         DEBUGF  3, "SSH: Message type: %u\n", al
  666.  
  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:
  685.         add     esi, 4
  686.         DEBUGF  3, "SSH: Global MSG received: %s\n", esi
  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.  
  715. endp
  716.