PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/pop3/Pop3Client.cs

#
C# | 380 lines | 270 code | 79 blank | 31 comment | 24 complexity | 4ca9f923a1a13c320a6db85c13726ad9 MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Threading;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. using System.Diagnostics;
  10. using Org.Mentalis.Security.Ssl;
  11. namespace Pop3
  12. {
  13. public class Pop3Client
  14. {
  15. private Pop3Credential m_credential;
  16. public const int DEFAULT_POP3_PORT = 110;
  17. private const int MAX_BUFFER_READ_SIZE = 256;
  18. private long m_inboxPosition = 0;
  19. private long m_directPosition = -1;
  20. private SecureSocket m_socket = null;
  21. private Pop3Message m_pop3Message = null;
  22. public Pop3Credential UserDetails
  23. {
  24. set { m_credential = value; }
  25. get { return m_credential; }
  26. }
  27. public string MessageID
  28. {
  29. get { return m_pop3Message.MessageID; }
  30. }
  31. public string From
  32. {
  33. get { return m_pop3Message.From; }
  34. }
  35. public string To
  36. {
  37. get { return m_pop3Message.To; }
  38. }
  39. public string Subject
  40. {
  41. get { return m_pop3Message.Subject; }
  42. }
  43. public string Body
  44. {
  45. get { return m_pop3Message.Body; }
  46. }
  47. public IEnumerator MultipartEnumerator
  48. {
  49. get { return m_pop3Message.MultipartEnumerator; }
  50. }
  51. public bool IsMultipart
  52. {
  53. get { return m_pop3Message.IsMultipart; }
  54. }
  55. public Pop3Client(string user, string pass, string server)
  56. {
  57. m_credential = new Pop3Credential(user, pass, server);
  58. }
  59. public Pop3Client(string user, string pass, string server, int port)
  60. {
  61. m_credential = new Pop3Credential(user, pass, server, port);
  62. }
  63. public Pop3Client(string user, string pass, string server, int port, bool ssl_enabled)
  64. {
  65. m_credential = new Pop3Credential(user, pass, server, port, ssl_enabled);
  66. }
  67. private SecureSocket GetClientSocket()
  68. {
  69. SecureSocket s = null;
  70. try
  71. {
  72. IPHostEntry hostEntry = null;
  73. // Get host related information.
  74. hostEntry = Dns.GetHostEntry(m_credential.Server);
  75. // Loop through the AddressList to obtain the supported
  76. // AddressFamily. This is to avoid an exception that
  77. // occurs when the host IP Address is not compatible
  78. // with the address family
  79. // (typical in the IPv6 case).
  80. foreach (IPAddress address in hostEntry.AddressList)
  81. {
  82. int port = DEFAULT_POP3_PORT;
  83. if (m_credential.Port > 0)
  84. port = m_credential.Port;
  85. IPEndPoint ipe = new IPEndPoint(address, port);
  86. //Socket tempSocket =
  87. // new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  88. SecurityOptions secOpts;
  89. if (m_credential.EnableSsl)
  90. secOpts = new SecurityOptions(SecureProtocol.Ssl3);
  91. else
  92. secOpts = new SecurityOptions(SecureProtocol.None);
  93. SecureSocket tempSocket =
  94. new SecureSocket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp, secOpts);
  95. tempSocket.Connect(ipe);
  96. if (tempSocket.Connected)
  97. {
  98. // we have a connection.
  99. // return this socket ...
  100. s = tempSocket;
  101. break;
  102. }
  103. else
  104. {
  105. continue;
  106. }
  107. }
  108. }
  109. catch (Exception e)
  110. {
  111. throw new Pop3ConnectException(e.ToString());
  112. }
  113. // throw exception if can't connect ...
  114. if (s == null)
  115. {
  116. throw new Pop3ConnectException("Error : connecting to "
  117. + m_credential.Server);
  118. }
  119. return s;
  120. }
  121. //send the data to server
  122. private void Send(String data)
  123. {
  124. if (m_socket == null)
  125. {
  126. throw new Pop3MessageException("Pop3 connection is closed");
  127. }
  128. try
  129. {
  130. // Convert the string data to byte data
  131. // using Unicode encoding.
  132. byte[] byteData = Encoding.UTF8.GetBytes(data + "\r\n");
  133. // Begin sending the data to the remote device.
  134. m_socket.Send(byteData);
  135. }
  136. catch (Exception e)
  137. {
  138. throw new Pop3SendException(e.ToString());
  139. }
  140. }
  141. private string GetPop3String()
  142. {
  143. if (m_socket == null)
  144. {
  145. throw new
  146. Pop3MessageException("Connection to POP3 server is closed");
  147. }
  148. byte[] buffer = new byte[MAX_BUFFER_READ_SIZE];
  149. string line = null;
  150. try
  151. {
  152. int byteCount =
  153. m_socket.Receive(buffer, buffer.Length, 0);
  154. line =
  155. Encoding.UTF8.GetString(buffer, 0, byteCount);
  156. }
  157. catch (Exception e)
  158. {
  159. throw new Pop3ReceiveException(e.ToString());
  160. }
  161. return line;
  162. }
  163. private void LoginToInbox()
  164. {
  165. string returned;
  166. // send username ...
  167. Send("user " + m_credential.User);
  168. // get response ...
  169. returned = GetPop3String();
  170. if (!returned.Substring(0, 3).Equals("+OK"))
  171. {
  172. throw new Pop3LoginException("login not excepted");
  173. }
  174. // send password ...
  175. Send("pass " + m_credential.Pass);
  176. // get response ...
  177. returned = GetPop3String();
  178. if (!returned.Substring(0, 3).Equals("+OK"))
  179. {
  180. throw new
  181. Pop3LoginException("login/password not accepted");
  182. }
  183. }
  184. public long MessageCount
  185. {
  186. get
  187. {
  188. long count = 0;
  189. if (m_socket == null)
  190. {
  191. throw new Pop3MessageException("Pop3 server not connected");
  192. }
  193. Send("stat");
  194. string returned = GetPop3String();
  195. // if values returned ...
  196. if (Regex.Match(returned,
  197. @"^.*\+OK[ | ]+([0-9]+)[ | ]+.*$").Success)
  198. {
  199. // get number of emails ...
  200. count = long.Parse(Regex
  201. .Replace(returned.Replace("\r\n", "")
  202. , @"^.*\+OK[ | ]+([0-9]+)[ | ]+.*$", "$1"));
  203. }
  204. return (count);
  205. }
  206. }
  207. public void CloseConnection()
  208. {
  209. try
  210. {
  211. Send("quit");
  212. }
  213. catch { }
  214. if (m_socket != null)
  215. {
  216. m_socket.Close();
  217. m_socket = null;
  218. }
  219. m_pop3Message = null;
  220. }
  221. public bool DeleteEmail()
  222. {
  223. bool ret = false;
  224. Send("dele " + m_inboxPosition);
  225. string returned = GetPop3String();
  226. if (Regex.Match(returned,
  227. @"^.*\+OK.*$").Success)
  228. {
  229. ret = true;
  230. }
  231. return ret;
  232. }
  233. public bool NextEmail(long directPosition)
  234. {
  235. bool ret;
  236. if (directPosition >= 0)
  237. {
  238. m_directPosition = directPosition;
  239. ret = NextEmail();
  240. }
  241. else
  242. {
  243. throw new Pop3MessageException("Position less than zero");
  244. }
  245. return ret;
  246. }
  247. public bool NextEmail()
  248. {
  249. string returned;
  250. long pos;
  251. if (m_directPosition == -1)
  252. {
  253. if (m_inboxPosition == 0)
  254. {
  255. pos = 1;
  256. }
  257. else
  258. {
  259. pos = m_inboxPosition + 1;
  260. }
  261. }
  262. else
  263. {
  264. pos = m_directPosition + 1;
  265. m_directPosition = -1;
  266. }
  267. // send username ...
  268. Send("list " + pos.ToString());
  269. // get response ...
  270. returned = GetPop3String();
  271. // if email does not exist at this position
  272. // then return false ...
  273. if (returned.Substring(0, 4).Equals("-ERR"))
  274. {
  275. return false;
  276. }
  277. m_inboxPosition = pos;
  278. // strip out CRLF ...
  279. string[] noCr = returned.Split(new char[] { '\r' });
  280. // get size ...
  281. string[] elements = noCr[0].Split(new char[] { ' ' });
  282. long size = long.Parse(elements[2]);
  283. // ... else read email data
  284. m_pop3Message = new Pop3Message(m_inboxPosition, size, m_socket);
  285. return true;
  286. }
  287. public void OpenInbox()
  288. {
  289. // get a socket ...
  290. m_socket = GetClientSocket();
  291. // get initial header from POP3 server ...
  292. string header = GetPop3String();
  293. if (!header.Substring(0, 3).Equals("+OK"))
  294. {
  295. throw new Exception("Invalid initial POP3 response");
  296. }
  297. // send login details ...
  298. LoginToInbox();
  299. }
  300. }
  301. }