Versionr.Network.Client.Connect C# (CSharp) Method

Connect() public method

public Connect ( string host, int port, string module, bool requirewrite = false ) : bool
host string
port int
module string
requirewrite bool
return bool
        public bool Connect(string host, int port, string module, bool requirewrite = false)
        {
            if (port == -1)
                port = VersionrDefaultPort;
            IEnumerator<SharedNetwork.Protocol> protocols = SharedNetwork.AllowedProtocols.Cast<SharedNetwork.Protocol>().GetEnumerator();
            Retry:
            if (!protocols.MoveNext())
            {
                Printer.PrintMessage("#e#No valid protocols available.##");
                return false;
            }
            Host = host;
            Port = port;
            Module = module;
            Connected = false;
            try
            {
                Connection = new System.Net.Sockets.TcpClient();
                var connectionTask = Connection.ConnectAsync(Host, Port);
                if (!connectionTask.Wait(5000))
                {
                    throw new Exception(string.Format("Couldn't connect to target: {0}", this.VersionrURL));
                }
            }
            catch (Exception e)
            {
                Printer.PrintError(e.Message);
                return false;
            }
            if (Connection.Connected)
            {
                try
                {
                    Printer.PrintDiagnostics("Connected to server at {0}:{1}", host, port);
                    Handshake hs = Handshake.Create(protocols.Current);
                    hs.RequestedModule = Module;
                    Printer.PrintDiagnostics("Sending handshake...");
                    Connection.NoDelay = true;
                    ProtoBuf.Serializer.SerializeWithLengthPrefix<Handshake>(Connection.GetStream(), hs, ProtoBuf.PrefixStyle.Fixed32);

                    var startTransaction = ProtoBuf.Serializer.DeserializeWithLengthPrefix<Network.StartTransaction>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32);
                    if (startTransaction == null || !startTransaction.Accepted)
                    {
                        Printer.PrintError("#b#Server rejected connection.##");
                        if (startTransaction != null && hs.VersionrProtocol != startTransaction.ServerHandshake.VersionrProtocol)
                            Printer.PrintError("## Protocol mismatch - local: {0}, remote: {1}", hs.VersionrProtocol, startTransaction.ServerHandshake.VersionrProtocol);
                        else
                        {
                            if (startTransaction == null)
                                Printer.PrintError("## Connection terminated unexpectedly.");
                            else
                                Printer.PrintError("## Rejected request.");
                            return false;
                        }
                        Printer.PrintError("#b#Attempting to retry with a lower protocol.##");
                        goto Retry;
                    }
                    Printer.PrintDiagnostics("Server domain: {0}", startTransaction.Domain);
                    if (Workspace != null && !string.IsNullOrEmpty(startTransaction.Domain) && startTransaction.Domain != Workspace.Domain.ToString())
                    {
                        Printer.PrintError("Server domain doesn't match client domain. Disconnecting.");
                        return false;
                    }

                    RemoteDomain = startTransaction.Domain;

                    if (SharedNetwork.SupportsAuthentication(startTransaction.ServerHandshake.CheckProtocol().Value))
                    {
                        var command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32);
                        if (command.Type == NetCommandType.Authenticate)
                        {
                            bool runauth = true;
                            var challenge = ProtoBuf.Serializer.DeserializeWithLengthPrefix<AuthenticationChallenge>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32);
                            if ((!requirewrite && (command.Identifier & 1) != 0) ||
                                (requirewrite && (command.Identifier & 2) != 0)) // server supports unauthenticated access
                            {
                                AuthenticationResponse response = new AuthenticationResponse()
                                {
                                    IdentifierToken = string.Empty,
                                    Mode = AuthenticationMode.Guest
                                };
                                ProtoBuf.Serializer.SerializeWithLengthPrefix(Connection.GetStream(), response, ProtoBuf.PrefixStyle.Fixed32);
                                command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32);
                                if (command.Type == NetCommandType.Acknowledge)
                                    runauth = false;
                            }
                            if (runauth)
                            {
                                bool q = Printer.Quiet;
                                Printer.Quiet = false;
                                Printer.PrintMessage("Server at #b#{0}## requires authentication.", VersionrURL);
                                while (true)
                                {
                                    if (challenge.AvailableModes.Contains(AuthenticationMode.Simple))
                                    {
                                        System.Console.CursorVisible = true;
                                        Printer.PrintMessageSingleLine("#b#Username:## ");
                                        string user = System.Console.ReadLine();
                                        Printer.PrintMessageSingleLine("#b#Password:## ");
                                        string pass = GetPassword();
                                        System.Console.CursorVisible = false;

                                        user = user.Trim(new char[] { '\r', '\n', ' ' });

                                        AuthenticationResponse response = new AuthenticationResponse()
                                        {
                                            IdentifierToken = user,
                                            Mode = AuthenticationMode.Simple,
                                            Payload = System.Text.ASCIIEncoding.ASCII.GetBytes(BCrypt.Net.BCrypt.HashPassword(pass, challenge.Salt))
                                        };
                                        Printer.PrintMessage("\n");
                                        ProtoBuf.Serializer.SerializeWithLengthPrefix(Connection.GetStream(), response, ProtoBuf.PrefixStyle.Fixed32);
                                        command = ProtoBuf.Serializer.DeserializeWithLengthPrefix<NetCommand>(Connection.GetStream(), ProtoBuf.PrefixStyle.Fixed32);
                                        if (command.Type == NetCommandType.AuthRetry)
                                            Printer.PrintError("#e#Authentication failed.## Retry.");
                                        if (command.Type == NetCommandType.AuthFail)
                                        {
                                            Printer.PrintError("#e#Authentication failed.##");
                                            return false;
                                        }
                                        if (command.Type == NetCommandType.Acknowledge)
                                            break;
                                    }
                                    else
                                    {
                                        Printer.PrintError("Unsupported authentication requirements!");
                                        return false;
                                    }
                                }
                                Printer.Quiet = q;
                            }
                        }
                    }
                    if (startTransaction.Encrypted)
                    {
                        var key = startTransaction.RSAKey;
                        Printer.PrintDiagnostics("Server RSA Key: {0}", key.Fingerprint());

                        var publicKey = new System.Security.Cryptography.RSACryptoServiceProvider();
                        publicKey.ImportParameters(key);

                        Printer.PrintDiagnostics("Generating secret key for data channel...");
                        System.Security.Cryptography.RSAOAEPKeyExchangeFormatter exch = new System.Security.Cryptography.RSAOAEPKeyExchangeFormatter(publicKey);

                        System.Security.Cryptography.AesManaged aesProvider = new System.Security.Cryptography.AesManaged();
                        aesProvider.KeySize = 256;
                        aesProvider.GenerateIV();
                        aesProvider.GenerateKey();

                        AESProvider = aesProvider;
                        AESKey = aesProvider.Key;
                        AESIV = aesProvider.IV;

                        Printer.PrintDiagnostics("Key: {0}", System.Convert.ToBase64String(aesProvider.Key));
                        var keyExchangeObject = new Network.StartClientTransaction() { Key = exch.CreateKeyExchange(aesProvider.Key), IV = exch.CreateKeyExchange(aesProvider.IV) };

                        ProtoBuf.Serializer.SerializeWithLengthPrefix<StartClientTransaction>(Connection.GetStream(), keyExchangeObject, ProtoBuf.PrefixStyle.Fixed32);
                        Connection.GetStream().Flush();
                        Connected = true;
                        SharedNetwork.SharedNetworkInfo sharedInfo = new SharedNetwork.SharedNetworkInfo()
                        {
                            DecryptorFunction = () => { return Decryptor; },
                            EncryptorFunction = () => { return Encryptor; },
                            Stream = Connection.GetStream(),
                            Workspace = Workspace,
                            Client = true,
                            CommunicationProtocol = protocols.Current
                        };

                        SharedInfo = sharedInfo;
                    }
                    else
                    {
                        Printer.PrintDiagnostics("Using cleartext communication");
                        var keyExchangeObject = new Network.StartClientTransaction();
                        ProtoBuf.Serializer.SerializeWithLengthPrefix<StartClientTransaction>(Connection.GetStream(), keyExchangeObject, ProtoBuf.PrefixStyle.Fixed32);
                        Connection.GetStream().Flush();
                        Connected = true;
                        SharedNetwork.SharedNetworkInfo sharedInfo = new SharedNetwork.SharedNetworkInfo()
                        {
                            DecryptorFunction = null,
                            EncryptorFunction = null,
                            Stream = Connection.GetStream(),
                            Workspace = Workspace,
                            Client = true,
                            CommunicationProtocol = protocols.Current
                        };
                        SharedInfo = sharedInfo;
                    }
                    return true;
                }
                catch (Exception e)
                {
                    Printer.PrintError("Error encountered: {0}", e);
                    return false;
                }
            }
            else
                return false;
        }

Usage Example

Exemplo n.º 1
0
        public AreaVM(string path, string name, AreaInitMode areaInitMode, string host = null, int port = 0)
        {
            RefreshCommand = new DelegateCommand(Refresh);
            PullCommand = new DelegateCommand(Pull);
            PushCommand = new DelegateCommand(Push);

            _name = name;

            DirectoryInfo dir = new DirectoryInfo(path);
            switch (areaInitMode)
            {
                case AreaInitMode.Clone:
                    // Spawn another dialog for the source (or put it in the Clone New button)
                    Client client = new Client(dir);
                    if (client.Connect(host, port, null, true))
                    {
                        bool result = client.Clone(true);
                        if (!result)
                            result = client.Clone(false);
                        if (result)
                        {
                            string remoteName = "default";
                            client.Workspace.SetRemote(client.Host, client.Port, client.Module, remoteName);
                            client.Pull(false, client.Workspace.CurrentBranch.ID.ToString());
                            _area = Area.Load(client.Workspace.Root);
                            _area.Checkout(null, false, false);
                            client.SyncRecords();
                        }
                    }
                    else
                    {
                        MessageBox.Show(string.Format("Couldn't connect to {0}:{1}", host, port), "Clone Failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    client.Close();
                    break;
                case AreaInitMode.InitNew:
                    // Tell versionr to initialize at path
                    try
                    {
                        dir.Create();
                    }
                    catch
                    {
                        MessageBox.Show("Error - couldn't create subdirectory \"{0}\"", dir.FullName);
                        break;
                    }
                    _area = Area.Init(dir, name);
                    break;
                case AreaInitMode.UseExisting:
                    // Add it to settings and refresh UI, get status etc.
                    _area = Area.Load(dir);
                    break;
            }
        }
All Usage Examples Of Versionr.Network.Client::Connect