public IServerState Process() { stream.WriteByte(Node.ProtocolVersion); var serverHandshake = new ServerHandshake(); serverHandshake.NodeId = app.Node.Id; Serializer.SerializeWithLengthPrefix(stream, serverHandshake, PrefixStyle.Base128); var handshake = Serializer.DeserializeWithLengthPrefix<ClientHandshake>(stream, PrefixStyle.Base128); if (handshake.GetObjectRequest != null && handshake.StoreObjectRequest != null) { this.Warn("Ignoring TCP request from {0} containing multiple requests", client.Client.RemoteEndPoint); return null; } if (handshake.GetObjectRequest == null && handshake.StoreObjectRequest == null) { this.Warn("Ignoring TCP request from {0} containing no requests", client.Client.RemoteEndPoint); return null; } var clientAddress = ((IPEndPoint) client.Client.RemoteEndPoint).Address; app.Node.Kademlia.AddVerifiedNode(new IPEndPoint(clientAddress, handshake.Port), handshake.NodeId); if (handshake.GetObjectRequest != null) { return new GetObjectState(stream, app, handshake.GetObjectRequest); } return new StoreObjectState(stream, app, handshake.StoreObjectRequest); }
private bool ReadHandshake() { var hs = new byte[1024]; int count = Socket.Receive(hs); var bytes = new ArraySegment <byte>(hs, 0, count); ServerHandshake handshake = null; if (bytes.Count > 0) { handshake = ParseServerHandshake(bytes); } var isValid = (handshake != null) && (handshake.Origin == Handshake.Origin) && (handshake.Location == "ws://" + Handshake.Host + Handshake.ResourcePath); if (isValid) { for (int i = 0; i < 16; i++) { if (handshake.AnswerBytes[i] != Handshake.ExpectedAnswer[i]) { isValid = false; break; } } } return(isValid); }
private void Receive(object sender, MessageEventArgs e) { PacketChecker packet = JsonUtility.FromJson <PacketChecker>(e.Data); if (packet == null) { return; } if (packet.packetType == null) { return; } switch (packet.packetType) { case (int)GameServerPackets.Handshake: ServerHandshake shake = JsonUtility.FromJson <ServerHandshake>(e.Data); Debug.Log(shake.welcomeMessage); break; case (int)GameServerPackets.GetLobbyCode: CreateLobby lobby = JsonUtility.FromJson <CreateLobby>(e.Data); info.currentGame = lobby.lobbyCode; actionsToRun.Add(() => SceneManager.LoadScene(joinScene)); break; case (int)GameServerPackets.ErrorMessage: Disconnect(); Application.Quit(); break; } }
public void FindsKeysFromMessage(string message) { ServerHandshake.GetKey(message, actualyKey); for (int i = 0; i < ServerHandshake.KeyLength; i++) { if (expectedKey[i] != actualyKey[i]) { Assert.Fail($"Keys did not match."); } } }
private ServerHandshake ParseServerHandshake(ArraySegment <byte> byteShake) { // the "grammar" of the handshake var pattern = @"^HTTP\/1\.1 101 Web Socket Protocol Handshake\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]+)\r\n)+"; // unordered set of fields (name-chars colon space any-chars cr lf) // subtract the challenge bytes from the handshake var handshake = new ServerHandshake(); ArraySegment <byte> challenge = new ArraySegment <byte>(byteShake.Array, byteShake.Count - 16, 16); handshake.AnswerBytes = new byte[16]; //challenge.Array; Array.Copy(challenge.Array, challenge.Offset, handshake.AnswerBytes, 0, 16); // get the rest of the handshake var utf8_handshake = Encoding.UTF8.GetString(byteShake.Array, 0, byteShake.Count - 16); // match the handshake against the "grammar" var regex = new Regex(pattern, RegexOptions.IgnoreCase); var match = regex.Match(utf8_handshake); var fields = match.Groups; // run through every match and save them in the handshake object for (int i = 0; i < fields["field_name"].Captures.Count; i++) { var name = fields["field_name"].Captures[i].ToString(); var value = fields["field_value"].Captures[i].ToString(); switch (name.ToLower()) { case "sec-websocket-origin": handshake.Origin = value; break; case "sec-websocket-location": handshake.Location = value; break; case "sec-websocket-protocol": handshake.SubProtocol = value; break; } } return(handshake); }
public void ClientConnecting(IncomingMessageBuffer buffer) { ClientConnect message = new ClientConnect(); message.Parse(buffer); ServerHandshake handshake = new ServerHandshake(); handshake.Address = UdpReceiver.Instance.ServerEndpoint; handshake.SendPing = message.SendPing; handshake.SendPong = message.SendPing + 1000L; Frame frame = new Frame(); frame.Payload = handshake.ToByteArray(); frame.Reliability = Frame.ReliabilityStatus.UNRELIABLE; SendFrame(frame); }
public static HandshakeReturnCapsula Login(Logger logger, Stream stream, X509Certificate2 cert, string password, string userName = null, int?clientId = null) { ClientHandshake clientHandshake = new ClientHandshake() { PemCertificate = X509Certificate2Utils.ExportToPem(cert), UserName = userName, ClientId = clientId, ServerPassword = password }; if (userName != null && userName.Length > DataConstants.USER_NAME_MAX_LENGHT) { throw new Exception("Username is too long."); } TextEncoder.SendJson(stream, clientHandshake); byte[] encrypted = BinaryEncoder.ReceiveBytes(stream); byte[] decrypted = RSAEncoder.Decrypt(encrypted, cert); BinaryEncoder.SendBytes(stream, decrypted); ServerHandshake serverHandshake = TextEncoder.ReadJson <ServerHandshake>(stream); logger.Log("Handshake", "Handshake", serverHandshake.Errors, false); if (!serverHandshake.Succeeded) { throw new Exception($"Handshake failed\n{serverHandshake.Errors}"); } return(new HandshakeReturnCapsula() { UserId = serverHandshake.UserId, UserName = serverHandshake.UserName, ClientId = serverHandshake.ClientId, SelfAesPassword = serverHandshake.SelfAesKey == null ? null : new AESPassword(RSAEncoder.DecryptAndVerify(serverHandshake.SelfAesKey, cert, cert)) }); }
private bool CheckAuthenticationResponse(Context context) { var receivedData = context.UserContext.DataFrame.ToString(); var header = new Header(receivedData); var handshake = new ServerHandshake(header); if (Authentication.GenerateAccept(_handshake.Key) != handshake.Accept) { return(false); } if (SubProtocols != null) { if (header.SubProtocols == null) { return(false); } foreach (var s in SubProtocols) { if (header.SubProtocols.Contains(s) && String.IsNullOrEmpty(CurrentProtocol)) { CurrentProtocol = s; } } if (String.IsNullOrEmpty(CurrentProtocol)) { return(false); } } ReadyState = ReadyStates.OPEN; IsAuthenticated = true; _connecting = false; context.UserContext.OnConnected(); return(true); }
public static ConnectionInfo Run(Stream stream, Action <string> log, ServerConfig config) { ClientHandshake clientHandshake = TextEncoder.ReadJson <ClientHandshake>(stream); X509Certificate2 clientCertificate = X509Certificate2Utils.ImportFromPem(clientHandshake.PemCertificate); log($"Logging user sent username {clientHandshake.UserName}\n Certificate:\n {clientHandshake.PemCertificate}"); ServerHandshake errorHandshake = new ServerHandshake() { Errors = "", NewUser = false, Succeeded = false, UserId = -1, UserName = "" }; if (config.Password != null && !config.Password.Equals(clientHandshake.ServerPassword)) { errorHandshake.Errors = "Server password is wrong."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Generating random bytes"); byte[] randomBytes = LUtils.GenerateRandomBytes(TcpConstants.HANDSHAKE_LENGHT); log("Sending encrypted bytes"); BinaryEncoder.SendBytes(stream, RSAEncoder.Encrypt(randomBytes, clientCertificate)); byte[] received = BinaryEncoder.ReceiveBytes(stream); if (!randomBytes.SequenceEqual(received)) { log("Client's certificate verification failed."); errorHandshake.Errors = "Client's certificate verification failed."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Certificate verification succeeded."); Users user; String message; Clients client; byte[] aesKey = null; bool newUser = false; using (Context context = new Context(config)) { byte[] hash = SHA256Utils.ComputeByteSha256Hash(clientCertificate); user = context.Users.SingleOrDefault(u => u.PublicCertificateSha256.SequenceEqual(hash)); if (user == null) { log("User doesn't exist yet. I'll try to create him."); newUser = true; log("Checking the uniquity of username."); String userName = clientHandshake.UserName; if (context.Users.SingleOrDefault(u => u.UserName.Equals(userName)) != null) { errorHandshake.Errors = "Username isn't unique."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (userName.Length > 45) { errorHandshake.Errors = "Username is too long (max. 45 chars)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (userName.Length < 4) { errorHandshake.Errors = "Username is too short (min. 4 chars)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (!Validators.ValidateRegexUserName(userName)) { errorHandshake.Errors = "Username must match this regex ^[a-zA-Z][-a-zA-Z0-9_]+$ (Vaguely can't contain special chars and spaces)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Creating user."); user = new Users() { PublicCertificate = clientHandshake.PemCertificate, PublicCertificateSha256 = hash, UserName = clientHandshake.UserName }; context.Users.Add(user); context.SaveChanges(); message = "User successfully created."; log("User successfully created."); } else { message = "User exists."; log("User exists."); } client = new Clients() { UserId = user.Id }; if (clientHandshake.ClientId == null) { log($"Loading self-aes key."); aesKey = context.UsersKeys .Where(u => u.RecepientId == user.Id) .Where(u => u.SenderId == user.Id) .Select(u => u.AesKey) .SingleOrDefault(); context.Add(client); context.SaveChanges(); log($"Added client with Id {client.Id}."); } else { client.Id = (int)clientHandshake.ClientId; if (context.Clients.Where(u => u.Id == client.Id).Single().UserId != user.Id) { errorHandshake.Errors = "This client id isn't owned by this user."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log($"Client with Id {client.Id} has logged in."); } } ServerHandshake toSend = new ServerHandshake() { Errors = message, NewUser = newUser, Succeeded = true, UserId = user.Id, UserName = user.UserName, ClientId = client.Id, SelfAesKey = aesKey }; TextEncoder.SendJson(stream, toSend); ConnectionInfo ret = new ConnectionInfo(user, clientCertificate, client.Id); log($"Handshake successeded. User {ret.UserName} with id {ret.UserId} has logged in. Client has id {client.Id}."); return(ret); }
private ServerHandshake ParseServerHandshake(ArraySegment<byte> byteShake) { // the "grammar" of the handshake var pattern = @"^HTTP\/1\.1 101 Web Socket Protocol Handshake\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]+)\r\n)+"; // unordered set of fields (name-chars colon space any-chars cr lf) // subtract the challenge bytes from the handshake var handshake = new ServerHandshake(); ArraySegment<byte> challenge = new ArraySegment<byte>(byteShake.Array, byteShake.Count - 16, 16); handshake.AnswerBytes = new byte[16]; //challenge.Array; Array.Copy(challenge.Array, challenge.Offset, handshake.AnswerBytes, 0, 16); // get the rest of the handshake var utf8_handshake = Encoding.UTF8.GetString(byteShake.Array, 0, byteShake.Count - 16); // match the handshake against the "grammar" var regex = new Regex(pattern, RegexOptions.IgnoreCase); var match = regex.Match(utf8_handshake); var fields = match.Groups; // run through every match and save them in the handshake object for (int i = 0; i < fields["field_name"].Captures.Count; i++) { var name = fields["field_name"].Captures[i].ToString(); var value = fields["field_value"].Captures[i].ToString(); switch (name.ToLower()) { case "sec-websocket-origin": handshake.Origin = value; break; case "sec-websocket-location": handshake.Location = value; break; case "sec-websocket-protocol": handshake.SubProtocol = value; break; } } return handshake; }
public static UserCapsula Run(Stream stream, Action <string> log, ServerConfig config) { ClientHandshake clientHandshake = TextEncoder.ReadClientHandshake(stream); X509Certificate2 clientCertificate = X509Certificate2Utils.ImportFromPem(clientHandshake.PemCertificate); log($"Logging user sent username {clientHandshake.UserName}\n Certificate:\n {clientHandshake.PemCertificate}"); log("Generating random bytes"); byte[] randomBytes = LUtils.GenerateRandomBytes(TcpConstants.HANDSHAKE_LENGHT); log("Sending encrypted bytes"); BinaryEncoder.SendBytes(stream, RSAEncoder.Encrypt(randomBytes, clientCertificate)); ServerHandshake errorHandshake = new ServerHandshake() { Errors = "", NewUser = false, Succeeded = false, UserId = -1, UserName = "" }; byte[] received = BinaryEncoder.ReceiveBytes(stream); if (!randomBytes.SequenceEqual(received)) { log("Sending error to client."); errorHandshake.Errors = "Client's certificate verification failed."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Certificate verification succeeded."); Users user; String message; Clients client; bool newUser = false; using (Context context = new Context(config)) { SHA1 sha = new SHA1CryptoServiceProvider(); byte[] hash = sha.ComputeHash(clientCertificate.RawData); user = context.Users.SingleOrDefault(u => u.PublicCertificateSha1.SequenceEqual(hash)); if (user == null) { log("User doesn't exist yet. I'll try to create him."); newUser = true; log("Checking the uniquity of username."); String userName = clientHandshake.UserName; if (context.Users.SingleOrDefault(u => u.UserName.Equals(userName)) != null) { log("Username isn't unique."); errorHandshake.Errors = "Username isn't unique."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Creating user."); user = new Users() { PublicCertificate = clientHandshake.PemCertificate, PublicCertificateSha1 = hash, UserName = clientHandshake.UserName }; context.Users.Add(user); context.SaveChanges(); message = "User successfully created."; log("User successfully created."); } else { message = "User exists."; log("User exists."); } client = new Clients() { UserId = user.Id }; if (clientHandshake.ClientId == null) { context.Add(client); context.SaveChanges(); log($"Added client with Id {client.Id}."); } else { log($"Client with Id {client.Id} has logged in."); } } ServerHandshake toSend = new ServerHandshake() { Errors = message, NewUser = newUser, Succeeded = true, UserId = user.Id, UserName = user.UserName, ClientId = client.Id }; TextEncoder.SendJson(stream, toSend); UserCapsula ret = new UserCapsula(user, clientCertificate); log($"Handshake successeded. User {ret.UserName} with id {ret.UserId} has logged in"); return(ret); }
public static ClientHandshake Handshake(ServerHandshake serverData, NetworkStream stream) { SendServerData(serverData, stream); return(GetClientData(stream)); }
public static void SendServerData(ServerHandshake serverData, NetworkStream stream) { NetworkInterop.WriteInt(stream, serverData.clientNumber); }