Subversion Repositories Kolibri OS

Rev

Rev 9114 | Rev 9216 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;    ssh.asm - SSH client for KolibriOS
  2. ;
  3. ;    Copyright (C) 2015-2021 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. format binary as ""
  19.  
  20. __DEBUG__               = 1
  21. __DEBUG_LEVEL__         = 2             ; 1: Everything, including sensitive information, 2: Debugging, 3: Errors only
  22.  
  23. BUFFERSIZE              = 64*1024       ; Must be at least 32K according rfc4253#section-6.1
  24. PACKETSIZE              = 32*1024       ; Must be at least 32K according rfc4253#section-6.1
  25. MAX_BITS                = 8192
  26.  
  27. DH_PRIVATE_KEY_SIZE     = 256
  28. MAX_INPUT_LENGTH        = 255
  29. MAX_USERNAME_LENGTH     = 256
  30. MAX_PASSWORD_LENGTH     = 256
  31. MAX_HOSTNAME_LENGTH     = 4096
  32. MAX_PUBLIC_KEY_SIZE     = 4096
  33.  
  34. use32
  35.  
  36.         db      'MENUET01'      ; signature
  37.         dd      1               ; header version
  38.         dd      start           ; entry point
  39.         dd      i_end           ; initialized size
  40.         dd      mem+65536       ; required memory
  41.         dd      mem+65536       ; stack pointer
  42.         dd      params          ; parameters
  43.         dd      0               ; path
  44.  
  45. include '../../macros.inc'
  46. ;include '../../struct.inc'
  47. purge mov,add,sub
  48. include '../../proc32.inc'
  49. include '../../dll.inc'
  50. include '../../debug-fdo.inc'
  51. include '../../network.inc'
  52. include '../../develop/libraries/libcrash/trunk/libcrash.inc'
  53.  
  54. ; macros for network byte order
  55. macro dd_n op {
  56.    dd 0 or (((op) and 0FF000000h) shr 24) or \
  57.            (((op) and 000FF0000h) shr  8) or \
  58.            (((op) and 00000FF00h) shl  8) or \
  59.            (((op) and 0000000FFh) shl 24)
  60. }
  61.  
  62. macro dw_n op {
  63.    dw 0 or (((op) and 0FF00h) shr 8) or \
  64.            (((op) and 000FFh) shl 8)
  65. }
  66.  
  67. macro str string {
  68.     local .start, .stop
  69.  
  70.     dd_n (.stop-.start)
  71.  
  72.     .start db string
  73.     .stop:
  74. }
  75.  
  76. proc dump_hex _ptr, _length
  77. if __DEBUG_LEVEL__ <= 1
  78.         pushad
  79.  
  80.         mov     esi, [_ptr]
  81.         mov     ecx, [_length]
  82.   .next_dword:
  83.         lodsd
  84.         bswap   eax
  85.         DEBUGF  1,'%x', eax
  86.         loop    .next_dword
  87.         DEBUGF  1,'\n'
  88.  
  89.         popad
  90. end if
  91.         ret
  92. endp
  93.  
  94. macro DEBUGM l, s, m {
  95. if __DEBUG__
  96.         DEBUGF  l, s
  97.   if l >=__DEBUG_LEVEL__
  98.         stdcall mpint_print, m
  99.   end if
  100. end if
  101. }
  102.  
  103. include 'mpint.inc'
  104. include 'seed.inc'
  105. include 'random.inc'
  106.  
  107. include 'aes256.inc'
  108. include 'aes256-ctr.inc'
  109. include 'aes256-cbc.inc'
  110.  
  111. include 'blowfish.inc'
  112. include 'blowfish-ctr.inc'
  113. include 'blowfish-cbc.inc'
  114.  
  115. include 'hmac_sha256.inc'
  116. include 'hmac_sha1.inc'
  117. include 'hmac_md5.inc'
  118.  
  119. include 'sshlib.inc'
  120.  
  121. include 'sshlib_mcodes.inc'
  122. include 'sshlib_transport.inc'
  123. include 'sshlib_connection.inc'
  124. include 'sshlib_dh_gex.inc'
  125. include 'sshlib_host.inc'
  126. include 'sshlib_channel.inc'
  127. include 'sshlib_userauth.inc'
  128.  
  129. include 'encodings.inc'         ; Unfortunately, we dont have UTF-8 capable console yet :(
  130.  
  131. start:
  132.         mcall   68, 11          ; Init heap
  133.  
  134.         DEBUGF  2, "SSH: Loading libraries\n"
  135.         stdcall dll.Load, @IMPORT
  136.         test    eax, eax
  137.         jnz     main.fail
  138.  
  139.         DEBUGF  2, "SSH: Init PRNG\n"
  140.         call    create_seed
  141.         call    init_random
  142.  
  143.         DEBUGF  2, "SSH: Init Console\n"
  144.         invoke  con_start, 1
  145.         invoke  con_init, 80, 25, 80, 250, title
  146.  
  147.         cmp     byte[params], 0
  148.         jne     main.connect
  149.  
  150. main:
  151.         invoke  con_cls
  152. ; Welcome user
  153.         invoke  con_write_asciiz, str1a
  154.   .prompt:
  155.         invoke  con_write_asciiz, str1b
  156. ; Reset window title
  157.         invoke  con_set_title, title
  158. ; Write prompt
  159.         invoke  con_write_asciiz, str2
  160. ; read string
  161.         mov     esi, params
  162.         invoke  con_gets, esi, MAX_HOSTNAME_LENGTH
  163. ; check for exit
  164.         test    eax, eax
  165.         jz      .done
  166.         cmp     byte[esi], 10
  167.         jz      .done
  168.  
  169.   .connect:
  170.         stdcall sshlib_connect, ssh_con, params
  171.         cmp     eax, 0
  172.         jg      .prompt
  173.         jl      .error
  174.  
  175.   .login:
  176.         mcall   68, 12, (MAX_USERNAME_LENGTH + MAX_PASSWORD_LENGTH)
  177.         test    eax, eax
  178.         jz      .done   ; ERR_NOMEM
  179.         mov     esi, eax
  180.         lea     edi, [eax + MAX_USERNAME_LENGTH]
  181.  
  182. ; Get username
  183.         invoke  con_write_asciiz, str12
  184.         invoke  con_gets, esi, MAX_USERNAME_LENGTH
  185.         test    eax, eax
  186. ;;        jz      .con_closed_must_clear
  187.  
  188. ; Get password
  189.         invoke  con_write_asciiz, str13a
  190.         invoke  con_gets, edi, MAX_PASSWORD_LENGTH
  191.         test    eax, eax
  192. ;;        jz      .con_closed_must_clear
  193.         invoke  con_write_asciiz, str13b
  194.  
  195. ; Authenticate
  196.         stdcall sshlib_userauth_password, ssh_con, esi, edi
  197. ; Clear and free username and password
  198.   .clear:
  199.         push    eax
  200.         mov     edx, edi
  201.         xor     eax, eax
  202.         mov     ecx, (MAX_USERNAME_LENGTH + MAX_PASSWORD_LENGTH)/4
  203.         rep     stosd
  204.         mcall   68, 13, edx
  205.         pop     eax
  206.  
  207.         cmp     eax, 0
  208.         jg      .login          ; Authentication failed
  209.         jl      .error          ; An error occured
  210.  
  211. ; Open a channel
  212.         stdcall sshlib_chan_open, ssh_con
  213.         cmp     eax, 0
  214.         jg      .prompt         ; Authentication failed
  215.         jl      .error          ; An error occured
  216.  
  217. ; Start console input handler thread without deactivating the current window
  218. ; Get active window ID
  219.         mcall   18, 7
  220.         push    eax
  221. ; Create thread
  222.         mcall   51, 1, con_in_thread, mem - 2048
  223. ; Activate window with given ID
  224.         pop     ecx
  225.         mcall   18, 3
  226.  
  227.   .loop:
  228.         invoke  con_get_flags
  229.         test    eax, 0x200                      ; console window closed?
  230.         jnz     .con_closed
  231.  
  232.         stdcall sshlib_msg_handler, ssh_con, 0
  233.         cmp     eax, 0
  234.         jle     .check_err
  235.  
  236.         cmp     [ssh_con.rx_buffer.message_code], SSH_MSG_CHANNEL_DATA
  237.         jne     .dump
  238.  
  239.         mov     eax, dword[ssh_con.rx_buffer.message_code+5]
  240.         bswap   eax
  241.         DEBUGF  1, 'SSH: got %u bytes of data !\n', eax
  242.  
  243.         lea     esi, [ssh_con.rx_buffer.message_code+5+4]
  244.         lea     edx, [esi+eax]
  245.         lea     edi, [ssh_con.rx_buffer]
  246.   @@:
  247.         call    get_byte_utf8
  248.         stosb
  249.         cmp     esi, edx
  250.         jb      @r
  251.         xor     al, al
  252.         stosb
  253.  
  254.         lea     esi, [ssh_con.rx_buffer]
  255.         DEBUGF  3, 'SSH msg: %s\n', esi
  256.  
  257.         invoke  con_write_asciiz, esi
  258.         jmp     .loop
  259.  
  260.   .dump:
  261.         DEBUGF  3, "SSH: Unsupported message: "
  262.         lea     esi, [ssh_con.rx_buffer.message_code]
  263.         mov     ecx, eax
  264.         pusha
  265.   @@:
  266.         lodsb
  267.         DEBUGF  3, "%x ", eax:2
  268.         dec     ecx
  269.         jnz     @r
  270.         popa
  271.         DEBUGF  3, "\n"
  272.         jmp     .loop
  273.  
  274.   .check_err:
  275.         jz      .err_conn_closed
  276.         cmp     ebx, EWOULDBLOCK
  277.         je      .loop
  278.         jmp     .err_sock
  279.  
  280.   .con_closed:
  281.         ; Send close message on the active channel
  282.         stdcall sshlib_send_packet, ssh_con, ssh_msg_channel_close, ssh_msg_channel_close.length, 0
  283.         jmp     .done
  284.  
  285.   .error:
  286.  
  287. ; TODO: proper cleanup after error
  288.  
  289.         cmp     eax, SSHLIB_ERR_NOMEM
  290.         je      .done
  291.         cmp     eax, SSHLIB_ERR_SOCKET
  292.         je      .err_sock
  293.         cmp     eax, SSHLIB_ERR_PROTOCOL
  294.         je      .err_proto
  295.         cmp     eax, SSHLIB_ERR_HOSTNAME
  296.         je      .err_hostname
  297.         cmp     eax, SSHLIB_ERR_HKEY_VERIFY_FAIL
  298.         je      .err_hostkey_fail
  299.         cmp     eax, SSHLIB_ERR_HKEY_SIGNATURE
  300.         je      .err_hostkey_signature
  301.         cmp     eax, SSHLIB_ERR_HKEY_PUBLIC_KEY
  302.         je      .err_hostkey
  303.  
  304.         jmp     .done
  305.  
  306.  
  307.   .err_proto:
  308. ;        lea     eax, [ssh_con.rx_buffer]
  309. ;        int3
  310.         invoke  con_write_asciiz, str7
  311.         jmp     .prompt
  312.  
  313.   .err_sock:
  314.         invoke  con_write_asciiz, str6
  315.  
  316.         mov     eax, str14
  317.         cmp     ebx, ETIMEDOUT
  318.         je      .err_sock_detail
  319.         mov     eax, str15
  320.         cmp     ebx, ECONNREFUSED
  321.         je      .err_sock_detail
  322.         mov     eax, str16
  323.         cmp     ebx, ECONNRESET
  324.         je      .err_sock_detail
  325.         mov     eax, str17
  326.   .err_sock_detail:
  327.         invoke  con_write_asciiz, eax
  328.         jmp     .prompt
  329.  
  330.   .err_hostname:
  331.         invoke  con_write_asciiz, str10
  332.         jmp     .prompt
  333.  
  334.   .err_conn_closed:
  335.         invoke  con_write_asciiz, str11
  336.         jmp     .prompt
  337.  
  338.   .err_hostkey:
  339.         invoke  con_write_asciiz, str19
  340.         jmp     .prompt
  341.  
  342.   .err_hostkey_signature:
  343.         invoke  con_write_asciiz, str20
  344.         jmp     .prompt
  345.  
  346.   .err_hostkey_fail:
  347.         invoke  con_write_asciiz, str21
  348.         jmp     .prompt
  349.  
  350.   .done:
  351.         invoke  con_exit, 1
  352.   .exit:
  353.         DEBUGF  3, "SSH: Exiting\n"
  354.         mcall   close, [ssh_con.socketnum]
  355.   .fail:
  356.         mcall   -1
  357.  
  358.  
  359. proc sshlib_callback_connecting, con_ptr, connstring_sz
  360.  
  361.         invoke  con_write_asciiz, str3
  362.         mov     eax, [con_ptr]
  363.         lea     eax, [eax+sshlib_connection.hostname_sz]
  364.         invoke  con_write_asciiz, eax
  365.         invoke  con_write_asciiz, str8
  366.         invoke  con_write_asciiz, [connstring_sz]
  367.         invoke  con_write_asciiz, str9
  368.  
  369.         ret
  370. endp
  371.  
  372.  
  373. proc sshlib_callback_hostkey_problem, con_ptr, problem_type, hostkey_sz
  374.  
  375.         cmp     [problem_type], SSHLIB_HOSTKEY_PROBLEM_UNKNOWN
  376.         je      .unknown
  377.         cmp     [problem_type], SSHLIB_HOSTKEY_PROBLEM_MISMATCH
  378.         je      .mismatch
  379.  
  380.         mov     eax, -1
  381.         ret
  382.  
  383.   .unknown:
  384.         invoke  con_write_asciiz, str22
  385.         jmp     .ask
  386.  
  387.   .mismatch:
  388.         invoke  con_write_asciiz, str23
  389. ;        jmp     .ask
  390.   .ask:
  391.         invoke  con_write_asciiz, str24a
  392.         invoke  con_write_asciiz, [hostkey_sz]
  393.         invoke  con_write_asciiz, str24b
  394.   .getansw:
  395.         invoke  con_getch2
  396.         or      al, 0x20        ; convert to lowercase
  397.         cmp     al, 'a'
  398.         je      .accept
  399.         cmp     al, 'c'
  400.         je      .once
  401.         cmp     al, 'x'
  402.         je      .refuse
  403.         jmp     .getansw
  404.  
  405.   .accept:
  406.         mov     eax, SSHLIB_HOSTKEY_ACCEPT
  407.         ret
  408.   .once:
  409.         mov     eax, SSHLIB_HOSTKEY_ONCE
  410.         ret
  411.   .refuse:
  412.         mov     eax, SSHLIB_HOSTKEY_REFUSE
  413.         ret
  414.  
  415. endp
  416.  
  417.  
  418.  
  419. align 16
  420. con_in_thread:
  421.  
  422.   .loop:
  423. ; TODO: check if channel is still open somehow
  424.  
  425.         invoke  con_get_input, keyb_input, MAX_INPUT_LENGTH
  426.         test    eax, eax
  427.         jz      .no_input
  428.  
  429.         mov     ecx, eax
  430.         mov     esi, keyb_input
  431.         mov     edi, ssh_msg_channel_data.data
  432.         call    recode_to_utf8
  433.  
  434.         lea     eax, [edi - ssh_msg_channel_data.data]
  435.         lea     ecx, [edi - ssh_msg_channel_data]
  436.         bswap   eax
  437.         mov     [ssh_msg_channel_data.len], eax
  438.         stdcall sshlib_send_packet, ssh_con, ssh_msg_channel_data, ecx, 0
  439.         cmp     eax, 0
  440.         jle     .exit
  441.  
  442.   .no_input:
  443.         invoke  con_get_flags
  444.         test    eax, 0x200                      ; con window closed?
  445.         jz      .loop
  446.  
  447.   .exit:
  448.         mcall   -1
  449.  
  450.  
  451. ; data
  452. title   db 'Secure Shell',0
  453. str1a   db 'SSHv2 client for KolibriOS',10,0
  454. str1b   db 10,'Please enter URL of SSH server (hostname:port)',10,0
  455. str2    db '> ',0
  456. str3    db 'Connecting to ',0
  457. str4    db 10,0
  458. str6    db 10, 27, '[2J',27,'[mA network error has occured.',10,0
  459. str7    db 10, 27, '[2J',27,'[mAn SSH protocol error has occured.',10,0
  460. str8    db ' (',0
  461. str9    db ')',10,0
  462. str10   db 'Host does not exist.',10,10,0
  463. str11   db 10, 27, '[2J',27,'[mThe remote host closed the connection.',10,0
  464. str12   db 'Login as: ',0
  465. str13a  db 'Password: ', 27, '[?25l', 27, '[30;40m', 0
  466. str13b  db 10, 27, '[?25h', 27, '[0m', 27, '[2J', 0
  467. str14   db 'The connection timed out',10,0
  468. str15   db 'The connection was refused',10,0
  469. str16   db 'The connection was reset',10,0
  470. str17   db 'No details available',10,0
  471. ;str18   db 'User authentication failed',10,0;;;;
  472. str19   db "The remote host's public key is invalid.", 10, 0
  473. str20   db "The remote host's signature is invalid.", 10, 0
  474. str21   db "The remote host failed to verify it's own public key.", 10, 0
  475. str22   db "The host key for the server was not found in the cache.", 10
  476.         db "There is no guarantee to the servers identity !",10, 0
  477.  
  478. str23   db "The host key provided by the host does not match the cached one.", 10
  479.         db "This may indicate that the remote server has been compromised!", 10, 0
  480.  
  481. str24a  db 10, "The remote host key is: ", 10, 0
  482. str24b  db 10, 10, "If you trust this host, press A to accept and store the (new) key.", 10
  483.         db "Press C to connect to the host but don't store the (new) key.", 10
  484.         db "Press X to abort.", 10, 0
  485.  
  486.  
  487. ssh_ident_ha:
  488.         dd_n (ssh_msg_ident.length-2)
  489. ssh_msg_ident:
  490.         db "SSH-2.0-KolibriOS_SSH_0.09",13,10
  491.   .length = $ - ssh_msg_ident
  492.  
  493.  
  494. ssh_msg_kex:
  495.         db SSH_MSG_KEXINIT
  496.   .cookie:
  497.         rd 4
  498.   .kex_algorithms:
  499.         str "diffie-hellman-group-exchange-sha256" ; diffie-hellman-group-exchange-sha1
  500.   .server_host_key_algorithms:
  501.         str "rsa-sha2-512,rsa-sha2-256,ssh-rsa"                    ;,ssh-dss
  502.   .encryption_algorithms_client_to_server:
  503.         str "aes256-ctr"                 ;,aes256-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128"
  504.   .encryption_algorithms_server_to_client:
  505.         str "aes256-ctr"                 ;,aes256-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128"
  506.   .mac_algorithms_client_to_server:
  507.         str "hmac-sha2-256"              ;,hmac-sha1,hmac-sha1-96,hmac-md5"
  508.   .mac_algorithms_server_to_client:
  509.         str "hmac-sha2-256"              ;,hmac-sha1,hmac-sha1-96,hmac-md5"
  510.   .compression_algorithms_client_to_server:
  511.         str "none"                       ;,zlib"
  512.   .compression_algorithms_server_to_client:
  513.         str "none"                       ;,zlib"
  514.   .languages_client_to_server:
  515.         str ""
  516.   .languages_server_to_client:
  517.         str ""
  518.   .first_kex_packet_follows:
  519.         db 0
  520.   .reserved:
  521.         dd_n 0
  522.   .length = $ - ssh_msg_kex
  523.  
  524.  
  525. ssh_msg_gex_req:
  526.         db SSH_MSG_KEX_DH_GEX_REQUEST
  527.         dd_n 4096/4                      ; DH GEX min
  528.         dd_n 4096/2                      ; DH GEX number of bits
  529.         dd_n 4096                        ; DH GEX Max
  530.   .length = $ - ssh_msg_gex_req
  531.  
  532.  
  533. ssh_msg_new_keys:
  534.         db SSH_MSG_NEWKEYS
  535.   .length = $ - ssh_msg_new_keys
  536.  
  537.  
  538. ssh_msg_request_service:
  539.         db SSH_MSG_SERVICE_REQUEST
  540.         str "ssh-userauth"              ; Service name
  541.   .length = $ - ssh_msg_request_service
  542.  
  543.  
  544. ssh_msg_channel_open:
  545.         db SSH_MSG_CHANNEL_OPEN
  546.         str "session"
  547.         dd_n 0                          ; Sender channel
  548.         dd_n BUFFERSIZE                 ; Initial window size
  549.         dd_n PACKETSIZE                 ; maximum packet size
  550.   .length = $ - ssh_msg_channel_open
  551.  
  552.  
  553. ssh_msg_channel_close:
  554.         db SSH_MSG_CHANNEL_CLOSE
  555.         dd_n 0                          ; Sender channel
  556.   .length = $ - ssh_msg_channel_close
  557.  
  558.  
  559. ssh_msg_channel_request:
  560.         db SSH_MSG_CHANNEL_REQUEST
  561.         dd_n 0                          ; Recipient channel
  562.         str "pty-req"
  563.         db 1                            ; Bool: want reply
  564.         str "xterm"
  565.         dd_n 80                         ; terminal width (rows)
  566.         dd_n 25                         ; terminal height (rows)
  567.         dd_n 80*8                       ; terminal width (pixels)
  568.         dd_n 25*16                      ; terminal height (pixels)
  569.  
  570.         dd_n 0                          ; list of supported opcodes
  571.   .length = $ - ssh_msg_channel_request
  572.  
  573.  
  574. ssh_msg_shell_request:
  575.         db SSH_MSG_CHANNEL_REQUEST
  576.         dd_n 0                          ; Recipient channel
  577.         str "shell"
  578.         db 1                            ; Bool: want reply
  579.   .length = $ - ssh_msg_shell_request
  580.  
  581.  
  582. ssh_msg_channel_data:
  583.         db SSH_MSG_CHANNEL_DATA
  584.         dd_n 0                          ; Sender channel
  585.   .len  dd ?
  586.   .data rb 4*MAX_INPUT_LENGTH + 1
  587.  
  588.  
  589. ssh_msg_channel_window_adjust:
  590.         db SSH_MSG_CHANNEL_WINDOW_ADJUST
  591.         dd_n 0                          ; Sender channel
  592.   .wnd  dd ?
  593.   .length = $ - ssh_msg_channel_window_adjust
  594.  
  595.  
  596. include_debug_strings
  597.  
  598. align 4
  599. @IMPORT:
  600.  
  601. library network, 'network.obj', \
  602.         console, 'console.obj', \
  603.         libcrash, 'libcrash.obj', \
  604.         libini, 'libini.obj'
  605.  
  606. import  network, \
  607.         getaddrinfo, 'getaddrinfo', \
  608.         freeaddrinfo, 'freeaddrinfo', \
  609.         inet_ntoa, 'inet_ntoa'
  610.  
  611. import  console, \
  612.         con_start, 'START', \
  613.         con_init, 'con_init', \
  614.         con_write_asciiz, 'con_write_asciiz', \
  615.         con_exit, 'con_exit', \
  616.         con_gets, 'con_gets', \
  617.         con_cls, 'con_cls', \
  618.         con_getch2, 'con_getch2', \
  619.         con_get_flags, 'con_get_flags', \
  620.         con_set_title, 'con_set_title', \
  621.         con_get_input, 'con_get_input'
  622.  
  623. import  libcrash, \
  624.         sha512_init, 'sha512_init', \
  625.         sha512_update, 'sha512_update', \
  626.         sha512_final, 'sha512_final',\
  627.         sha256_init, 'sha256_init', \
  628.         sha256_update, 'sha256_update', \
  629.         sha256_final, 'sha256_final',\
  630.         sha1_init, 'sha1_init', \
  631.         sha1_update, 'sha1_update', \
  632.         sha1_final, 'sha1_final', \
  633.         md5_init, 'md5_init', \
  634.         md5_update, 'md5_update', \
  635.         md5_final, 'md5_final'
  636.  
  637. import  libini, \
  638.         ini_get_str, 'ini_get_str', \
  639.         ini_set_str, 'ini_set_str'
  640.  
  641. IncludeIGlobals
  642.  
  643. i_end:
  644.  
  645. IncludeUGlobals
  646.  
  647. params          rb MAX_HOSTNAME_LENGTH
  648.  
  649. ssh_con         sshlib_connection
  650. ssh_chan        sshlib_channel
  651.  
  652. keyb_input      rb MAX_INPUT_LENGTH
  653.  
  654. mem:
  655.