internal void Connect(ConnectionState State) { IPAddress[] resolved = Dns.GetHostAddresses(Properties.HostIp); string DnsIp = ""; bool IsIPv6 = false; for (int i = 0; i < resolved.Length; i++) { if (resolved[i].AddressFamily == AddressFamily.InterNetwork || resolved[i].AddressFamily == AddressFamily.InterNetworkV6) { IsIPv6 = resolved[i].AddressFamily == AddressFamily.InterNetworkV6; DnsIp = resolved[i].ToString(); break; } } if (DnsIp == "") { throw new Exception("Unable to resolve \"" + Properties.HostIp + "\" by using DNS"); } int ConTimeout = Properties.ConnectionTimeout; do { this.Handle = new Socket(IsIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IAsyncResult result = this.Handle.BeginConnect(new IPEndPoint(resolved[0], Properties.Port), (IAsyncResult ar) => { try { this.Handle.EndConnect(ar); } catch (Exception ex) { /* Will throw a error if connection couldn't be made */ SysLogger.Log(ex.Message, SysLogType.Error); } }, null); Stopwatch sw = Stopwatch.StartNew(); if (ConTimeout > 0) { result.AsyncWaitHandle.WaitOne(ConTimeout); } else { result.AsyncWaitHandle.WaitOne(); } sw.Stop(); ConTimeout -= (int)sw.ElapsedMilliseconds; if (!this.Handle.Connected) this.Handle.Close(); } while (ConTimeout > 0 && !this.Handle.Connected); if (!Handle.Connected) throw new Exception("Unable to establish a connection with " + Properties.HostIp + ":" + Properties.Port); Connection = new Connection(this); Connection.StartReceiver(); onBeforeConnect(); //let's begin the handshake User user = new User(Properties.Username, Properties.Password, new List<Stream>(Properties.PrivateKeyFiles), Properties.PublicKeyFile); user.GenKey(this, SessionSide.Client, Properties.Handshake_Maze_Size, Properties.Handshake_MazeCount, Properties.Handshake_StepSize); this.clientHS = user.MazeHandshake; byte[] encryptedPublicKey = clientHS.GetEncryptedPublicKey(); byte[] byteCode = clientHS.GetByteCode(); Connection.SendMessage(new MsgHandshake(byteCode), new SystemHeader()); //send our encrypted public key Connection.SendMessage(new MsgHandshake(encryptedPublicKey), new SystemHeader()); //and now just wait for the handshake to finish... can't take longer then 60 seconds MazeErrorCode errorCode = Connection.HandshakeSync.Wait<MazeErrorCode>(MazeErrorCode.Error, 60000); if (errorCode != MazeErrorCode.Finished) { throw new Exception("Username or Password is incorrect."); } bool initOk = Connection.InitSync.Wait<bool>(false, 30000); if (!initOk) { throw new Exception("A server time-out occured"); } //re-calculate the private keys for(int i = 0; i < Properties.PrivateKeyFiles.Length; i++) { clientHS.RecalculatePrivateKey(Properties.PrivateKeyFiles[i]); } this.Username = Properties.Username; this.KeepAliveTimer = new System.Timers.Timer(); this.KeepAliveTimer.Interval = 5000; this.KeepAliveTimer.Elapsed += KeepAliveTimer_Elapsed; this.KeepAliveTimer.Enabled = true; onConnect(); }
/// <summary> /// Create a new instance of User /// </summary> /// <param name="Username">The Username for the user</param> /// <param name="Password">The Password for the user</param> /// <param name="PrivateKeys">The Private Key(s) that are being used to Encrypt the Session</param> /// <param name="PublicKey">The Public Key to indentify the user</param> public User RegisterUser(string Username, string Password, List<Stream> PrivateKeys, Stream PublicKey) { User user = new User(Username, Password, PrivateKeys, PublicKey); user.GenKey(SessionSide.Server, serverProperties.Handshake_Maze_Size, serverProperties.Handshake_MazeCount, serverProperties.Handshake_StepSize); return user; }