private void DedicatedQueue_MessageReceived(object sender, MessageReceivedEventArgs e) { //var signatureIsValid = clientServerHandshakeComplete && SignatureIsValid(e.RawData, PublicKeystore[e.Message.ClientName].Dsa); if (e.MessageEnevelope.BasicProperties.CorrelationId != null && RpcCallWaitInfo.ContainsKey(e.MessageEnevelope.BasicProperties.CorrelationId)) { var waitInfo = RpcCallWaitInfo[e.MessageEnevelope.BasicProperties.CorrelationId]; waitInfo.ResponseMessageEnvelope = e.MessageEnevelope; //waitInfo.RawResponse = e.RawData; waitInfo.WaitHandle.Set(); } else if (e.MessageEnevelope.SignatureVerificationStatus == SignatureVerificationStatus.SignatureValid) { if (e.MessageEnevelope.Message.GetType() == typeof(ClientReannounceRequestMessage)) { Log.Information("Server requested reannouncement of clients."); var message = new ClientAnnounceMessage(PublicKeystore.ParentClientInfo); //todo: Encrypt? WriteToServerNoWait(message, false); } else if (e.MessageEnevelope.Message.GetType() == typeof(HeartbeatMessage)) { #if false if (!serverHeartbeatTimer.Enabled) { Log.Information("Server heartbeat re-established."); } serverHeartbeatTimer.Restart(); #endif } else if (e.MessageEnevelope.Message.GetType() == typeof(PublicKeyUpdate)) { var tempMessage = (PublicKeyUpdate)e.MessageEnevelope.Message; PublicKeystore.Add(tempMessage.ClientInfo); //TODO: Re-enable Log.Verbose($"Received public key '{tempMessage.ClientInfo.ECKey.GetPublicKeyHash()}' for client '{tempMessage.ClientInfo.Name}'."); } else if (e.MessageEnevelope.Message.GetType() == typeof(TrustZoneSharedKeyUpdate)) { var tempMessage = (TrustZoneSharedKeyUpdate)e.MessageEnevelope.Message; if (e.MessageEnevelope.SenderIdentityHash != this.PublicKeystore.TrustCoordinatorIdentity.IdentityHash) { throw new Exception("Trust Zone Key Update from client that is not the coordinator."); } PublicKeystore.TrustZoneSharedKeys.Add(tempMessage.SharedKey); Log.Verbose($"Received trust zone shared key"); } else { FireMessageReceivedEvent(e); } } #if false else if (clientServerHandshakeComplete) { throw new Exception(); } #endif }
/// <summary> /// Connects the server's queues to the RabbitMQ server and begins processing of messages. /// </summary> /// <param name="timeout">The maximum amount of time to wait for a successful connection. An exception occurs upon timeout.</param> /// <param name="subscriptionTags"></param> public void Connect(TimeSpan timeout, MessageTagCollection subscriptionTags) { //TODO: Add subscription of broadcast tags SetupConnections(timeout, subscriptionTags); DedicatedQueue = MessageQueue.CreateExchangeBoundMessageQueue <ReadableMessageQueue>(this, Channel, ClientName, BroadcastExchangeName, DedicatedQueueName, this.QueuesAreDurable, this.AutoDeleteQueuesOnClose); DedicatedQueue.MessageReceived += DedicatedQueue_MessageReceived; DedicatedQueue.AsynchronousException += (sender, eventArgs) => FireAsynchronousExceptionEvent(this, eventArgs); DedicatedQueue.BeginFullConsume(true); // Announce client to server ClientAnnounceMessage message = new ClientAnnounceMessage(PublicKeystore.ParentClientInfo); //TODO: Encrypt this? this.BroadcastToAllClients(message, false); //var result = this.WriteToServer(message, out response, out rawResponse, (int)timeout.TotalMilliseconds); #if false if (result.CallResult == RpcCallResult.Timeout) { throw new ConnectionException("Timeout trying to communicate with the server."); } var resultMessage = (ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message; switch (resultMessage.Response) { case AnnounceResponse.Accepted: clientServerHandshakeComplete = true; //serverName = result.ResponseMessageEnvelope.SenderName; PublicKeystore.SystemSharedKeys[resultMessage.SystemSharedKeyId] = resultMessage.SystemSharedKey; break; case AnnounceResponse.Rejected: throw new ConnectionException($"Client rejected by server with the following message: {result.ResponseMessageEnvelope.Message.MessageText}."); } //result.ResponseMessageEnvelope.ReverifySignature(PublicKeystore[result.ResponseMessageEnvelope.SenderName].Dsa); //TODO: This is where we need to determine what to do with a new unstrusted signature if (result.ResponseMessageEnvelope.SignatureVerificationStatus != SignatureVerificationStatus.SignatureValid && result.ResponseMessageEnvelope.SignatureVerificationStatus != SignatureVerificationStatus.SignatureValidButUntrusted) { throw new Exception("Bad server key."); } else { //PublicKeystore.Merge(((ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message).PublicKeystore); //TODO: Fix PublicKeystore[result.ResponseMessageEnvelope.SenderName].Iv = ((ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message).Iv; if (HeartbeatInterval > 0) { serverHeartbeatTimer.Interval = HeartbeatInterval * 2; serverHeartbeatTimer.Elapsed += ServerHeartbeatTimer_Elapsed; serverHeartbeatTimer.Start(); heartbeatSendTimer.Interval = HeartbeatInterval; heartbeatSendTimer.Elapsed += HeartbeatSendTimer_Elapsed; heartbeatSendTimer.Start(); } } #endif IsConnected = true; }