From ac66265351c3c0e3f8adec34a8194a6e3414ce5f Mon Sep 17 00:00:00 2001 From: Rob Blackin Date: Tue, 17 Nov 2020 19:40:31 -0500 Subject: [PATCH 1/9] Added Sql Server Support. Needed to make CreateIndex and RemoveIndex abstract. --- .../Cryptography/NpgsqlCertificateDatabase.cs | 22 ++++++++++++++++ .../Cryptography/SqlCertificateDatabase.cs | 26 +++---------------- .../Cryptography/SqliteCertificateDatabase.cs | 20 ++++++++++++++ 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs b/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs index 1bee953df6..bf5f63d208 100644 --- a/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs @@ -260,5 +260,27 @@ protected override void AddTableColumn (DbConnection connection, DataTable table command.ExecuteNonQuery (); } } + protected override void CreateIndex(DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName(tableName, columnNames); + var query = string.Format("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join(", ", columnNames)); + + using (var command = connection.CreateCommand()) + { + command.CommandText = query; + command.ExecuteNonQuery(); + } + } + protected override void RemoveIndex(DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName(tableName, columnNames); + var query = string.Format("DROP INDEX IF EXISTS {0}", indexName); + + using (var command = connection.CreateCommand()) + { + command.CommandText = query; + command.ExecuteNonQuery(); + } + } } } diff --git a/MimeKit/Cryptography/SqlCertificateDatabase.cs b/MimeKit/Cryptography/SqlCertificateDatabase.cs index 482b6466c3..4569ed4143 100644 --- a/MimeKit/Cryptography/SqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqlCertificateDatabase.cs @@ -229,32 +229,12 @@ static DataTable CreateCrlsDataTable (string tableName) /// The column to add. protected abstract void AddTableColumn (DbConnection connection, DataTable table, DataColumn column); - static string GetIndexName (string tableName, string[] columnNames) + public static string GetIndexName (string tableName, string[] columnNames) { return string.Format ("{0}_{1}_INDEX", tableName, string.Join ("_", columnNames)); } - - static void CreateIndex (DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName (tableName, columnNames); - var query = string.Format ("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join (", ", columnNames)); - - using (var command = connection.CreateCommand ()) { - command.CommandText = query; - command.ExecuteNonQuery (); - } - } - - static void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName (tableName, columnNames); - var query = string.Format ("DROP INDEX IF EXISTS {0}", indexName); - - using (var command = connection.CreateCommand ()) { - command.CommandText = query; - command.ExecuteNonQuery (); - } - } + protected abstract void CreateIndex (DbConnection connection, string tableName, string[] columnNames); + protected abstract void RemoveIndex (DbConnection connection, string tableName, string[] columnNames); void CreateCertificatesTable (DataTable table) { diff --git a/MimeKit/Cryptography/SqliteCertificateDatabase.cs b/MimeKit/Cryptography/SqliteCertificateDatabase.cs index c37e68f0a0..cf2ad1da6b 100644 --- a/MimeKit/Cryptography/SqliteCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqliteCertificateDatabase.cs @@ -390,5 +390,25 @@ protected override void AddTableColumn (DbConnection connection, DataTable table command.ExecuteNonQuery (); } } + protected override void CreateIndex (DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join (", ", columnNames)); + + using (var command = connection.CreateCommand ()) { + command.CommandText = query; + command.ExecuteNonQuery (); + } + } + protected override void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("DROP INDEX IF EXISTS {0}", indexName); + + using (var command = connection.CreateCommand ()) { + command.CommandText = query; + command.ExecuteNonQuery (); + } + } } } From 47f30434a51ab3589cb712a000209c07f83d25c6 Mon Sep 17 00:00:00 2001 From: Rob Blackin Date: Tue, 17 Nov 2020 20:03:29 -0500 Subject: [PATCH 2/9] Added Nuget package and the missing SQLServerCertificateDatabase.cs file --- .../SQLServerCertificateDatabase.cs | 175 ++++++++++++++++++ MimeKit/MimeKit.csproj | 2 + 2 files changed, 177 insertions(+) create mode 100644 MimeKit/Cryptography/SQLServerCertificateDatabase.cs diff --git a/MimeKit/Cryptography/SQLServerCertificateDatabase.cs b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs new file mode 100644 index 0000000000..8303789823 --- /dev/null +++ b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs @@ -0,0 +1,175 @@ +// +// SQLServerCertificateDatabase.cs +// +// Author: Rob Blackin +// +// Copyright (c) 2013-2020 .NET Foundation and Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; + +namespace MimeKit.Cryptography +{ + public class SQLServerCertificateDatabase : SqlCertificateDatabase + { + public SQLServerCertificateDatabase(DbConnection connection, string password) : base(connection, password) + { + } + + protected override void AddTableColumn(DbConnection connection, DataTable table, DataColumn column) + { + var statement = new StringBuilder("ALTER TABLE "); + int primaryKeys = table.PrimaryKey?.Length ?? 0; + + statement.Append(table.TableName); + statement.Append(" ADD COLUMN "); + Build(statement, table, column, ref primaryKeys); + + using (var command = connection.CreateCommand()) + { + command.CommandText = statement.ToString(); + command.CommandType = CommandType.Text; + command.ExecuteNonQuery(); + } + } + + protected override void CreateTable(DbConnection connection, DataTable table) + { + var statement = new StringBuilder($"if not exists (select * from sysobjects where name='{table.TableName}' and xtype='U') "); + int primaryKeys = 0; + + statement.Append($"Create table {table.TableName} ("); + + foreach (DataColumn column in table.Columns) + { + Build(statement, table, column, ref primaryKeys); + statement.Append(", "); + } + + if (table.Columns.Count > 0) + statement.Length -= 2; + + statement.Append(')'); + + using (var command = connection.CreateCommand()) + { + command.CommandText = statement.ToString(); + command.CommandType = CommandType.Text; + command.ExecuteNonQuery(); + } + } + static void Build(StringBuilder statement, DataTable table, DataColumn column, ref int primaryKeys) + { + statement.Append(column.ColumnName); + statement.Append(' '); + + if (column.DataType == typeof(long) || column.DataType == typeof(int)) + { + if (column.AutoIncrement) + statement.Append("int identity(1,1)"); + else + statement.Append("int"); + } + else if (column.DataType == typeof(bool)) + { + statement.Append("bit"); + } + else if (column.DataType == typeof(byte[])) + { + statement.Append($"varbinary(4096)"); + } + else if (column.DataType == typeof(string)) + { + statement.Append("varchar(256)"); + } + else + { + throw new NotImplementedException(); + } + + bool isPrimaryKey = false; + if (table != null && table.PrimaryKey != null && primaryKeys < table.PrimaryKey.Length) + { + for (int i = 0; i < table.PrimaryKey.Length; i++) + { + if (column == table.PrimaryKey[i]) + { + statement.Append(" PRIMARY KEY Clustered"); + isPrimaryKey = true; + primaryKeys++; + break; + } + } + } + + if (column.Unique && !isPrimaryKey) + statement.Append(" UNIQUE"); + + if (!column.AllowDBNull) + statement.Append(" NOT NULL"); + } + protected override IList GetTableColumns(DbConnection connection, string tableName) + { + using (var command = connection.CreateCommand()) + { + command.CommandText = $"select top 1 * from {tableName}"; + using (var reader = command.ExecuteReader()) + { + var columns = new List(); + var table = reader.GetSchemaTable(); + foreach (DataRow row in table.Rows) + { + columns.Add(new DataColumn { ColumnName = row.Field("ColumnName") }); + } + + return columns; + } + } + } + + protected override void CreateIndex(DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName(tableName, columnNames); + var query = string.Format("IF NOT EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) CREATE INDEX {0} ON {1}({2})", indexName, tableName, string.Join(", ", columnNames)); + + using (var command = connection.CreateCommand()) + { + command.CommandText = query; + command.ExecuteNonQuery(); + } + } + + protected override void RemoveIndex(DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName(tableName, columnNames); + var query = string.Format("IF EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) DROP INDEX {0} ON {1}", indexName, tableName); + + using (var command = connection.CreateCommand()) + { + command.CommandText = query; + command.ExecuteNonQuery(); + } + } + } +} diff --git a/MimeKit/MimeKit.csproj b/MimeKit/MimeKit.csproj index e29d780a7f..a72895be6c 100644 --- a/MimeKit/MimeKit.csproj +++ b/MimeKit/MimeKit.csproj @@ -67,6 +67,7 @@ + @@ -134,6 +135,7 @@ + From a4d72b0264cae0dd896bb553b4a1b57725d0fae7 Mon Sep 17 00:00:00 2001 From: Rob Blackin Date: Wed, 18 Nov 2020 11:51:58 -0500 Subject: [PATCH 3/9] tweak per PR Review --- .../Cryptography/SqlCertificateDatabase.cs | 25 ++++++++++++++++--- .../Cryptography/SqliteCertificateDatabase.cs | 19 -------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/MimeKit/Cryptography/SqlCertificateDatabase.cs b/MimeKit/Cryptography/SqlCertificateDatabase.cs index 4569ed4143..17d611c538 100644 --- a/MimeKit/Cryptography/SqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqlCertificateDatabase.cs @@ -229,12 +229,31 @@ static DataTable CreateCrlsDataTable (string tableName) /// The column to add. protected abstract void AddTableColumn (DbConnection connection, DataTable table, DataColumn column); - public static string GetIndexName (string tableName, string[] columnNames) + protected string GetIndexName (string tableName, string[] columnNames) { return string.Format ("{0}_{1}_INDEX", tableName, string.Join ("_", columnNames)); } - protected abstract void CreateIndex (DbConnection connection, string tableName, string[] columnNames); - protected abstract void RemoveIndex (DbConnection connection, string tableName, string[] columnNames); + + protected virtual void CreateIndex (DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join (", ", columnNames)); + + using (var command = connection.CreateCommand ()) { + command.CommandText = query; + command.ExecuteNonQuery (); + } + } + protected virtual void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) + { + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("DROP INDEX IF EXISTS {0}", indexName); + + using (var command = connection.CreateCommand ()) { + command.CommandText = query; + command.ExecuteNonQuery (); + } + } void CreateCertificatesTable (DataTable table) { diff --git a/MimeKit/Cryptography/SqliteCertificateDatabase.cs b/MimeKit/Cryptography/SqliteCertificateDatabase.cs index cf2ad1da6b..8a43f4438f 100644 --- a/MimeKit/Cryptography/SqliteCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqliteCertificateDatabase.cs @@ -390,25 +390,6 @@ protected override void AddTableColumn (DbConnection connection, DataTable table command.ExecuteNonQuery (); } } - protected override void CreateIndex (DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName (tableName, columnNames); - var query = string.Format ("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join (", ", columnNames)); - using (var command = connection.CreateCommand ()) { - command.CommandText = query; - command.ExecuteNonQuery (); - } - } - protected override void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName (tableName, columnNames); - var query = string.Format ("DROP INDEX IF EXISTS {0}", indexName); - - using (var command = connection.CreateCommand ()) { - command.CommandText = query; - command.ExecuteNonQuery (); - } - } } } From e6e172e5bd3b5073d9d086df50d7bf6602a5f5ad Mon Sep 17 00:00:00 2001 From: Rob Blackin Date: Thu, 19 Nov 2020 11:54:03 -0500 Subject: [PATCH 4/9] fix for insert and reading certificate --- .../SQLServerCertificateDatabase.cs | 79 +++++++++++++++++-- .../Cryptography/SqlCertificateDatabase.cs | 8 +- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/MimeKit/Cryptography/SQLServerCertificateDatabase.cs b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs index 8303789823..10d0f0f77b 100644 --- a/MimeKit/Cryptography/SQLServerCertificateDatabase.cs +++ b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs @@ -29,6 +29,10 @@ using System.Data.Common; using System.Text; +using MimeKit.Utils; + +using Org.BouncyCastle.X509; + namespace MimeKit.Cryptography { public class SQLServerCertificateDatabase : SqlCertificateDatabase @@ -88,7 +92,9 @@ static void Build(StringBuilder statement, DataTable table, DataColumn column, r { if (column.AutoIncrement) statement.Append("int identity(1,1)"); - else + else if (column.DataType == typeof (long)) + statement.Append ("DateTime"); + else statement.Append("int"); } else if (column.DataType == typeof(bool)) @@ -108,7 +114,6 @@ static void Build(StringBuilder statement, DataTable table, DataColumn column, r throw new NotImplementedException(); } - bool isPrimaryKey = false; if (table != null && table.PrimaryKey != null && primaryKeys < table.PrimaryKey.Length) { for (int i = 0; i < table.PrimaryKey.Length; i++) @@ -116,16 +121,12 @@ static void Build(StringBuilder statement, DataTable table, DataColumn column, r if (column == table.PrimaryKey[i]) { statement.Append(" PRIMARY KEY Clustered"); - isPrimaryKey = true; primaryKeys++; break; } } } - if (column.Unique && !isPrimaryKey) - statement.Append(" UNIQUE"); - if (!column.AllowDBNull) statement.Append(" NOT NULL"); } @@ -171,5 +172,69 @@ protected override void RemoveIndex(DbConnection connection, string tableName, s command.ExecuteNonQuery(); } } - } + + /// + /// Gets the database command to select the record matching the specified certificate. + /// + /// + /// Gets the database command to select the record matching the specified certificate. + /// + /// The database command. + /// The certificate. + /// The fields to return. + protected override DbCommand GetSelectCommand (X509Certificate certificate, X509CertificateRecordFields fields) + { + var fingerprint = certificate.GetFingerprint ().ToLowerInvariant (); + var serialNumber = certificate.SerialNumber.ToString (); + var issuerName = certificate.IssuerDN.ToString (); + var command = connection.CreateCommand (); + var query = CreateSelectQuery (fields).Replace("SELECT","SELECT top 1"); + + // FIXME: Is this really the best way to query for an exact match of a certificate? + query = query.Append (" WHERE ISSUERNAME = @ISSUERNAME AND SERIALNUMBER = @SERIALNUMBER AND FINGERPRINT = @FINGERPRINT"); + command.AddParameterWithValue ("@ISSUERNAME", issuerName); + command.AddParameterWithValue ("@SERIALNUMBER", serialNumber); + command.AddParameterWithValue ("@FINGERPRINT", fingerprint); + + command.CommandText = query.ToString (); + command.CommandType = CommandType.Text; + + return command; + } + + protected override DbCommand GetInsertCommand (X509CertificateRecord record) + { + var statement = new StringBuilder ("INSERT INTO CERTIFICATES("); + var variables = new StringBuilder ("VALUES("); + var command = connection.CreateCommand (); + var columns = certificatesTable.Columns; + + for (int i = 1; i < columns.Count; i++) { + if (i > 1) { + statement.Append (", "); + variables.Append (", "); + } + + var value = GetValue (record, columns[i].ColumnName); + if (value.GetType () == typeof (DateTime)) { + value = ((DateTime) value < DateUtils.UnixEpoch) ? DateUtils.UnixEpoch : (DateTime)value; + } + + if (columns[i].ColumnName == "PRIVATEKEY" && value.GetType()==typeof(DBNull)) { value = new byte[] { }; } + var variable = "@" + columns[i]; + + command.AddParameterWithValue (variable, value); + statement.Append (columns[i]); + variables.Append (variable); + } + + statement.Append (')'); + variables.Append (')'); + + command.CommandText = statement + " " + variables; + command.CommandType = CommandType.Text; + + return command; + } + } } diff --git a/MimeKit/Cryptography/SqlCertificateDatabase.cs b/MimeKit/Cryptography/SqlCertificateDatabase.cs index 17d611c538..e9983af6fd 100644 --- a/MimeKit/Cryptography/SqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqlCertificateDatabase.cs @@ -53,8 +53,8 @@ namespace MimeKit.Cryptography { /// public abstract class SqlCertificateDatabase : X509CertificateDatabase { - readonly DataTable certificatesTable, crlsTable; - readonly DbConnection connection; + protected readonly DataTable certificatesTable, crlsTable; + protected readonly DbConnection connection; bool disposed; /// @@ -336,7 +336,7 @@ void CreateCrlsTable (DataTable table) CreateIndex (connection, table.TableName, new [] { "DELTA", "ISSUERNAME", "THISUPDATE" }); } - static StringBuilder CreateSelectQuery (X509CertificateRecordFields fields) + protected StringBuilder CreateSelectQuery (X509CertificateRecordFields fields) { var query = new StringBuilder ("SELECT "); var columns = GetColumnNames (fields); @@ -551,7 +551,7 @@ protected override DbCommand GetSelectCommand (IX509Selector selector, bool trus query.Length = baseQueryLength; } - command.CommandText = query.ToString (); + command.CommandText = query.ToString(); command.CommandType = CommandType.Text; return command; From 18cf72078ffdd7193215d3fa52f1f64a3e3fd526 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 19 Nov 2020 20:44:16 -0500 Subject: [PATCH 5/9] Update NpgsqlCertificateDatabase.cs No need to override CreateIndex() and RemoveIndex() anymore. --- .../Cryptography/NpgsqlCertificateDatabase.cs | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs b/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs index bf5f63d208..1bee953df6 100644 --- a/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/NpgsqlCertificateDatabase.cs @@ -260,27 +260,5 @@ protected override void AddTableColumn (DbConnection connection, DataTable table command.ExecuteNonQuery (); } } - protected override void CreateIndex(DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName(tableName, columnNames); - var query = string.Format("CREATE INDEX IF NOT EXISTS {0} ON {1}({2})", indexName, tableName, string.Join(", ", columnNames)); - - using (var command = connection.CreateCommand()) - { - command.CommandText = query; - command.ExecuteNonQuery(); - } - } - protected override void RemoveIndex(DbConnection connection, string tableName, string[] columnNames) - { - var indexName = GetIndexName(tableName, columnNames); - var query = string.Format("DROP INDEX IF EXISTS {0}", indexName); - - using (var command = connection.CreateCommand()) - { - command.CommandText = query; - command.ExecuteNonQuery(); - } - } } } From 59afec7181243b672e97e246ef8a5ae412e6e0b9 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 19 Nov 2020 20:46:08 -0500 Subject: [PATCH 6/9] Update SqlCertificateDatabase.cs --- MimeKit/Cryptography/SqlCertificateDatabase.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MimeKit/Cryptography/SqlCertificateDatabase.cs b/MimeKit/Cryptography/SqlCertificateDatabase.cs index e9983af6fd..50fdea2d92 100644 --- a/MimeKit/Cryptography/SqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqlCertificateDatabase.cs @@ -244,6 +244,7 @@ protected virtual void CreateIndex (DbConnection connection, string tableName, s command.ExecuteNonQuery (); } } + protected virtual void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) { var indexName = GetIndexName (tableName, columnNames); From b291b85d50d86bd93512076d5afa6c1eaaa46989 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 19 Nov 2020 20:47:32 -0500 Subject: [PATCH 7/9] Update SqlCertificateDatabase.cs formatting fix --- MimeKit/Cryptography/SqlCertificateDatabase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MimeKit/Cryptography/SqlCertificateDatabase.cs b/MimeKit/Cryptography/SqlCertificateDatabase.cs index 50fdea2d92..cd5979ce32 100644 --- a/MimeKit/Cryptography/SqlCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqlCertificateDatabase.cs @@ -552,7 +552,7 @@ protected override DbCommand GetSelectCommand (IX509Selector selector, bool trus query.Length = baseQueryLength; } - command.CommandText = query.ToString(); + command.CommandText = query.ToString (); command.CommandType = CommandType.Text; return command; From b73d4c2b06331e029f07a2dd627485d28f92ab4d Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 19 Nov 2020 20:47:58 -0500 Subject: [PATCH 8/9] Update SqliteCertificateDatabase.cs formatting fix --- MimeKit/Cryptography/SqliteCertificateDatabase.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MimeKit/Cryptography/SqliteCertificateDatabase.cs b/MimeKit/Cryptography/SqliteCertificateDatabase.cs index 8a43f4438f..c37e68f0a0 100644 --- a/MimeKit/Cryptography/SqliteCertificateDatabase.cs +++ b/MimeKit/Cryptography/SqliteCertificateDatabase.cs @@ -390,6 +390,5 @@ protected override void AddTableColumn (DbConnection connection, DataTable table command.ExecuteNonQuery (); } } - } } From ff3d62abb8474e70605598817644df64753505f9 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 19 Nov 2020 20:57:22 -0500 Subject: [PATCH 9/9] Update SQLServerCertificateDatabase.cs formatting fixes --- .../SQLServerCertificateDatabase.cs | 151 ++++++++---------- 1 file changed, 67 insertions(+), 84 deletions(-) diff --git a/MimeKit/Cryptography/SQLServerCertificateDatabase.cs b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs index 10d0f0f77b..10f87bb811 100644 --- a/MimeKit/Cryptography/SQLServerCertificateDatabase.cs +++ b/MimeKit/Cryptography/SQLServerCertificateDatabase.cs @@ -23,104 +23,90 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // + using System; -using System.Collections.Generic; +using System.Text; using System.Data; using System.Data.Common; -using System.Text; +using System.Collections.Generic; using MimeKit.Utils; using Org.BouncyCastle.X509; -namespace MimeKit.Cryptography -{ +namespace MimeKit.Cryptography { public class SQLServerCertificateDatabase : SqlCertificateDatabase { - public SQLServerCertificateDatabase(DbConnection connection, string password) : base(connection, password) + public SQLServerCertificateDatabase (DbConnection connection, string password) : base (connection, password) { } - protected override void AddTableColumn(DbConnection connection, DataTable table, DataColumn column) + protected override void AddTableColumn (DbConnection connection, DataTable table, DataColumn column) { - var statement = new StringBuilder("ALTER TABLE "); + var statement = new StringBuilder ("ALTER TABLE "); int primaryKeys = table.PrimaryKey?.Length ?? 0; - statement.Append(table.TableName); - statement.Append(" ADD COLUMN "); - Build(statement, table, column, ref primaryKeys); + statement.Append (table.TableName); + statement.Append (" ADD COLUMN "); + Build (statement, table, column, ref primaryKeys); - using (var command = connection.CreateCommand()) - { - command.CommandText = statement.ToString(); + using (var command = connection.CreateCommand ()) { + command.CommandText = statement.ToString (); command.CommandType = CommandType.Text; - command.ExecuteNonQuery(); + command.ExecuteNonQuery (); } } - protected override void CreateTable(DbConnection connection, DataTable table) + protected override void CreateTable (DbConnection connection, DataTable table) { - var statement = new StringBuilder($"if not exists (select * from sysobjects where name='{table.TableName}' and xtype='U') "); + var statement = new StringBuilder ($"if not exists (select * from sysobjects where name='{table.TableName}' and xtype='U') "); int primaryKeys = 0; - statement.Append($"Create table {table.TableName} ("); + statement.Append ($"Create table {table.TableName} ("); - foreach (DataColumn column in table.Columns) - { - Build(statement, table, column, ref primaryKeys); - statement.Append(", "); + foreach (DataColumn column in table.Columns) { + Build (statement, table, column, ref primaryKeys); + statement.Append (", "); } if (table.Columns.Count > 0) statement.Length -= 2; - statement.Append(')'); + statement.Append (')'); - using (var command = connection.CreateCommand()) - { - command.CommandText = statement.ToString(); + using (var command = connection.CreateCommand ()) { + command.CommandText = statement.ToString (); command.CommandType = CommandType.Text; - command.ExecuteNonQuery(); + command.ExecuteNonQuery (); } } - static void Build(StringBuilder statement, DataTable table, DataColumn column, ref int primaryKeys) + + static void Build (StringBuilder statement, DataTable table, DataColumn column, ref int primaryKeys) { - statement.Append(column.ColumnName); - statement.Append(' '); + statement.Append (column.ColumnName); + statement.Append (' '); - if (column.DataType == typeof(long) || column.DataType == typeof(int)) - { + if (column.DataType == typeof (long) || column.DataType == typeof (int)) { if (column.AutoIncrement) - statement.Append("int identity(1,1)"); + statement.Append ("int identity(1,1)"); else if (column.DataType == typeof (long)) statement.Append ("DateTime"); else - statement.Append("int"); - } - else if (column.DataType == typeof(bool)) - { - statement.Append("bit"); - } - else if (column.DataType == typeof(byte[])) - { - statement.Append($"varbinary(4096)"); - } - else if (column.DataType == typeof(string)) - { - statement.Append("varchar(256)"); - } - else - { - throw new NotImplementedException(); + statement.Append ("int"); + } else if (column.DataType == typeof (bool)) { + statement.Append ("bit"); + } else if (column.DataType == typeof (byte[])) { + statement.Append ($"varbinary(4096)"); + } else if (column.DataType == typeof (string)) { + statement.Append ("varchar(256)"); + } else { + throw new NotImplementedException (); } - if (table != null && table.PrimaryKey != null && primaryKeys < table.PrimaryKey.Length) - { - for (int i = 0; i < table.PrimaryKey.Length; i++) - { - if (column == table.PrimaryKey[i]) - { - statement.Append(" PRIMARY KEY Clustered"); + if (table != null && table.PrimaryKey != null && primaryKeys < table.PrimaryKey.Length) { + for (int i = 0; i < table.PrimaryKey.Length; i++) { + if (column == table.PrimaryKey[i]) { + statement.Append (" PRIMARY KEY Clustered"); primaryKeys++; break; } @@ -128,48 +114,44 @@ static void Build(StringBuilder statement, DataTable table, DataColumn column, r } if (!column.AllowDBNull) - statement.Append(" NOT NULL"); + statement.Append (" NOT NULL"); } - protected override IList GetTableColumns(DbConnection connection, string tableName) + + protected override IList GetTableColumns (DbConnection connection, string tableName) { - using (var command = connection.CreateCommand()) - { + using (var command = connection.CreateCommand ()) { command.CommandText = $"select top 1 * from {tableName}"; - using (var reader = command.ExecuteReader()) - { - var columns = new List(); - var table = reader.GetSchemaTable(); + using (var reader = command.ExecuteReader ()) { + var columns = new List (); + var table = reader.GetSchemaTable (); + foreach (DataRow row in table.Rows) - { - columns.Add(new DataColumn { ColumnName = row.Field("ColumnName") }); - } + columns.Add (new DataColumn { ColumnName = row.Field ("ColumnName") }); return columns; } } } - protected override void CreateIndex(DbConnection connection, string tableName, string[] columnNames) + protected override void CreateIndex (DbConnection connection, string tableName, string[] columnNames) { - var indexName = GetIndexName(tableName, columnNames); - var query = string.Format("IF NOT EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) CREATE INDEX {0} ON {1}({2})", indexName, tableName, string.Join(", ", columnNames)); + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("IF NOT EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) CREATE INDEX {0} ON {1}({2})", indexName, tableName, string.Join(", ", columnNames)); - using (var command = connection.CreateCommand()) - { + using (var command = connection.CreateCommand ()) { command.CommandText = query; - command.ExecuteNonQuery(); + command.ExecuteNonQuery (); } } - protected override void RemoveIndex(DbConnection connection, string tableName, string[] columnNames) + protected override void RemoveIndex (DbConnection connection, string tableName, string[] columnNames) { - var indexName = GetIndexName(tableName, columnNames); - var query = string.Format("IF EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) DROP INDEX {0} ON {1}", indexName, tableName); + var indexName = GetIndexName (tableName, columnNames); + var query = string.Format ("IF EXISTS (Select 8 from sys.indexes where name='{0}' and object_id=OBJECT_ID('{1}')) DROP INDEX {0} ON {1}", indexName, tableName); - using (var command = connection.CreateCommand()) - { + using (var command = connection.CreateCommand ()) { command.CommandText = query; - command.ExecuteNonQuery(); + command.ExecuteNonQuery (); } } @@ -188,7 +170,7 @@ protected override DbCommand GetSelectCommand (X509Certificate certificate, X509 var serialNumber = certificate.SerialNumber.ToString (); var issuerName = certificate.IssuerDN.ToString (); var command = connection.CreateCommand (); - var query = CreateSelectQuery (fields).Replace("SELECT","SELECT top 1"); + var query = CreateSelectQuery (fields).Replace ("SELECT", "SELECT top 1"); // FIXME: Is this really the best way to query for an exact match of a certificate? query = query.Append (" WHERE ISSUERNAME = @ISSUERNAME AND SERIALNUMBER = @SERIALNUMBER AND FINGERPRINT = @FINGERPRINT"); @@ -216,11 +198,12 @@ protected override DbCommand GetInsertCommand (X509CertificateRecord record) } var value = GetValue (record, columns[i].ColumnName); - if (value.GetType () == typeof (DateTime)) { - value = ((DateTime) value < DateUtils.UnixEpoch) ? DateUtils.UnixEpoch : (DateTime)value; - } + if (value.GetType () == typeof (DateTime)) + value = ((DateTime) value < DateUtils.UnixEpoch) ? DateUtils.UnixEpoch : (DateTime) value; + + if (columns[i].ColumnName == "PRIVATEKEY" && value.GetType () == typeof (DBNull)) + value = new byte[0]; - if (columns[i].ColumnName == "PRIVATEKEY" && value.GetType()==typeof(DBNull)) { value = new byte[] { }; } var variable = "@" + columns[i]; command.AddParameterWithValue (variable, value);