protected async override Task processMessageAsync(NewValidMessageEventArgs args) { AbstractMessage msg = args.MESSAGE; if (state == RecourceBindingState.BOUND || state == RecourceBindingState.ERROR || msg.isProcessed()) { return; } switch (state) { case RecourceBindingState.UNBOUND: if (msg is StreamFeaturesMessage || msg is OpenStreamAnswerMessage) { StreamFeaturesMessage features; if (msg is OpenStreamAnswerMessage) { features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage(); } else { features = msg as StreamFeaturesMessage; } if (features is null) { return; } if (features.containsFeature("bind")) { setMessageProcessed(args); BindResourceMessage bindMsg = new BindResourceMessage(XMPP_CONNECTION.account.user.resourcePart); id = bindMsg.ID; await XMPP_CONNECTION.SendAsync(bindMsg, true); state = RecourceBindingState.BINDING; } } break; case RecourceBindingState.BINDING: if (msg is IQMessage) { IQMessage iQM = msg as IQMessage; if (string.Equals(iQM.ID, id)) { stopListeningForMessages(); setMessageProcessed(args); XMPP_CONNECTION.SendAsync(new StartSessionMessage(), true).Wait(); state = RecourceBindingState.BOUND; ResourceBound?.Invoke(this, new EventArgs()); } } break; } }
protected async override Task processMessageAsync(NewValidMessageEventArgs args) { AbstractMessage msg = args.MESSAGE; if (msg.isProcessed()) { return; } switch (state) { case SASLState.DISCONNECTED: if (msg is StreamFeaturesMessage || msg is OpenStreamAnswerMessage) { StreamFeaturesMessage features = null; if (msg is OpenStreamAnswerMessage) { features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage(); } else { features = msg as StreamFeaturesMessage; } if (features is null) { return; } ArrayList mechanisms = getMechanisms(features); if (mechanisms is null) { return; } setMessageProcessed(args); selectMechanism(mechanisms); if (selectedMechanism is null) { state = SASLState.ERROR; await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "selectedMechanism is null"), true); return; } await XMPP_CONNECTION.SendAsync(selectedMechanism.getSelectSASLMechanismMessage(), true); state = SASLState.REQUESTED; } break; case SASLState.REQUESTED: case SASLState.CHALLENGING: if (msg is ScramSHAChallengeMessage) { state = SASLState.CHALLENGING; setMessageProcessed(args); AbstractMessage response = selectedMechanism.generateResponse(msg); if (!(response is null)) { await XMPP_CONNECTION.SendAsync(response, true); } } else if (msg is SASLSuccessMessage) { state = SASLState.CONNECTED; msg.setRestartConnection(AbstractMessage.SOFT_RESTART); setMessageProcessed(args); stopListeningForMessages(); } else if (msg is SASLFailureMessage) { stopListeningForMessages(); SASLFailureMessage saslFailureMessage = msg as SASLFailureMessage; state = SASLState.ERROR; Logger.Error("Error during SASL authentication: " + saslFailureMessage.ERROR_TYPE + "\n" + saslFailureMessage.ERROR_MESSAGE); if (saslFailureMessage.ERROR_TYPE == SASLErrorType.UNKNOWN_ERROR) { await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "SASL: " + saslFailureMessage.ERROR_MESSAGE), true); } else { await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "SASL: " + saslFailureMessage.ERROR_TYPE), true); } } break; case SASLState.CONNECTED: break; default: throw new InvalidOperationException("Unexpected value for state: " + state); } }
protected async override Task processMessageAsync(NewValidMessageEventArgs args) { AbstractMessage msg = args.MESSAGE; if (msg.isProcessed()) { return; } if ((state == TLSState.CONNECTING || state == TLSState.REQUESTED) && msg is ErrorMessage) { setMessageProcessed(args); setState(TLSState.ERROR); ErrorMessage error = msg as ErrorMessage; if (error.getType().Equals(Consts.XML_FAILURE)) { error.setRestartConnection(AbstractMessage.HARD_RESTART); } return; } switch (state) { case TLSState.DISCONNECTED: case TLSState.CONNECTING: if (msg is OpenStreamAnswerMessage) { StreamFeaturesMessage features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage(); if (features != null) { await streamFeaturesMessageReceivedAsync(features, args); } } else if (msg is StreamFeaturesMessage) { await streamFeaturesMessageReceivedAsync(msg as StreamFeaturesMessage, args); } break; case TLSState.REQUESTED: if (msg is ProceedAnswerMessage) { setMessageProcessed(args); XMPPAccount account = XMPP_CONNECTION.account; Logger.Debug("Upgrading " + account.getBareJid() + " connection to TLS..."); try { TCP_CONNECTION.upgradeToTLSAsync().Wait(); } catch (AggregateException e) { if (e.InnerException is TaskCanceledException) { Logger.Error("Timeout during upgrading " + account.getBareJid() + " to TLS!", e); setState(TLSState.ERROR); await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, "TSL upgrading timeout!"), true); return; } else { Logger.Error("Error during upgrading " + account.getBareJid() + " to TLS!", e.InnerException); setState(TLSState.ERROR); await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, e.InnerException?.Message), true); return; } } catch (Exception e) { Logger.Error("Error during upgrading " + account.getBareJid() + " to TLS!", e); setState(TLSState.ERROR); await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, e.Message), true); return; } Logger.Debug("Success upgrading " + account.getBareJid() + " to TLS."); setState(TLSState.CONNECTED); stopListeningForMessages(); // TLS established ==> resend stream header msg.setRestartConnection(AbstractMessage.SOFT_RESTART); } break; } }