8000 Merge pull request #101 from caleblloyd/f_ssl2 · mysql-net/MySqlConnector@8477ec6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8477ec6

Browse files
authored
Merge pull request #101 from caleblloyd/f_ssl2
Add SSL support. Fixes #88
2 parents a25b2e5 + 1512af5 commit 8477ec6

19 files changed

+254
-42
lines changed

.ci/config.ssl.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"Data": {
3+
"ConnectionString": "server=127.0.0.1;user id=ssltest;password=test;port=3306;database=mysqltest;ssl mode=required;certificate file=.ci/ssl-client.pfx;Use Affected Rows=true",
4+
"PasswordlessUser": "no_password",
5+
"SupportsJson": true
6+
}
7+
}

.ci/server.cnf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# uses a seperate key for the server and clinet
2+
# this is how things should be run in production
3+
14
[mysqld]
25
ssl-ca=/etc/mysql/conf.d/ssl-ca.pem
36
ssl-cert=/etc/mysql/conf.d/ssl-server-cert.pem

.ci/server.debug

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# uses the same key for the server and client
2+
# uses a non-ephemeral cipher suite
3+
# allows for WireShark to decrypt packets given "ssl-client-key.pem"
4+
# go to "Edit -> Preferences", "Protocols", "SSL", and add RSA key
5+
# this is for testing, don't do this in production
6+
7+
[mysqld]
8+
ssl-ca=/etc/mysql/conf.d/ssl-ca.pem
9+
ssl-cert=/etc/mysql/conf.d/ssl-client-cert.pem
10+
ssl-key=/etc/mysql/conf.d/ssl-client-key.pem
11+
ssl-cipher=AES128-SHA

.ci/ssl-client.pfx

3.36 KB
Binary file not shown.

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ before_install:
88
- sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
99
- sudo apt-get update
1010
- sudo apt-get install -y dotnet-dev-1.0.0-preview2-003121
11-
- cp tests/SideBySide.New/config.json.example tests/SideBySide.New/config.json
1211

1312
script:
1413
- dotnet restore
1514
- dotnet test tests/MySqlConnector.Tests --configuration Release
16-
- dotnet test tests/SideBySide.New --configuration Release
15+
- echo 'Executing tests with ssl mode=none' && cp tests/SideBySide.New/config.json.example tests/SideBySide.New/config.json && dotnet test tests/SideBySide.New --configuration Release
16+
- echo 'Executing tests with ssl mode=required' && cp .ci/config.ssl.json tests/SideBySide.New/config.json && dotnet test tests/SideBySide.New --configuration Release

src/MySqlConnector/MySqlClient/ConnectionPool.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public async Task<MySqlSession> GetSessionAsync(IOBehavior ioBehavior, Cancellat
4343
}
4444

4545
session = new MySqlSession(this, m_generation);
46-
await session.ConnectAsync(m_servers, m_port, m_userId, m_password, m_database, ioBehavior, cancellationToken).ConfigureAwait(false);
46+
await session.ConnectAsync(m_servers, m_port, m_userId, m_password, m_database, m_sslMode, m_certificateFile, m_certificatePassword, ioBehavior, cancellationToken).ConfigureAwait(false);
4747
return session;
4848
}
4949
catch
@@ -124,8 +124,8 @@ public static ConnectionPool GetPool(MySqlConnectionStringBuilder csb)
124124
ConnectionPool pool;
125125
if (!s_pools.TryGetValue(key, out pool))
126126
{
127-
pool = s_pools.GetOrAdd(key, newKey => new ConnectionPool(csb.Server.Split(','), (int) csb.Port, csb.UserID,
128-
csb.Password, csb.Database, csb.ConnectionReset, (int)csb.MinimumPoolSize, (int) csb.MaximumPoolSize));
127+
pool = s_pools.GetOrAdd(key, newKey => new ConnectionPool(csb.Server.Split(','), (int) csb.Port, csb.UserID, csb.Password, csb.Database,
128+
csb.SslMode, csb.CertificateFile, csb.CertificatePassword, csb.ConnectionReset, (int)csb.MinimumPoolSize, (int) csb.MaximumPoolSize));
129129
}
130130
return pool;
131131
}
@@ -138,15 +138,18 @@ public static async Task ClearPoolsAsync(IOBehavior ioBehavior, CancellationToke
138138
await pool.ClearAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
139139
}
140140

141-
private ConnectionPool(IEnumerable<string> servers, int port, string userId, string password, string database,
142-
bool resetConnections, int minimumSize, int maximumSize)
141+
private ConnectionPool(IEnumerable<string> servers, int port, string userId, string password, string database, SslMode sslMode,
142+
string certificateFile, string certificatePassword, bool resetConnections, int minimumSize, int maximumSize)
143143
{
144144
m_servers = servers;
145145
m_port = port;
146146
m_userId = userId;
147147
m_password = password;
148148
m_database = database;
149149
m_resetConnections = resetConnections;
150+
m_sslMode = sslMode;
151+
m_certificateFile = certificateFile;
152+
m_certificatePassword = certificatePassword;
150153
m_minimumSize = minimumSize;
151154
m_maximumSize = maximumSize;
152155

@@ -166,6 +169,9 @@ private ConnectionPool(IEnumerable<string> servers, int port, string userId, str
166169
readonly string m_userId;
167170
readonly string m_password;
168171
readonly string m_database;
172+
readonly SslMode m_sslMode;
173+
readonly string m_certificateFile;
174+
readonly string m_certificatePassword;
169175
readonly bool m_resetConnections;
170176
readonly int m_minimumSize;
171177
readonly int m_maximumSize;

src/MySqlConnector/MySqlClient/MySqlConnection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ private async Task<MySqlSession> CreateSessionAsync(IOBehavior ioBehavior, Cance
226226
else
227227
{
228228
var session = new MySqlSession();
229-
await session.ConnectAsync(m_connectionStringBuilder.Server.Split(','), (int) m_connectionStringBuilder.Port, m_connectionStringBuilder.UserID,
230-
m_connectionStringBuilder.Password, m_connectionStringBuilder.Database, ioBehavior, linkedSource.Token).ConfigureAwait(false);
229+
await session.ConnectAsync(m_connectionStringBuilder.Server.Split(','), (int) m_connectionStringBuilder.Port, m_connectionStringBuilder.UserID, m_connectionStringBuilder.Password, m_connectionStringBuilder.Database,
230+
m_connectionStringBuilder.SslMode, m_connectionStringBuilder.CertificateFile, m_connectionStringBuilder.CertificatePassword, ioBehavior, linkedSource.Token).ConfigureAwait(false);
231231
return session;
232232
}
233233
}

src/MySqlConnector/MySqlClient/MySqlConnectionStringBuilder.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
namespace MySql.Data.MySqlClient
77
{
8+
public enum SslMode
9+
{
10+
None,
11+
Required,
12+
VerifyCa,
13+
VerifyFull,
14+
}
15+
816
public sealed class MySqlConnectionStringBuilder : DbConnectionStringBuilder
917
{
1018
public MySqlConnectionStringBuilder()
@@ -82,6 +90,24 @@ public bool UseCompression
8290
set { MySqlConnectionStringOption.UseCompression.SetValue(this, value); }
8391
}
8492

93+
public SslMode SslMode
94+
{
95+
get { return MySqlConnectionStringOption.SslMode.GetValue(this); }
96+
set { MySqlConnectionStringOption.SslMode.SetValue(this, value); }
97+
}
98+
99+
public string CertificateFile
100+
{
101+
get { return MySqlConnectionStringOption.CertificateFile.GetValue(this); }
102+
set { MySqlConnectionStringOption.CertificateFile.SetValue(this, value); }
103+
}
104+
105+
public string CertificatePassword
106+
{
107+
get { return MySqlConnectionStringOption.CertificatePassword.GetValue(this); }
108+
set { MySqlConnectionStringOption.CertificatePassword.SetValue(this, value); }
109+
}
110+
85111
public bool Pooling
86112
{
87113
get { return MySqlConnectionStringOption.Pooling.GetValue(this); }
@@ -179,6 +205,9 @@ internal abstract class MySqlConnectionStringOption
179205
public static readonly MySqlConnectionStringOption<bool> OldGuids;
180206
public static readonly MySqlConnectionStringOption<bool> PersistSecurityInfo;
181207
public static readonly MySqlConnectionStringOption<bool> UseCompression;
208+
public static readonly MySqlConnectionStringOption<SslMode> SslMode;
209+
public static readonly MySqlConnectionStringOption<string> CertificateFile;
210+
public static readonly MySqlConnectionStringOption<string> CertificatePassword;
182211
public static readonly MySqlConnectionStringOption<bool> Pooling;
183212
public static readonly MySqlConnectionStringOption<bool> ConnectionReset;
184213
public static readonly MySqlConnectionStringOption<uint> ConnectionTimeout;
@@ -265,6 +294,18 @@ static MySqlConnectionStringOption()
265294
keys: new[] { "Compress", "Use Compression", "UseCompression" },
266295
defaultValue: false));
267296

297+
AddOption(CertificateFile = new MySqlConnectionStringOption<string>(
298+
keys: new[] { "CertificateFile", "Certificate File" },
299+
defaultValue: ""));
300+
301+
AddOption(CertificatePassword = new MySqlConnectionStringOption<string>(
302+
keys: new[] { "CertificatePassword", "Certificate Password" },
303+
defaultValue: ""));
304+
305+
AddOption(SslMode = new MySqlConnectionStringOption<SslMode>(
306+
keys: new[] { "SSL Mode", "SslMode" },
307+
defaultValue: MySqlClient.SslMode.None));
308+
268309
AddOption(Pooling = new MySqlConnectionStringOption<bool>(
269310
keys: new[] { "Pooling" },
270311
defaultValue: true));
@@ -334,6 +375,16 @@ private static T ChangeType(object objectValue)
334375
return (T) (object) false;
335376
}
336377

378+
if (typeof(T) == typeof(SslMode) && objectValue is string)
379+
{
380+
foreach (var val in Enum.GetValues(typeof(T)))
381+
{
382+
if (string.Equals((string) objectValue, val.ToString(), StringComparison.OrdinalIgnoreCase))
383+
return (T) val;
384+
}
385+
throw new InvalidOperationException("Value '{0}' not supported for option '{1}'.".FormatInvariant(objectValue, typeof(T).Name));
386+
}
387+
337388
return (T) Convert.ChangeType(objectValue, typeof(T), CultureInfo.InvariantCulture);
338389
}
339390

src/MySqlConnector/Protocol/Serialization/IPacketHandler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace MySql.Data.Protocol.Serialization
55
{
66
internal interface IPacketHandler
77
{
8+
void SetByteHandler(IByteHandler byteHandler);
89
ValueTask<Packet> ReadPacketAsync(ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior);
910
ValueTask<int> WritePacketAsync(Packet packet, IOBehavior ioBehavior);
1011
}

src/MySqlConnector/Protocol/Serialization/IPayloadHandler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace MySql.Data.Protocol.Serialization
66
{
77
internal interface IPayloadHandler
88
{
9+
void SetByteHandler(IByteHandler byteHandler);
910
ValueTask<ArraySegment<byte>> ReadPayloadAsync(IConversation conversation, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior);
1011
ValueTask<int> WritePayloadAsync(IConversation conversation, ArraySegment<byte> payload, IOBehavior ioBehavior);
1112
}

0 commit comments

Comments
 (0)
0