Subversion Repositories Kolibri OS

Rev

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