forked from andyedinborough/aenetmail
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TextClient.cs
147 lines (125 loc) · 4.14 KB
/
TextClient.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.IO;
using System.Net.Sockets;
namespace AE.Net.Mail {
public abstract class TextClient : IDisposable {
protected TcpClient _Connection;
protected Stream _Stream;
public virtual string Host { get; private set; }
public virtual int Port { get; set; }
public virtual bool Ssl { get; set; }
public virtual bool IsConnected { get; private set; }
public virtual bool IsAuthenticated { get; private set; }
public virtual bool IsDisposed { get; private set; }
public virtual System.Text.Encoding Encoding { get; set; }
public event EventHandler<WarningEventArgs> Warning;
protected virtual void RaiseWarning(MailMessage mailMessage, string message) {
var warning = Warning;
if (warning != null) {
warning(this, new WarningEventArgs { MailMessage = mailMessage, Message = message });
}
}
public TextClient() {
Encoding = System.Text.Encoding.GetEncoding(1252);
}
internal abstract void OnLogin(string username, string password);
internal abstract void OnLogout();
internal abstract void CheckResultOK(string result);
protected virtual void OnConnected(string result) {
CheckResultOK(result);
}
public virtual void Login(string username, string password) {
if (!IsConnected) {
throw new Exception("You must connect first!");
}
IsAuthenticated = false;
OnLogin(username, password);
IsAuthenticated = true;
}
public virtual void Logout() {
OnLogout();
IsAuthenticated = false;
}
public virtual void Connect(string hostname, int port, bool ssl, bool skipSslValidation) {
System.Net.Security.RemoteCertificateValidationCallback validateCertificate = null;
if (skipSslValidation)
validateCertificate = (sender, cert, chain, err) => true;
Connect(hostname, port, ssl, validateCertificate);
}
public virtual void Connect(string hostname, int port, bool ssl, System.Net.Security.RemoteCertificateValidationCallback validateCertificate) {
try {
Host = hostname;
Port = port;
Ssl = ssl;
_Connection = new TcpClient(hostname, port);
_Stream = _Connection.GetStream();
if (ssl) {
System.Net.Security.SslStream sslStream;
if (validateCertificate != null)
sslStream = new System.Net.Security.SslStream(_Stream, false, validateCertificate);
else
sslStream = new System.Net.Security.SslStream(_Stream, false);
_Stream = sslStream;
sslStream.AuthenticateAsClient(hostname);
}
OnConnected(GetResponse());
IsConnected = true;
Host = hostname;
} catch (Exception) {
IsConnected = false;
Utilities.TryDispose(ref _Stream);
throw;
}
}
protected virtual void CheckConnectionStatus() {
if (IsDisposed)
throw new ObjectDisposedException(this.GetType().Name);
if (!IsConnected)
throw new Exception("You must connect first!");
if (!IsAuthenticated)
throw new Exception("You must authenticate first!");
}
protected virtual void SendCommand(string command) {
var bytes = System.Text.Encoding.Default.GetBytes(command + "\r\n");
_Stream.Write(bytes, 0, bytes.Length);
}
protected virtual string SendCommandGetResponse(string command) {
SendCommand(command);
return GetResponse();
}
protected virtual string GetResponse(int Timeout = 10000) {
int max = 0;
return _Stream.ReadLine(ref max, Encoding, null, Timeout);
}
protected virtual void SendCommandCheckOK(string command) {
CheckResultOK(SendCommandGetResponse(command));
}
public virtual void Disconnect() {
if (!IsConnected)
return;
if (IsAuthenticated) {
Logout();
}
IsConnected = false;
Utilities.TryDispose(ref _Stream);
Utilities.TryDispose(ref _Connection);
}
~TextClient() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!IsDisposed && disposing)
lock (this)
if (!IsDisposed && disposing) {
IsDisposed = true;
Disconnect();
}
_Stream = null;
_Connection = null;
}
}
}