Skip to content

Commit 8dc820c

Browse files
Merge pull request #75 from microsoft/SQLCHECK_CertPerm
added Certificate permissions
2 parents aafcd1b + 4143338 commit 8dc820c

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

SQLCheck/SQLCheck/Collectors.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
using System.Security.Cryptography.X509Certificates;
1616
using System.Security.Cryptography;
1717
using System.Linq;
18+
using System.ComponentModel;
19+
using System.Runtime.Remoting.Messaging;
20+
using System.Security.Principal;
21+
using System.Runtime.ConstrainedExecution;
1822

1923
namespace SQLCheck
2024
{
@@ -47,10 +51,12 @@ public static void Collect(DataSet ds)
4751
CollectSQLAlias(ds);
4852
CollectClientSNI(ds);
4953
CollectCertificate(ds);
54+
CollectCertificatePerm(ds);
5055
CollectService(ds);
5156
CollectSPNAccount(ds);
5257
CollectSQLInstance(ds); // dropped SQL 2000 and RS 2000
5358
CollectSQLServer(ds);
59+
5460
// Collect SSRS
5561
// Collect OLAP
5662

@@ -3423,5 +3429,54 @@ public static bool CompareAccounts(string account1, string account2)
34233429
// no match
34243430
return false;
34253431
}
3432+
3433+
private static void CollectCertificatePerm(DataSet ds)
3434+
{
3435+
DataTable dtCertificatePerm = ds.Tables["CertificatePermissions"];
3436+
DataRow Certificate = null;
3437+
try
3438+
{
3439+
3440+
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); //set store to Local Machine/My
3441+
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
3442+
string keyPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"/Microsoft/Crypto/RSA/MachineKeys/";
3443+
foreach (X509Certificate2 mCert in store.Certificates) //loop through all private keys in store directory
3444+
{
3445+
if (mCert.HasPrivateKey)//check to see if the certificate has a private key
3446+
{
3447+
try
3448+
{
3449+
RSACryptoServiceProvider pkey = (RSACryptoServiceProvider)mCert.PrivateKey; //save private key to a veriable
3450+
3451+
if (pkey != null)
3452+
{
3453+
//get private key file name
3454+
string Container = pkey.CspKeyContainerInfo.KeyContainerName.ToString(); //get private key file name
3455+
string[] pKeyName = Container.Split('}');
3456+
string PrivateKey = pKeyName[pKeyName.Length - 1];
3457+
//add private key file name to the folder path
3458+
if (File.Exists(keyPath + PrivateKey))
3459+
{
3460+
FileSecurity fSecurity = File.GetAccessControl(keyPath + PrivateKey);
3461+
//loop through all ACL on the file and add it to the data collector
3462+
foreach (FileSystemAccessRule rule in fSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
3463+
{
3464+
Certificate = dtCertificatePerm.NewRow();
3465+
Certificate["FriendlyName"] = mCert.FriendlyName;
3466+
Certificate["Thumbprint"] = mCert.Thumbprint;
3467+
Certificate["UserID"] = $"{rule.IdentityReference.Value}";
3468+
Certificate["Permissions"] = $"{rule.FileSystemRights}";
3469+
dtCertificatePerm.Rows.Add(Certificate);
3470+
}
3471+
}
3472+
}
3473+
}
3474+
catch { };
3475+
}
3476+
}
3477+
store.Close();
3478+
}
3479+
catch (Exception ex) { Console.WriteLine(ex); };
3480+
}
34263481
}
34273482
}

SQLCheck/SQLCheck/Storage.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,19 @@ public static DataSet CreateDataSet(String ComputerName)
586586
dt.AddColumn("Message", "String");
587587
ds.Tables.Add(dt);
588588

589+
//
590+
//Certificate User and Permissions
591+
//
592+
593+
dt = new DataTable("CertificatePermissions");
594+
dt.AddColumn("ID", "Integer");
595+
dt.Columns["ID"].AutoIncrement=true;
596+
dt.AddColumn("FriendlyName", "String");
597+
dt.AddColumn("Thumbprint", "String");
598+
dt.AddColumn("UserID", "String");
599+
dt.AddColumn("Permissions", "String");
600+
ds.Tables.Add(dt);
601+
589602
return ds;
590603
}
591604

SQLCheck/SQLCheck/TextReport.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static void Report(DataSet ds, TextWriter s)
4343
s.WriteLine(SmartString.CenterText("SQL Server Information", fieldWidth));
4444
s.WriteLine();
4545
ReportCertificate(ds, s);
46+
ReportCertificatePermissions(ds, s);
4647
ReportService(ds, s);
4748
ReportSQLServer(ds, s);
4849
ReportFooter(s);
@@ -1041,6 +1042,26 @@ static void ReportSQLServer(DataSet ds, TextWriter s) // outputs computer and d
10411042
}
10421043
}
10431044

1045+
static void ReportCertificatePermissions(DataSet ds, TextWriter s) // outputs Certificate friendly name, thumbprint, UserID's and permissions
1046+
{
1047+
DataTable dtCertificatePerm = ds.Tables["CertificatePermissions"];
1048+
s.WriteLine("Certificate Permissions:");
1049+
s.WriteLine();
1050+
ReportFormatter rf = new ReportFormatter();
1051+
rf.SetColumnNames("Friendly Name:L", "Thumbprint:L", "UserID:L", "Permissions:L");
1052+
foreach (DataRow drCertPerm in dtCertificatePerm.Rows)
1053+
{
1054+
rf.SetcolumnData(drCertPerm.GetString("FriendlyName"),
1055+
drCertPerm.GetString("Thumbprint"),
1056+
drCertPerm.GetString("UserID"),
1057+
drCertPerm.GetString("Permissions"));
1058+
}
1059+
s.WriteLine(rf.GetHeaderText());
1060+
s.WriteLine(rf.GetSeparatorText());
1061+
for (int i = 0; i < rf.GetRowCount(); i++) s.WriteLine(rf.GetDataText(i));
1062+
s.WriteLine();
1063+
ReportMessages(ds, s, "Certificate Permissions", -1); // returns a blank line at the end ... -1 = messages for all rows
1064+
}
10441065
static void ReportMessages(DataSet ds, TextWriter s, string tableName, int tableRow, bool blankLineAlways = false, bool WarningsAndAbove = false)
10451066
{
10461067

0 commit comments

Comments
 (0)