示例#1
0
        private void Connection()
        {
            // Connect and determine version of server, and set client protocol version to match
            try
            {
                rfb.Connect(host, port);
                rfb.ReadProtocolVersion();
                rfb.WriteProtocolVersion();

                // Figure out which type of authentication the server uses
                byte[] types = rfb.ReadSecurityTypes();

                // Based on what the server sends back in the way of supported Security Types, one of
                // two things will need to be done: either the server will reject the connection (i.e., type = 0),
                // or a list of supported types will be sent, of which we need to choose and use one.
                if (types.Length > 0)
                {
                    if (types[0] == 0)
                    {
                        // The server is not able (or willing) to accept the connection.
                        // A message follows indicating why the connection was dropped.
                        throw new VncProtocolException("Connection Failed. The server rejected the connection for the following reason: " + rfb.ReadSecurityFailureReason());
                    }
                    else
                    {
                        securityType = GetSupportedSecurityType(types);
                        System.Diagnostics.Debug.Assert(securityType > 0, "Unknown Security Type(s)", "The server sent one or more unknown Security Types.");

                        rfb.WriteSecurityType(securityType);

                        // Protocol 3.8 states that a SecurityResult is still sent when using NONE (see 6.2.1)
                        if (rfb.ServerVersion == 3.8f && securityType == 1)
                        {
                            if (rfb.ReadSecurityResult() > 0)
                            {
                                // For some reason, the server is not accepting the connection.  Get the
                                // reason and throw an exception
                                throw new VncProtocolException("Unable to Connecto to the Server. The Server rejected the connection for the following reason: " + rfb.ReadSecurityFailureReason());
                            }
                        }

                        onConnection(null, (securityType > 1) ? true : false);
                    }
                }
                else
                {
                    onConnection(new VncProtocolException("Protocol Error Connecting to Server. The Server didn't send any Security Types during the initial handshake."), false);
                }
            }
            catch (Exception e)
            {
                onConnection(new VncProtocolException("Unable to connect to the server. Error was: " + e.Message, e), false);
            }
        }
        // vnc client handling - main thread
        private void RunNetThread()
        {
            while (!terminate)
            {
                if (autoconnect && host != "")
                {
                    try
                    {
                        sleeptime = 0;
                        Log.Info("Connecting to \"" + host + ":" + port + "\"...");
                        rfb = new RfbProtocol();
                        rfb.Connect(host, (int)port);
                        Log.Debug("Connected.");
                        rfb.ReadProtocolVersion();

                        // Handle possible repeater connection
                        if (rfb.ServerVersion == 0.0)
                        {
                            rfb.WriteProxyAddress();
                            // Now we are connected to the real server; read the protocol version of the
                            // server
                            rfb.ReadProtocolVersion();
                            // Resume normal handshake and protocol
                        }

                        rfb.WriteProtocolVersion();
                        Log.Debug("Protocol Version:" + rfb.ServerVersion);

                        // Figure out which type of authentication the server uses
                        byte[] types = rfb.ReadSecurityTypes();

                        // Based on what the server sends back in the way of supported Security Types, one of
                        // two things will need to be done: either the server will reject the connection (i.e., type = 0),
                        // or a list of supported types will be sent, of which we need to choose and use one.
                        if (types.Length > 0)
                        {
                            if (types[0] == 0)
                            {
                                // The server is not able (or willing) to accept the connection.
                                // A message follows indicating why the connection was dropped.
                                throw new Exception("Connection Failed. The server rejected the connection for the following reason: " + rfb.ReadSecurityFailureReason());
                            }
                            else
                            {
                                byte securityType = GetSupportedSecurityType(types);
                                if (securityType == 0)
                                {
                                    throw new Exception("Unknown Security Type(s), The server sent one or more unknown Security Types.");
                                }

                                rfb.WriteSecurityType(securityType);

                                // Protocol 3.8 states that a SecurityResult is still sent when using NONE (see 6.2.1)
                                if (rfb.ServerVersion >= 3.799f && rfb.ServerVersion <= 3.801 && securityType == 1)
                                {
                                    if (rfb.ReadSecurityResult() > 0)
                                    {
                                        // For some reason, the server is not accepting the connection.  Get the
                                        // reason and throw an exception
                                        throw new Exception("Unable to Connect to the Server. The Server rejected the connection for the following reason: " + rfb.ReadSecurityFailureReason());
                                    }
                                }

                                if (securityType > 1)
                                {
                                    byte[] challenge = rfb.ReadSecurityChallenge();
                                    rfb.WriteSecurityResponse(EncryptChallenge(pass, challenge));
                                    if (rfb.ReadSecurityResult() != 0)
                                    {
                                        // Authentication failed, and if the server is using Protocol version 3.8, a
                                        // plain text message follows indicating why the error happend.  I'm not
                                        // currently using this message, but it is read here to clean out the stream.
                                        // In earlier versions of the protocol, the server will just drop the connection.
                                        autoconnect = false;
                                        if (rfb.ServerVersion == 3.8)
                                        {
                                            throw new Exception("The server denyes the authentication. Reason: \"" + rfb.ReadSecurityFailureReason() + "\"");
                                        }
                                        throw new Exception("The server denyes the authentication.");
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Something is wrong, since we should have gotten at least 1 Security Type
                            throw new Exception("Protocol Error Connecting to Server. The Server didn't send any Security Types during the initial handshake.");
                        }

                        // Finish initializing protocol with host
                        rfb.WriteClientInitialisation(shared);
                        buffer = rfb.ReadServerInit();
                        rfb.WriteSetPixelFormat(buffer);        // just use the server's framebuffer format

                        if (hideRemoteCursor)
                        {
                            rfb.WriteSetEncodings(new int[]
                            {
                                RfbProtocol.ZRLE_ENCODING,
                                RfbProtocol.HEXTILE_ENCODING,
                                RfbProtocol.RRE_ENCODING,
                                RfbProtocol.COPYRECT_ENCODING,
                                RfbProtocol.RAW_ENCODING,
                                RfbProtocol.CURSOR_PSEUDO_ENCODING
                            });
                        }
                        else
                        {
                            rfb.WriteSetEncodings(new int[]
                            {
                                RfbProtocol.ZRLE_ENCODING,
                                RfbProtocol.HEXTILE_ENCODING,
                                RfbProtocol.RRE_ENCODING,
                                RfbProtocol.COPYRECT_ENCODING,
                                RfbProtocol.RAW_ENCODING
                            });
                        }

                        // Create an EncodedRectangleFactory so that EncodedRectangles can be built according to set pixel layout
                        factory = new EncodedRectangleFactory(rfb, buffer);
                        // Get the initial destkop from the host

                        rfb.WriteFramebufferUpdateRequest(0, 0, (ushort)buffer.Width, (ushort)buffer.Height, false);

                        while (!terminate && autoconnect)
                        {
                            switch (rfb.ReadServerMessageType())
                            {
                            case RfbProtocol.FRAMEBUFFER_UPDATE:
                                int rectangles = rfb.ReadFramebufferUpdate();

                                for (int i = 0; i < rectangles; ++i)
                                {
                                    // Get the update rectangle's info
                                    Rectangle rectangle;
                                    int       enc;
                                    rfb.ReadFramebufferUpdateRectHeader(out rectangle, out enc);

                                    // Build a derived EncodedRectangle type and pull-down all the pixel info
                                    EncodedRectangle er = factory.Build(rectangle, enc);

                                    er.Decode();
                                    er.Draw();
                                }
                                break;

                            case RfbProtocol.BELL:
                                Log.Debug("Bell");
                                break;

                            case RfbProtocol.SERVER_CUT_TEXT:
                                rfb.ReadServerCutText();
                                Log.Debug("server-cut-text");
                                break;

                            case RfbProtocol.SET_COLOUR_MAP_ENTRIES:
                                Log.Debug("SET_COLOUR_MAP_ENTRIES");
                                rfb.ReadColourMapEntry();
                                break;

                            default:
                                throw new Exception("Unknown messagetype.");
                            }
                            invalid = true;
                            rfb.WriteFramebufferUpdateRequest(0, 0, (ushort)buffer.Width, (ushort)buffer.Height, true);
                        }
                    }
                    catch (SocketException)
                    {
                        Log.Info("Unable to connect to the server. Retry in 60s.");
                        sleeptime = 60000;
                    }
                    catch (IOException e)
                    {
                        Log.Debug("Exception in NetThread(" + e.GetType().ToString() + "): " + e.Message);
                    }
                    catch (Exception e)
                    {
                        Log.Error("Exception in NetThread(" + e.GetType().ToString() + "): " + e.Message);
                        sleeptime = 10000;
                    }
                    try
                    {
                        rfb.Close();
                    }
                    catch (Exception) {}
                    rfb     = null;
                    buffer  = null;
                    factory = null;
                    invalid = true;
                    Thread.Sleep(sleeptime);
                }
            }
        }