Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  VNC client for KolibriOS                                       ;;
  7. ;;                                                                 ;;
  8. ;;  Written by hidnplayr@kolibrios.org                             ;;
  9. ;;                                                                 ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. thread_start:
  16.  
  17.         mcall   40, 0                   ; disable all events for this thread
  18.  
  19. ; Extract port number from server address
  20.         mov     esi, serveraddr
  21.   @@:
  22.         lodsb
  23.         test    al, al
  24.         jz      .port_done
  25.         cmp     al, ':'
  26.         jne     @r
  27.         mov     byte[esi-1], 0          ; replace colon with 0 byte, we dont want to upset getaddrinfo
  28.         xor     eax, eax
  29.         xor     ebx, ebx                ; port number
  30.   @@:
  31.         lodsb
  32.         test    al, al
  33.         jz      @f
  34.         sub     al, '0'
  35.         jb      err_dns
  36.         cmp     al, 9
  37.         ja      err_dns
  38.         lea     ebx, [ebx*4+ebx]
  39.         lea     ebx, [ebx*2+eax]
  40.         jmp     @b
  41.   @@:
  42.         xchg    bl, bh
  43.         mov     [sockaddr1.port], bx
  44.   .port_done:
  45.  
  46. ; Resolve hostname
  47.         push    esp                     ; reserve stack place
  48.         invoke  getaddrinfo, serveraddr, 0, 0, esp
  49.         pop     esi
  50.         test    eax, eax
  51.         jnz     err_dns
  52.  
  53.         mov     eax, [esi+addrinfo.ai_addr]
  54.         mov     eax, [eax+sockaddr_in.sin_addr]
  55.         mov     [sockaddr1.ip], eax
  56.         invoke  freeaddrinfo, esi
  57.  
  58.         DEBUGF  1, "Connecting to %u.%u.%u.%u:%u\n", \
  59.         [sockaddr1.ip]:1, [sockaddr1.ip+1]:1, [sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \
  60.         [sockaddr1.port]:2
  61.  
  62. ; Open socket
  63.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  64.         cmp     eax, -1
  65.         je      err_sock
  66.         mov     [socketnum], eax
  67.  
  68. ; Connect to the server
  69.         mcall   connect, [socketnum], sockaddr1, 18
  70.         cmp     eax, -1
  71.         je      err_connect
  72.  
  73. ; Verify handshake from server
  74.         call    read_data
  75.         cmp     eax, 12
  76.         jb      err_proto
  77.         cmp     dword[esi], "RFB "
  78.         jne     err_proto
  79.         add     esi, 12
  80.  
  81. ; Did we get an error message already?
  82.         cmp     eax, 16
  83.         jb      @f
  84.         lodsd
  85.         test    eax, eax
  86.         je      err_handshake
  87.   @@:
  88.  
  89. ; Reply to handshake
  90.         DEBUGF  1, "Sending handshake\n"
  91.         mcall   send, [socketnum], HandShake, 12, 0
  92.  
  93. ; VNC 3.3 protocol: server decides security type
  94.         call    read_data
  95.         cmp     eax, 4
  96.         jb      err_proto
  97.         lodsd
  98.         cmp     eax, 0x00000000
  99.         je      err_handshake
  100.         cmp     eax, 0x01000000         ; no security
  101.         je      initialize
  102.         cmp     eax, 0x02000000         ; VNC security
  103.         je      vnc_security
  104.         jmp     err_proto
  105.  
  106. vnc_security:
  107.  
  108.         lea     eax, [esi+8]
  109.         cmp     [datapointer], eax
  110.         jb      err_proto
  111.  
  112.         push    esi     ; pointer to message
  113.  
  114.         mov     dword[password], 0
  115.         mov     dword[password+4], 0
  116.  
  117.         and     [USERbox.flags], not ed_focus
  118.         or      [USERbox.flags], ed_disabled
  119.         or      [PASSbox.flags], ed_focus
  120.  
  121.         mov     [status], STATUS_REQ_LOGIN
  122.         or      [work], WORK_GUI
  123.   @@:
  124.         mcall   5, 10
  125.         cmp     [status], STATUS_LOGIN
  126.         je      @f
  127.         cmp     [status], STATUS_REQ_LOGIN
  128.         je      @r
  129.         mcall   -1
  130.   @@:
  131.         DEBUGF  1, "VNC authentication\n"
  132.  
  133. ; Bit reverse the password and create DES keys
  134.         mov     ebx, dword[password]
  135.         mov     edx, ebx
  136.         and     ebx, 0xf0f0f0f0
  137.         shr     ebx, 4
  138.         and     edx, 0x0f0f0f0f
  139.         shl     edx, 4
  140.         or      ebx, edx
  141.         mov     edx, ebx
  142.         and     ebx, 0xCCCCCCCC
  143.         shr     ebx, 2
  144.         and     edx, 0x33333333
  145.         shl     edx, 2
  146.         or      ebx, edx
  147.         mov     edx, ebx
  148.         and     ebx, 0xAAAAAAAA
  149.         shr     ebx, 1
  150.         and     edx, 0x55555555
  151.         shl     edx, 1
  152.         or      ebx, edx
  153.         bswap   ebx
  154.  
  155.         mov     eax, dword[password+4]
  156.         mov     edx, eax
  157.         and     eax, 0xf0f0f0f0
  158.         shr     eax, 4
  159.         and     edx, 0x0f0f0f0f
  160.         shl     edx, 4
  161.         or      eax, edx
  162.         mov     edx, eax
  163.         and     eax, 0xCCCCCCCC
  164.         shr     eax, 2
  165.         and     edx, 0x33333333
  166.         shl     edx, 2
  167.         or      eax, edx
  168.         mov     edx, eax
  169.         and     eax, 0xAAAAAAAA
  170.         shr     eax, 1
  171.         and     edx, 0x55555555
  172.         shl     edx, 1
  173.         or      edx, eax
  174.         bswap   edx
  175.  
  176.         mov     edi, keys
  177.         call    DES_create_keys
  178.  
  179. ; Encrypt message with DES
  180.         mov     esi, [esp]
  181.         mov     ebx, dword[esi+0]
  182.         mov     edx, dword[esi+4]
  183.         call    encrypt_DES
  184.         mov     esi, [esp]
  185.         mov     dword[esi+0], ebx
  186.         mov     dword[esi+4], edx
  187.  
  188.         mov     ebx, dword[esi+8]
  189.         mov     edx, dword[esi+12]
  190.         call    encrypt_DES
  191.         mov     esi, [esp]
  192.         mov     dword[esi+8], ebx
  193.         mov     dword[esi+12], edx
  194.  
  195. ; Blank out the password and key fields in RAM
  196.         mov     edi, password
  197.         mov     ecx, 384/4
  198.         xor     eax, eax
  199.         rep     stosd
  200.  
  201. ; Send the authentication response to server
  202.         pop     edx
  203.         mcall   send, [socketnum], , 16, 0
  204.  
  205. securityresult:
  206. ; Wait for SecurityResult from server
  207.         call    read_data
  208.         cmp     eax, 4
  209.         jb      err_proto
  210.         cmp     dword[esi], 0           ; OK
  211.         jne     err_login
  212.  
  213. initialize:
  214.         DEBUGF  1, "Sending ClientInit\n"
  215.         mcall   send, [socketnum], ClientInit, 1, 0
  216.  
  217.         call    read_data               ; now the server should send init message
  218.         cmp     eax, ServerInit.name
  219.         jb      err_proto
  220.  
  221.         DEBUGF  2, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \
  222.         [esi+ServerInit.pixelformat.bpp]:1, \
  223.         [esi+ServerInit.pixelformat.depth]:1, \
  224.         [esi+ServerInit.pixelformat.big_endian]:1, \
  225.         [esi+ServerInit.pixelformat.true_color]:1
  226.  
  227.         mov     eax, dword[esi+ServerInit.width]
  228.         mov     dword[FramebufferUpdateRequest.width], eax
  229.         bswap   eax
  230.         mov     dword[screen], eax
  231.         DEBUGF  1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2
  232.  
  233. ; Set main window caption to servername
  234.         mov     ecx, dword[esi+ServerInit.name_length]
  235.         bswap   ecx
  236.         add     esi, ServerInit.name
  237.         lea     eax, [esi+ecx]
  238.         cmp     [datapointer], eax
  239.         jb      err_proto
  240.         cmp     ecx, 64         ; Limit name length to 64 chars
  241.         jbe     @f
  242.         mov     ecx, 64
  243.   @@:
  244.         mov     edi, servername
  245.         rep movsb
  246.         mov     byte[edi], 0
  247.         mov     [name.dash], "-"
  248.  
  249.         DEBUGF  1, "Sending pixel format\n"
  250.         mcall   send, [socketnum], SetPixelFormat, 20, 0
  251.  
  252.         DEBUGF  1, "Sending encoding info\n"
  253.         mcall   send, [socketnum], SetEncodings, SetEncodings.length, 0
  254.  
  255. ; Tell the main thread we are ready for business!
  256.         mov     [status], STATUS_CONNECTED
  257.  
  258. ; Request initial framebuffer update from server
  259.         mov     [FramebufferUpdateRequest.inc], 0
  260.  
  261. request_fbu:
  262.         DEBUGF  1, "Requesting framebuffer update\n"
  263.         mcall   send, [socketnum], FramebufferUpdateRequest, 10, 0
  264.         mov     [FramebufferUpdateRequest.inc], 1
  265.  
  266. thread_loop:
  267.         call    read_data              ; Read the data into the buffer
  268.  
  269.         lodsb
  270.         cmp     al, 0
  271.         je      framebufferupdate
  272.         cmp     al, 1
  273.         je      setcolourmapentries
  274.         cmp     al, 2
  275.         je      bell
  276.         cmp     al, 3
  277.         je      servercuttext
  278.  
  279.         DEBUGF  2, "Unknown server command: %u\n", al
  280.         jmp     thread_loop
  281.  
  282. framebufferupdate:
  283.  
  284.   @@:
  285.         lea     eax, [esi+6]
  286.         cmp     [datapointer], eax
  287.         jae     @f
  288.         call    read_data.more
  289.         jmp     @b
  290.   @@:
  291.  
  292.         inc     esi     ; padding
  293.         lodsw
  294.         xchg    al, ah
  295.         mov     [rectangles], ax
  296.         DEBUGF  1, "Framebufferupdate: %u rectangles\n", ax
  297.  
  298. rectangle_loop:
  299.  
  300.   @@:
  301.         lea     eax, [esi+12]
  302.         cmp     [datapointer], eax
  303.         jae     @f
  304.         call    read_data.more
  305.         jmp     @b
  306.   @@:
  307.  
  308.         xor     eax, eax
  309.         lodsw
  310.         xchg    al, ah
  311.         mov     [rectangle.x], eax
  312.         lodsw
  313.         xchg    al, ah
  314.         mov     [rectangle.y], eax
  315.         lodsw
  316.         xchg    al, ah
  317.         mov     [rectangle.width], eax
  318.         lodsw
  319.         xchg    al, ah
  320.         mov     [rectangle.height], eax
  321.  
  322.         lodsd                           ; encoding
  323.         bswap   eax
  324.         DEBUGF  1, "Rectangle: x=%u y=%u width=%u height=%u encoding: ",\
  325.         [rectangle.x]:2, [rectangle.y]:2, [rectangle.width]:2, [rectangle.height]:2
  326.  
  327.         cmp     eax, 0
  328.         je      encoding_raw
  329.         cmp     eax, 1
  330.         je      encoding_CopyRect
  331.         cmp     eax, 2
  332.         je      encoding_RRE
  333.         cmp     eax, 15
  334.         je      encoding_TRLE
  335.         cmp     eax, 16
  336.         je      encoding_ZRLE
  337.         cmp     eax, 0xffffff11
  338.         je      encoding_cursor
  339.  
  340.         DEBUGF  2, "unknown encoding: %u\n", eax
  341.         jmp     thread_loop
  342.  
  343. next_rectangle:
  344.         or      [work], WORK_FRAMEBUFFER
  345.         dec     [rectangles]
  346.         jnz     rectangle_loop
  347.         jmp     request_fbu
  348.  
  349.  
  350. setcolourmapentries:
  351.  
  352.         DEBUGF  1, "Server sent SetColourMapEntries message\n"
  353.  
  354.   @@:
  355.         lea     eax, [esi+5]
  356.         cmp     [datapointer], eax
  357.         jae     @f
  358.         call    read_data.more
  359.         jmp     @b
  360.   @@:
  361.  
  362.         inc     esi             ; padding
  363.  
  364.         xor     eax, eax
  365.         lodsw                   ; first color (just ignore for now)
  366.  
  367.         lodsw                   ; number of colors (use to find end of message)
  368.         xchg    al, ah
  369.         lea     eax, [eax*2+eax]
  370.         shl     eax, 1
  371.   @@:
  372.         push    eax
  373.         add     eax, esi
  374.         cmp     [datapointer], eax
  375.         jae     @f
  376.         call    read_data.more
  377.         pop     eax
  378.         jmp     @b
  379.   @@:
  380.         pop     eax
  381.  
  382.         add     esi, eax        ; Just skip it for now.
  383.         jmp     thread_loop
  384.  
  385.  
  386. bell:
  387.         mcall   55, 55, , , beep
  388.         jmp     thread_loop
  389.  
  390.  
  391. servercuttext:
  392.  
  393.         DEBUGF  1, "Server cut text\n"
  394.  
  395.   @@:
  396.         lea     eax, [esi+7]
  397.         cmp     [datapointer], eax
  398.         jae     @f
  399.         call    read_data.more
  400.         jmp     @b
  401.   @@:
  402.  
  403.         add     esi, 3
  404.         lodsd
  405.         bswap   eax
  406.         mov     ecx, eax
  407.  
  408.   @@:
  409.         lea     eax, [esi+ecx]
  410.         cmp     [datapointer], eax
  411.         jae     @f
  412.         call    read_data.more
  413.         jmp     @b
  414.   @@:
  415.  
  416.         ; TODO: paste text to clipboard
  417.  
  418.         DEBUGF  1, "%u bytes of text\n", ecx
  419.         add     esi, ecx
  420.         jmp     thread_loop
  421.  
  422.  
  423. read_data:
  424.         mov     [datapointer], receive_buffer
  425.         mov     esi, receive_buffer
  426.   .more:
  427.         push    ebx ecx edx esi edi
  428.         neg     esi
  429.         add     esi, receive_buffer + RECEIVE_BUFFER_SIZE
  430.         jz      .buffer_end_reached
  431.         xor     edi, edi
  432.         mcall   recv, [socketnum], [datapointer]
  433.         pop     edi esi edx ecx ebx
  434.         cmp     eax, -1
  435.         je      err_sock
  436.         test    eax, eax
  437.         jz      err_disconnected
  438.         add     [datapointer], eax
  439.         ret
  440.  
  441.   .buffer_end_reached:
  442.         DEBUGF  1, "end of buffer reached, re-organizing\n"
  443.         pop     edi esi edx ecx ebx
  444.         ; Buffer is full, first needed data by program is pointed to by esi.
  445.         ; Move all usefull data to begin of buffer
  446.         cmp     esi, receive_buffer
  447.         je      err_proto
  448.         mov     ecx, [datapointer]
  449.         sub     ecx, esi
  450.         mov     edi, receive_buffer
  451.         rep movsb
  452.         mov     [datapointer], edi      ; new end of data
  453.         mov     esi, receive_buffer     ; new start of data
  454.         jmp     .more
  455.  
  456.  
  457. err_disconnected:
  458.         mov     [status], STATUS_DISCONNECTED
  459.         or      [work], WORK_GUI
  460.         mcall   -1
  461.  
  462. err_dns:
  463.         mov     [status], STATUS_DNS_ERR
  464.         or      [work], WORK_GUI
  465.         mcall   -1
  466.  
  467. err_sock:
  468. ; TODO: distinguish between different socket errors!
  469.         DEBUGF  2, "Socket error: %u\n", ebx
  470.         mov     [status], STATUS_SOCK_ERR
  471.         or      [work], WORK_GUI
  472.         mcall   -1
  473.  
  474. err_connect:
  475.         mov     [status], STATUS_CONNECT_ERR
  476.         or      [work], WORK_GUI
  477.         mcall   -1
  478.         ret
  479.  
  480. err_proto:
  481.         mov     [status], STATUS_PROTO_ERR
  482.         or      [work], WORK_GUI
  483.         mcall   -1
  484.         ret
  485.  
  486. err_handshake:
  487.         mov     [status], STATUS_SECURITY_ERR
  488.  
  489.         lodsd                   ; Custom message from server?
  490.         test    eax, eax
  491.         jz      .no_msg
  492.         bswap   eax
  493.         mov     ecx, eax
  494.         cmp     ecx, 512
  495.         jb      @f
  496.         mov     ecx, 512
  497.   @@:
  498.         mov     edi, sz_err_security_c
  499.         rep movsb
  500.         mov     byte[edi], 0
  501.         mov     [status], STATUS_SECURITY_ERR_C
  502.   .no_msg:
  503.  
  504.         or      [work], WORK_GUI
  505.         mcall   -1
  506.         ret
  507.  
  508. err_login:
  509.         mov     [status], STATUS_LOGIN_FAILED
  510.         or      [work], WORK_GUI
  511.         mcall   -1
  512.         ret
  513.