AFK Macro

Idle Mafia Macro/Source/src/linux/Trust.cs

Trust.cs

Linux: the certificates for Discord messages · 78 lines · 4 KB

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IdleMafiaBot
{
static class Trust
{
static readonly string[] Bundles = {
"/etc/ssl/certs/ca-certificates.crt", "/etc/pki/tls/certs/ca-bundle.crt", "/etc/ssl/cert.pem", "/etc/ssl/ca-bundle.pem" };
public static string Sync()
{
try
{
string bundle = Bundles.FirstOrDefault(File.Exists);
if (bundle == null) return "Discord: no system certificate list found (/etc/ssl/certs) - Discord messages may fail";
string home = Environment.GetEnvironmentVariable("HOME");
if (string.IsNullOrEmpty(home)) return null;
string trustDir = Path.Combine(home, ".config/.mono/new-certs/Trust");
if (Directory.Exists(trustDir))
{
var files = Directory.GetFiles(trustDir);
if (files.Length >= 20 && files.Max(f => File.GetLastWriteTimeUtc(f)) >= File.GetLastWriteTimeUtc(bundle)) return null;
}
var ders = Pem(File.ReadAllText(bundle));
if (ders.Count == 0) return null;
var asm = Assembly.Load("Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
var certT = asm.GetType("Mono.Security.X509.X509Certificate", true);
var mgr = asm.GetType("Mono.Security.X509.X509StoreManager", true);
var stores = mgr.GetProperty("NewCurrentUser", BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
var store = stores.GetType().GetProperty("TrustedRoot").GetValue(stores, null);
var import = store.GetType().GetMethod("Import", new[] { certT });
var have = store.GetType().GetProperty("Certificates").GetValue(store, null);
var contains = have.GetType().GetMethod("Contains", new[] { certT });
int added = 0;
foreach (var der in ders)
{
object c;
try { c = Activator.CreateInstance(certT, new object[] { der }); } catch (Exception) { continue; }
if ((bool)contains.Invoke(have, new[] { c })) continue;
try { import.Invoke(store, new[] { c }); added++; } catch (Exception) { }
}
if (added == 0 && Directory.Exists(trustDir))
{
var f = Directory.GetFiles(trustDir).FirstOrDefault();
if (f != null) File.SetLastWriteTimeUtc(f, DateTime.UtcNow);
}
return added > 0 ? "Discord: put the system's " + added + " trusted certificates into Mono's list (Discord messages need them)" : null;
}
catch (Exception e)
{
var inner = e is TargetInvocationException && e.InnerException != null ? e.InnerException : e;
return "Discord: couldn't fill Mono's certificate list (" + inner.GetType().Name + ": " + inner.Message + ") - Discord messages may fail";
}
}
static List<byte[]> Pem(string text)
{
var list = new List<byte[]>();
const string begin = "-----BEGIN CERTIFICATE-----", end = "-----END CERTIFICATE-----";
int i = 0;
while ((i = text.IndexOf(begin, i, StringComparison.Ordinal)) >= 0)
{
int j = text.IndexOf(end, i, StringComparison.Ordinal);
if (j < 0) break;
string b64 = text.Substring(i + begin.Length, j - i - begin.Length);
try { list.Add(Convert.FromBase64String(new string(b64.Where(ch => !char.IsWhiteSpace(ch)).ToArray()))); } catch (FormatException) { }
i = j + end.Length;
}
return list;
}
}
}