Subversion Repositories Kolibri OS

Rev

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