Subversion Repositories Kolibri OS

Rev

Rev 5708 | Rev 5720 | Go to most recent revision | 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. ; Wait for handshake from server
  74.         ; TODO: implement timeout
  75.         call    wait_for_data
  76.         cmp     dword[receive_buffer], "RFB "
  77.         jne     err_proto
  78.  
  79. ; Reply to handshake
  80.         DEBUGF  1, "Sending handshake\n"
  81.         mcall   send, [socketnum], HandShake, 12, 0
  82.         call    wait_for_data
  83.  
  84.         cmp     dword[receive_buffer], 0x01000000       ; no security
  85.         je      initialize
  86.         cmp     dword[receive_buffer], 0x02000000       ; VNC security
  87.         je      vnc_security
  88.  
  89.         jmp     err_security
  90.  
  91. vnc_security:
  92.  
  93.         mov     dword[password], 0
  94.         mov     dword[password+4], 0
  95.  
  96.         and     [USERbox.flags], not ed_focus
  97.         or      [USERbox.flags], ed_disabled
  98.         or      [PASSbox.flags], ed_focus
  99.  
  100.         mov     [status], STATUS_REQ_LOGIN
  101.         inc     [update_gui]
  102.   @@:
  103.         mcall   5, 10
  104.         cmp     [status], STATUS_LOGIN
  105.         je      @f
  106.         cmp     [status], STATUS_REQ_LOGIN
  107.         je      @r
  108.         mcall   -1
  109.   @@:
  110.         DEBUGF  1, "VNC authentication\n"
  111.  
  112. ; Bit reverse the password and create DES keys
  113.  
  114.         mov     ebx, dword[password]
  115.         mov     edx, ebx
  116.         and     ebx, 0xf0f0f0f0
  117.         shr     ebx, 4
  118.         and     edx, 0x0f0f0f0f
  119.         shl     edx, 4
  120.         or      ebx, edx
  121.         mov     edx, ebx
  122.         and     ebx, 0xCCCCCCCC
  123.         shr     ebx, 2
  124.         and     edx, 0x33333333
  125.         shl     edx, 2
  126.         or      ebx, edx
  127.         mov     edx, ebx
  128.         and     ebx, 0xAAAAAAAA
  129.         shr     ebx, 1
  130.         and     edx, 0x55555555
  131.         shl     edx, 1
  132.         or      ebx, edx
  133.         bswap   ebx
  134.  
  135.         mov     eax, dword[password+4]
  136.         mov     edx, eax
  137.         and     eax, 0xf0f0f0f0
  138.         shr     eax, 4
  139.         and     edx, 0x0f0f0f0f
  140.         shl     edx, 4
  141.         or      eax, edx
  142.         mov     edx, eax
  143.         and     eax, 0xCCCCCCCC
  144.         shr     eax, 2
  145.         and     edx, 0x33333333
  146.         shl     edx, 2
  147.         or      eax, edx
  148.         mov     edx, eax
  149.         and     eax, 0xAAAAAAAA
  150.         shr     eax, 1
  151.         and     edx, 0x55555555
  152.         shl     edx, 1
  153.         or      edx, eax
  154.         bswap   edx
  155.  
  156.         mov     edi, keys
  157.         call    DES_create_keys
  158.  
  159. ; Encrypt message with DES
  160.  
  161.         mov     ebx, dword[receive_buffer+4]
  162.         mov     edx, dword[receive_buffer+8]
  163.         call    encrypt_DES
  164.         mov     dword[receive_buffer+4], ebx
  165.         mov     dword[receive_buffer+8], edx
  166.  
  167.         mov     ebx, dword[receive_buffer+12]
  168.         mov     edx, dword[receive_buffer+16]
  169.         call    encrypt_DES
  170.         mov     dword[receive_buffer+12], ebx
  171.         mov     dword[receive_buffer+16], edx
  172.  
  173. ; Blank out the password and key fields in RAM
  174.  
  175.         mov     edi, password
  176.         mov     ecx, 384/4
  177.         xor     eax, eax
  178.         rep     stosd
  179.  
  180. ; Send the authentication response to server
  181.  
  182.         mcall   send, [socketnum], receive_buffer+4, 16, 0
  183.  
  184.         call    wait_for_data
  185.         cmp     dword[receive_buffer], 0
  186.         jne     err_login
  187. ;        jmp     initialize
  188.  
  189. initialize:
  190.         DEBUGF  1, "Sending ClientInit\n"
  191.         mcall   send, [socketnum], ClientInit, 1, 0
  192.  
  193.         call    wait_for_data       ; now the server should send init message
  194.  
  195.         DEBUGF  1, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \
  196.         [receive_buffer+framebuffer.pixelformat.bpp]:1, \
  197.         [receive_buffer+framebuffer.pixelformat.depth]:1, \
  198.         [receive_buffer+framebuffer.pixelformat.big_endian]:1, \
  199.         [receive_buffer+framebuffer.pixelformat.true_color]:1
  200.  
  201.         mov     eax, dword[receive_buffer+framebuffer.width]
  202.         mov     dword[FramebufferUpdateRequest.width], eax
  203.         bswap   eax
  204.         mov     dword[screen], eax
  205.         DEBUGF  1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2
  206.  
  207.         DEBUGF  1, "Sending pixel format\n"
  208. if BITS_PER_PIXEL = 8
  209.         mcall   send, [socketnum], SetPixelFormat8, 20, 0
  210. else if BITS_PER_PIXEL = 16
  211.         mcall   send, [socketnum], SetPixelFormat16, 20, 0
  212. else
  213.         mcall   send, [socketnum], SetPixelFormat24, 20, 0
  214. end if
  215.  
  216.         DEBUGF  1, "Sending encoding info\n"
  217.         mcall   send, [socketnum], SetEncodings, SetEncodings.length, 0
  218.  
  219. ; Set main window caption to servername
  220.         mov     ecx, dword[receive_buffer+framebuffer.name_length]
  221.         bswap   ecx
  222.         cmp     ecx, 64
  223.         jbe     @f
  224.         mov     ecx, 64
  225.   @@:
  226.         lea     esi, [receive_buffer+framebuffer.name]
  227.         mov     edi, servername
  228.         rep movsb
  229.         mov     byte[edi], 0
  230.         mov     [name.dash], "-"
  231.  
  232. ; Tell the main thread we are ready for business!
  233.         mov     [status], STATUS_CONNECTED
  234.  
  235. ; Request initial framebuffer update from server
  236.         mov     [FramebufferUpdateRequest.inc], 0
  237.  
  238. request_fbu:
  239.         DEBUGF  1, "Requesting framebuffer update\n"
  240.         mcall   send, [socketnum], FramebufferUpdateRequest, 10, 0
  241.         mov     [FramebufferUpdateRequest.inc], 1
  242.  
  243. thread_loop:
  244.         call    read_data              ; Read the data into the buffer
  245.  
  246.         lodsb
  247.         cmp     al, 0
  248.         je      framebufferupdate
  249.         cmp     al, 1
  250.         je      setcolourmapentries
  251.         cmp     al, 2
  252.         je      bell
  253.         cmp     al, 3
  254.         je      servercuttext
  255.  
  256.         DEBUGF  2, "Unknown server command: %u\n", al
  257.         jmp     thread_loop
  258.  
  259. framebufferupdate:
  260.  
  261.   @@:
  262.         lea     eax, [esi+6]
  263.         cmp     [datapointer], eax
  264.         jae     @f
  265.         call    read_data.more
  266.         jmp     @b
  267.   @@:
  268.  
  269.         inc     esi     ; padding
  270.         lodsw
  271.         xchg    al, ah
  272.         mov     [rectangles], ax
  273.         DEBUGF  1, "Framebufferupdate: %u rectangles\n", ax
  274.  
  275. rectangle_loop:
  276.  
  277.   @@:
  278.         lea     eax, [esi+12]
  279.         cmp     [datapointer], eax
  280.         jae     @f
  281.         call    read_data.more
  282.         jmp     @b
  283.   @@:
  284.  
  285.         xor     eax, eax
  286.         lodsw
  287.         xchg    al, ah
  288.         mov     [rectangle.x], eax
  289.         lodsw
  290.         xchg    al, ah
  291.         mov     [rectangle.y], eax
  292.         lodsw
  293.         xchg    al, ah
  294.         mov     [rectangle.width], eax
  295.         lodsw
  296.         xchg    al, ah
  297.         mov     [rectangle.height], eax
  298.  
  299.         lodsd                           ; encoding
  300.         bswap   eax
  301.         DEBUGF  1, "Rectangle: x=%u y=%u width=%u height=%u encoding: ",\
  302.         [rectangle.x]:2, [rectangle.y]:2, [rectangle.width]:2, [rectangle.height]:2
  303.  
  304.         cmp     eax, 0
  305.         je      encoding_raw
  306.         cmp     eax, 1
  307.         je      encoding_CopyRect
  308.         cmp     eax, 2
  309.         je      encoding_RRE
  310. ;        cmp     eax, 5
  311. ;        je      encoding_hextile
  312. ;        cmp     eax, 15
  313. ;        je      encoding_TRLE
  314. ;        cmp     eax, 16
  315. ;        je      encoding_ZRLE
  316.  
  317.         DEBUGF  2, "unknown encoding: %u\n", eax
  318.         jmp     thread_loop
  319.  
  320. next_rectangle:
  321.         inc     [update_framebuffer]
  322.         dec     [rectangles]
  323.         jnz     rectangle_loop
  324.         jmp     request_fbu
  325.  
  326.  
  327. setcolourmapentries:
  328.  
  329.         DEBUGF  1, "Server sent SetColourMapEntries message\n"
  330.  
  331.   @@:
  332.         lea     eax, [esi+5]
  333.         cmp     [datapointer], eax
  334.         jae     @f
  335.         call    read_data.more
  336.         jmp     @b
  337.   @@:
  338.  
  339.         inc     esi             ; padding
  340.  
  341.         xor     eax, eax
  342.         lodsw                   ; first color (just ignore for now)
  343.  
  344.         lodsw                   ; number of colors (use to find end of message)
  345.         xchg    al, ah
  346.         lea     eax, [eax*2+eax]
  347.         shl     eax, 1
  348.   @@:
  349.         push    eax
  350.         add     eax, esi
  351.         cmp     [datapointer], eax
  352.         jae     @f
  353.         call    read_data.more
  354.         pop     eax
  355.         jmp     @b
  356.   @@:
  357.         pop     eax
  358.  
  359.         add     esi, eax        ; Just skip it for now.
  360.         jmp     thread_loop
  361.  
  362.  
  363. bell:
  364.         mcall   55, 55, , , beep
  365.         jmp     thread_loop
  366.  
  367.  
  368. servercuttext:
  369.  
  370.         DEBUGF  1, "Server cut text\n"
  371.  
  372.   @@:
  373.         lea     eax, [esi+7]
  374.         cmp     [datapointer], eax
  375.         jae     @f
  376.         call    read_data.more
  377.         jmp     @b
  378.   @@:
  379.  
  380.         add     esi, 3
  381.         lodsd
  382.         bswap   eax
  383.         mov     ecx, eax
  384.  
  385.   @@:
  386.         lea     eax, [esi+ecx]
  387.         cmp     [datapointer], eax
  388.         jae     @f
  389.         call    read_data.more
  390.         jmp     @b
  391.   @@:
  392.  
  393.         ; TODO: paste text to clipboard
  394.  
  395.         DEBUGF  1, "%u bytes of text\n", ecx
  396.         add     esi, ecx
  397.         jmp     thread_loop
  398.  
  399.  
  400. read_data:
  401.         mov     [datapointer], receive_buffer
  402.         mov     esi, receive_buffer
  403.   .more:
  404.         push    ebx ecx edx esi edi
  405.         neg     esi
  406.         add     esi, receive_buffer + RECEIVE_BUFFER_SIZE
  407.         jz      .buffer_end_reached
  408.         xor     edi, edi
  409.         mcall   recv, [socketnum], [datapointer]
  410.         pop     edi esi edx ecx ebx
  411.         cmp     eax, -1
  412.         je      err_sock
  413.         test    eax, eax
  414.         jz      err_disconnected
  415.         add     [datapointer], eax
  416.         ret
  417.  
  418.   .buffer_end_reached:
  419.         ; Buffer is full, first needed data by program is pointed to by esi.
  420.         ; Move all usefull data to begin of buffer
  421.         cmp     esi, receive_buffer
  422.         je      err_proto
  423.         mov     ecx, [datapointer]
  424.         sub     ecx, esi
  425.         mov     edi, receive_buffer
  426.         rep movsb
  427.         mov     [datapointer], edi      ; new end of data
  428.         mov     esi, receive_buffer     ; new start of data
  429.         jmp     .more
  430.  
  431.  
  432.  
  433. wait_for_data:  ; FIXME: add timeout
  434.         mcall   recv, [socketnum], receive_buffer, 4096, 0      ; MSG_DONTWAIT
  435.         cmp     eax, -1
  436.         je      err_sock
  437.         test    eax, eax
  438.         jz      err_disconnected
  439.         ret
  440.  
  441.  
  442. err_disconnected:
  443.         mov     [status], STATUS_DISCONNECTED
  444.         inc     [update_gui]
  445.         mcall   -1
  446.  
  447. err_dns:
  448.         mov     [status], STATUS_DNS_ERR
  449.         inc     [update_gui]
  450.         mcall   -1
  451.  
  452. err_sock:
  453.         mov     [status], STATUS_SOCK_ERR
  454.         inc     [update_gui]
  455.         mcall   -1
  456.  
  457. err_connect:
  458.         mov     [status], STATUS_CONNECT_ERR
  459.         inc     [update_gui]
  460.         mcall   -1
  461.         ret
  462.  
  463. err_proto:
  464.         mov     [status], STATUS_PROTO_ERR
  465.         inc     [update_gui]
  466.         mcall   -1
  467.         ret
  468.  
  469. err_security:
  470.         mov     [status], STATUS_SECURITY_ERR
  471.         inc     [update_gui]
  472.         mcall   -1
  473.         ret
  474.  
  475. err_login:
  476.         mov     [status], STATUS_LOGIN_FAILED
  477.         inc     [update_gui]
  478.         mcall   -1
  479.         ret
  480.