private void ConnectionEstablishedHandler(object sender, ConnectionEventArgs e) { RaiseLogEntry(new LogEventArgs("Sending HelloPacket to incoming connection " + e.ConnectionId.Highlight(HighlightType.ConnectionID), LogLevel.DEBUG)); // Create a new session for this connection Session session = new Session { SessionId = Guid.NewGuid().ToString(), ConnectionId = e.ConnectionId, Expiry = DateTime.UtcNow + TimeSpan.FromMinutes(5), Authenticated = false }; lock (sessionsLock) { // Remove any existing sessions for this connection if (sessions.ContainsKey(e.ConnectionId)) { sessions.Remove(e.ConnectionId); } // Add it to the session dictionary sessions.Add(e.ConnectionId, session); } // Construct a HelloPacket HelloPacket hello = new HelloPacket { AuthType = authType, ServerName = serverName, ServerDescription = serverDescription, SessionId = session.SessionId }; // Pack it into an Any message Any packedHello = ProtobufPacketHelper.Pack(hello); // Try send it if (!netServer.TrySend(e.ConnectionId, MODULE_NAME, packedHello.ToByteArray())) { RaiseLogEntry(new LogEventArgs("Failed to send HelloPacket to connection " + e.ConnectionId.Highlight(HighlightType.ConnectionID), LogLevel.ERROR)); } }
/// <summary> /// Handler for incoming <see cref="HelloPacket"/>s. /// Responds with an <see cref="AuthenticatePacket"/>, requesting new credentials if necessary. /// </summary> /// <param name="connectionId">Original connection ID</param> /// <param name="packet">Incoming <see cref="HelloPacket"/></param> private void helloPacketHandler(string connectionId, HelloPacket packet) { // Nullify authenticated state Authenticated = false; SessionId = null; // Try to get an existing credential for this server and ensure it corresponds to the server's accepted authentication type // TODO: Use something better than server name that is unique to each (username problems all over again) if (!TryGetCredential(packet.ServerName, out Credential credential) || credential.AuthType != packet.AuthType) { RaiseLogEntry(new LogEventArgs(string.Format("No existing credential found for {0} auth type", packet.AuthType), LogLevel.DEBUG)); // Exception for client key authentication, it should be a 'zero-configuration' solution if (packet.AuthType == AuthTypes.ClientKey) { RaiseLogEntry(new LogEventArgs("Creating new ClientKey credential", LogLevel.DEBUG)); lock (credentialStore) { credential = new Credential { AuthType = AuthTypes.ClientKey, Username = credentialStore.ClientKey, Password = "" }; } } else { RaiseLogEntry(new LogEventArgs("Requesting credentials from user...", LogLevel.DEBUG)); // Request for credentials getCredentials( packet.SessionId, packet.ServerName, packet.ServerDescription, packet.AuthType, (credentialsProvided, sessionId, authType, username, password) => { if (credentialsProvided) { // Create a new credential and save it credential = new Credential { AuthType = authType, Username = username, Password = password }; AddOrUpdateCredential(packet.ServerName, credential); // Send an AuthenticatePacket as a response sendAuthenticatePacket(sessionId, credential); } else { // Close the connection netClient.Disconnect(); } } ); // Stop here as we don't have any credentials to send yet. // The connection can remain open so that the callback can send credentials when it gets them. return; } } // Send an AuthenticatePacket as a response sendAuthenticatePacket(packet.SessionId, credential); }