PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/sipsorcery-xmpp/SIPSorcery.XMPP/XMPPClient.cs

https://github.com/thecc4re/sipsorcery-mono
C# | 170 lines | 117 code | 21 blank | 32 comment | 2 complexity | a02af256e16e320d70abadaa456a660b MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //-----------------------------------------------------------------------------
  2. // Filename: XMPPClient.cs
  3. //
  4. // Description: Represents the top level abstraction that can be used to initiate
  5. // an XMPP client connection.
  6. //
  7. // History:
  8. // 13 Nov 2010 Aaron Clauson Created.
  9. //
  10. // License:
  11. // This software is licensed under the BSD License http://www.opensource.org/licenses/bsd-license.php
  12. //
  13. // Copyright (c) 2010 Aaron Clauson (aaron@sipsorcery.com), Hobart, Tasmanian, Australia (www.sipsorcery.com)
  14. // All rights reserved.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that
  17. // the following conditions are met:
  18. //
  19. // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  20. // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
  21. // disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of SIP Sorcery.
  22. // nor the names of its contributors may be used to endorse or promote products derived from this software without specific
  23. // prior written permission.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  26. // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  27. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  28. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  29. // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  30. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. // POSSIBILITY OF SUCH DAMAGE.
  32. //-----------------------------------------------------------------------------
  33. using System;
  34. using System.Collections.Generic;
  35. using System.IO;
  36. using System.Net;
  37. using System.Net.Security;
  38. using System.Net.Sockets;
  39. using System.Linq;
  40. using System.Security.Cryptography.X509Certificates;
  41. using System.Text;
  42. using System.Threading;
  43. using System.Xml.Linq;
  44. using SIPSorcery.Net;
  45. using SIPSorcery.Sys;
  46. using log4net;
  47. namespace SIPSorcery.XMPP
  48. {
  49. public class XMPPClient
  50. {
  51. public const int SSL_READWRITE_TIMEOUT = 600000;
  52. private static ILog logger = AppState.logger;
  53. public Action IsBound;
  54. public Action Disconnected;
  55. private string m_host;
  56. private int m_port;
  57. private string m_server;
  58. private string m_fromUsername;
  59. private string m_saslToken;
  60. private TcpClient m_tcpClient;
  61. private SslStream m_sslStream;
  62. private WrappedStream m_tcpWrappedStream;
  63. private WrappedStream m_sslWrappedStream;
  64. private WrappedStream m_authWrappedStream;
  65. private XMPPAuthenticatedStream m_authenticatedStream;
  66. private StreamWriter m_traceStream;
  67. public XMPPClient(string host, int port, string server, string username, string password)
  68. {
  69. m_host = host;
  70. m_port = port;
  71. m_server = server;
  72. m_fromUsername = username;
  73. m_saslToken = GetPlainSASLResponse(username, password);
  74. m_traceStream = new StreamWriter("trace.txt");
  75. }
  76. public void Connect()
  77. {
  78. try
  79. {
  80. m_tcpClient = new TcpClient(m_host, m_port);
  81. logger.Debug("XMPP client is connected to " + m_host + ":" + m_port + ".");
  82. m_tcpWrappedStream = new WrappedStream(m_tcpClient.GetStream(), m_traceStream);
  83. XMPPInitialStream initialStream = new XMPPInitialStream(m_tcpWrappedStream);
  84. initialStream.Start(m_server, null, null);
  85. m_tcpWrappedStream.BlockIO();
  86. XMPPStreamTLSRequired();
  87. m_sslWrappedStream.BlockIO();
  88. XMPPStreamAuthenticated();
  89. }
  90. catch (Exception excp)
  91. {
  92. logger.Error("Exception XMPPClient.Connect. " + excp.Message);
  93. }
  94. finally
  95. {
  96. if (Disconnected != null)
  97. {
  98. Disconnected();
  99. }
  100. }
  101. }
  102. public void SendMessage(string to, string message)
  103. {
  104. m_authenticatedStream.SendMessage(to, message);
  105. }
  106. public XMPPPhoneSession GetPhoneSession()
  107. {
  108. return new XMPPPhoneSession(m_authenticatedStream.JID, m_authenticatedStream);
  109. }
  110. private void XMPPStreamTLSRequired()
  111. {
  112. logger.Debug("XMPP client initiating TLS connection.");
  113. m_sslStream = new SslStream(m_tcpClient.GetStream(), false, ValidateServerCertificate, null);
  114. m_sslStream.ReadTimeout = SSL_READWRITE_TIMEOUT;
  115. m_sslStream.WriteTimeout = SSL_READWRITE_TIMEOUT;
  116. m_sslStream.AuthenticateAsClient(m_server);
  117. m_sslWrappedStream = new WrappedStream(m_sslStream, m_traceStream);
  118. XMPPEncryptedStream encryptedStream = new XMPPEncryptedStream(m_sslWrappedStream);
  119. encryptedStream.Start(m_server, m_saslToken, m_fromUsername);
  120. }
  121. private void XMPPStreamAuthenticated()
  122. {
  123. logger.Debug("XMPP client now authenticated as " + m_fromUsername + ", initiating binding.");
  124. m_authWrappedStream = new WrappedStream(m_sslStream, m_traceStream);
  125. m_authenticatedStream = new XMPPAuthenticatedStream(m_authWrappedStream);
  126. m_authenticatedStream.IsBound = IsBound;
  127. m_authenticatedStream.Start(m_server, null, m_fromUsername);
  128. }
  129. public static bool ValidateServerCertificate(
  130. object sender,
  131. X509Certificate certificate,
  132. X509Chain chain,
  133. SslPolicyErrors sslPolicyErrors)
  134. {
  135. logger.Debug(String.Format("XMPP Server Certificate: {0}", certificate.Subject));
  136. return true;
  137. }
  138. private static string GetPlainSASLResponse(string username, string password)
  139. {
  140. StringBuilder respnose = new StringBuilder();
  141. respnose.Append((char)0);
  142. respnose.Append(username);
  143. respnose.Append((char)0);
  144. respnose.Append(password);
  145. byte[] encode = Encoding.Default.GetBytes(respnose.ToString());
  146. return Convert.ToBase64String(encode, 0, encode.Length);
  147. }
  148. }
  149. }