Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

security system #212

Merged
merged 80 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
75c22f1
Initial security
Bod9001 Aug 2, 2023
a5a807e
White list jusst for a backup
Bod9001 Aug 2, 2023
5033973
Most of the easy stuff
Bod9001 Aug 3, 2023
4d25da2
Tweaking
Bod9001 Aug 10, 2023
8fccf9c
Dialogue box
Bod9001 Aug 17, 2023
679be7b
better dialogue
Bod9001 Aug 17, 2023
200f95d
try ccatch
Bod9001 Aug 18, 2023
72ce35d
The first passsinng ssecuurity
Bod9001 Sep 6, 2023
502095d
First working scan
Bod9001 Sep 12, 2023
b09f862
cleaning up
Bod9001 Sep 13, 2023
aa406e9
To do is
Bod9001 Sep 14, 2023
51ceeeb
Moved some stuff into Interfaces
Bod9001 Sep 14, 2023
feb1727
File service
Bod9001 Sep 15, 2023
2ffe3ad
Merge branch 'develop' into SecuritySystem
Bod9001 Sep 15, 2023
1efa52f
ooops
Bod9001 Sep 15, 2023
0adc222
zero warnings
Bod9001 Sep 15, 2023
e5c3e66
Verssion bump
Bod9001 Sep 15, 2023
9eda5b9
Naming
Bod9001 Sep 15, 2023
9987552
no Newtonsoft.Json
Bod9001 Sep 15, 2023
ad5e56b
codacy channges
Bod9001 Sep 16, 2023
fa0ed65
Passing Fix
Bod9001 Sep 20, 2023
5c4af51
No eerrors
Bod9001 Sep 20, 2023
0f053a8
version bump
Bod9001 Sep 20, 2023
06143d7
formattting?
Bod9001 Sep 20, 2023
f3a605e
Formmattingg?
Bod9001 Sep 20, 2023
81741b4
ssplit
Bod9001 Sep 20, 2023
9954c1f
more splitting and fix
Bod9001 Sep 20, 2023
a8af9be
formatting
Bod9001 Sep 20, 2023
45d59a6
changges
Bod9001 Sep 20, 2023
56c9e7f
weird code
Bod9001 Sep 20, 2023
0130459
fix tthe errors
Bod9001 Sep 20, 2023
1df4a2c
spacing
Bod9001 Sep 20, 2023
66aa382
no gotos
Bod9001 Sep 20, 2023
1118d57
spacing
Bod9001 Sep 20, 2023
96806a7
Improvemennts
Bod9001 Sep 20, 2023
085d8b2
Comment
Bod9001 Sep 20, 2023
d0fb590
A puush
Bod9001 Sep 28, 2023
c0f8cc5
debug
Bod9001 Sep 28, 2023
883befd
win
Bod9001 Sep 28, 2023
62cac89
win to max
Bod9001 Sep 28, 2023
710f6bb
remove
Bod9001 Sep 28, 2023
21b4abd
config
Bod9001 Sep 28, 2023
bbdf78f
Works for windows
Bod9001 Sep 29, 2023
c680510
mac? And Linux funcctionality
Bod9001 Sep 30, 2023
c915303
Automatic run of pipe
Bod9001 Oct 1, 2023
48910ac
Cleaning up
Bod9001 Oct 3, 2023
b7fbda3
Requested changes
Bod9001 Oct 3, 2023
430b6f3
spacing
Bod9001 Oct 3, 2023
e706d7f
Assembly name
Bod9001 Oct 13, 2023
5f0cb0a
some requested changes
Bod9001 Oct 25, 2023
3ce49d2
fixes
Bod9001 Oct 25, 2023
1114583
Coda see changes
Bod9001 Oct 25, 2023
68a3a30
cleaaning up
Bod9001 Oct 25, 2023
26aed81
moree cleaaninng
Bod9001 Oct 25, 2023
d973c04
cleaning cleaning ccleaaninng
Bod9001 Oct 25, 2023
efa9672
http's
Bod9001 Oct 25, 2023
77f0c26
docs
Bod9001 Oct 26, 2023
0393d3f
Whiteespace?
Bod9001 Oct 29, 2023
2e24de5
whitespace changes
Bod9001 Oct 29, 2023
96a2534
logs
Bod9001 Oct 30, 2023
3977b06
whyyyy
Bod9001 Oct 30, 2023
da4c95b
fixes
Bod9001 Oct 30, 2023
38721e2
logErroors
Bod9001 Oct 31, 2023
0c8e166
Whitespacee changes
Bod9001 Nov 3, 2023
66cb750
Linux fix
Bod9001 Nov 3, 2023
2446e16
log
Bod9001 Nov 4, 2023
90d91a9
logs
Bod9001 Nov 5, 2023
3f1d12d
mac fix
Bod9001 Nov 6, 2023
af77780
Moree / shennanigans
Bod9001 Nov 6, 2023
76b04e7
Evenn more \
Bod9001 Nov 6, 2023
7d64a5c
yay mac is stupid
Bod9001 Nov 10, 2023
5e4ba3b
.app
Bod9001 Nov 10, 2023
c416ee4
AnyURL
Bod9001 Nov 11, 2023
e1d76db
move to Installation path
Bod9001 Nov 12, 2023
f34c07b
format
Bod9001 Nov 12, 2023
b7a969c
warnings
Bod9001 Nov 12, 2023
afa02a7
flatpack fix
Bod9001 Nov 18, 2023
86f974d
format
Bod9001 Nov 19, 2023
9f92179
try catch
Bod9001 Nov 19, 2023
4102898
Cleanup of security scanning services (#221)
CorruptComputer Nov 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPublishable>false</IsPublishable>
Expand Down
90 changes: 90 additions & 0 deletions UnitystationLauncher/ContentScanning/AssemblyTypeChecker.Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ILVerify;
using Newtonsoft.Json;
using Pidgin;

namespace UnitystationLauncher.ContentScanning;

internal sealed partial class AssemblyTypeChecker
{
private static string pathToconfig = @"Q:\Fast programmes\DevStationHub\allowed.json"; //TODO!!!

private static SandboxConfig LoadConfig()
{
using (StreamReader file = File.OpenText(pathToconfig))
Bod9001 marked this conversation as resolved.
Show resolved Hide resolved
{
JsonSerializer serializer = new JsonSerializer();
var data = (SandboxConfig) serializer.Deserialize(file, typeof(SandboxConfig));
foreach (var Namespace in data.Types)
{
foreach (var Class in Namespace.Value)
{
ParseTypeConfig(Class.Value);
}
}

return data;
}
}

private static void ParseTypeConfig(TypeConfig cfg)
{
if (cfg.Methods != null)
{
var list = new List<WhitelistMethodDefine>();
foreach (var m in cfg.Methods)
{
try
{
list.Add(MethodParser.ParseOrThrow(m));
}
catch (ParseException e)
{
Console.WriteLine("oh no..");
// sawmill.Error($"Parse exception for '{m}': {e}");
}
}

cfg.MethodsParsed = list.ToArray();
}
else
{
cfg.MethodsParsed = Array.Empty<WhitelistMethodDefine>();
}

if (cfg.Fields != null)
{
var list = new List<WhitelistFieldDefine>();
foreach (var f in cfg.Fields)
{
// try
// {
list.Add(FieldParser.ParseOrThrow(f));
// }
// catch (ParseException e)
// {
// //sawmill.Error($"Parse exception for '{f}': {e}");
//
// }
}

cfg.FieldsParsed = list.ToArray();
}
else
{
cfg.FieldsParsed = Array.Empty<WhitelistFieldDefine>();
}

if (cfg.NestedTypes != null)
{
foreach (var nested in cfg.NestedTypes.Values)
{
ParseTypeConfig(nested);
}
}
}
}
85 changes: 85 additions & 0 deletions UnitystationLauncher/ContentScanning/AssemblyTypeChecker.Dump.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Internal.TypeSystem.Ecma;

namespace UnitystationLauncher.ContentScanning;

internal sealed partial class AssemblyTypeChecker
{
public static IEnumerable<string> DumpMetaMembers(Type type)
{
var assemblyLoc = type.Assembly.Location;

// Load assembly with System.Reflection.Metadata.
using var fs = File.OpenRead(assemblyLoc);
using var peReader = new PEReader(fs);

var metaReader = peReader.GetMetadataReader();

// Find type definition in raw assembly metadata.
// Is there a better way to do this than iterating??
TypeDefinition typeDef = default;
var found = false;
foreach (var typeDefHandle in metaReader.TypeDefinitions)
{
var tempTypeDef = metaReader.GetTypeDefinition(typeDefHandle);
var name = metaReader.GetString(tempTypeDef.Name);
var @namespace = NilNullString(metaReader, tempTypeDef.Namespace);
if (name == type.Name && @namespace == type.Namespace)
{
typeDef = tempTypeDef;
found = true;
break;
}
}

if (!found)
{
throw new InvalidOperationException("Type didn't exist??");
}

// Dump the list.
var provider = new TypeProvider();

foreach (var fieldHandle in typeDef.GetFields())
{
var fieldDef = metaReader.GetFieldDefinition(fieldHandle);

if ((fieldDef.Attributes & FieldAttributes.FieldAccessMask) != FieldAttributes.Public)
{
continue;
}

var fieldName = metaReader.GetString(fieldDef.Name);
var fieldType = fieldDef.DecodeSignature(provider, 0);

yield return $"{fieldType.WhitelistToString()} {fieldName}";
}

foreach (var methodHandle in typeDef.GetMethods())
{
var methodDef = metaReader.GetMethodDefinition(methodHandle);

if (!methodDef.Attributes.IsPublic())
{
continue;
}

var methodName = metaReader.GetString(methodDef.Name);
var methodSig = methodDef.DecodeSignature(provider, 0);

var paramString = string.Join(", ", methodSig.ParameterTypes.Select(t => t.WhitelistToString()));
var genericCount = methodSig.GenericParameterCount;
var typeParamString = genericCount == 0
? ""
: $"<{new string(',', genericCount - 1)}>";

yield return $"{methodSig.ReturnType.WhitelistToString()} {methodName}{typeParamString}({paramString})";
}
}
}
177 changes: 177 additions & 0 deletions UnitystationLauncher/ContentScanning/AssemblyTypeChecker.Parsing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Reflection.Metadata;
using Pidgin;
using static Pidgin.Parser;
using static Pidgin.Parser<char>;

namespace UnitystationLauncher.ContentScanning;

internal sealed partial class AssemblyTypeChecker
{
// Contains primary parsing code for method and field declarations in the sandbox whitelist.

private static readonly Parser<char, PrimitiveTypeCode> VoidTypeParser =
String("void").ThenReturn(PrimitiveTypeCode.Void);

private static readonly Parser<char, PrimitiveTypeCode> BooleanTypeParser =
String("bool").ThenReturn(PrimitiveTypeCode.Boolean);

private static readonly Parser<char, PrimitiveTypeCode> CharTypeParser =
String("char").ThenReturn(PrimitiveTypeCode.Char);

private static readonly Parser<char, PrimitiveTypeCode> SByteTypeParser =
String("sbyte").ThenReturn(PrimitiveTypeCode.SByte);

private static readonly Parser<char, PrimitiveTypeCode> ByteTypeParser =
String("byte").ThenReturn(PrimitiveTypeCode.Byte);

private static readonly Parser<char, PrimitiveTypeCode> Int16TypeParser =
String("short").ThenReturn(PrimitiveTypeCode.Int16);

private static readonly Parser<char, PrimitiveTypeCode> UInt16TypeParser =
String("ushort").ThenReturn(PrimitiveTypeCode.UInt32);

private static readonly Parser<char, PrimitiveTypeCode> Int32TypeParser =
String("int").ThenReturn(PrimitiveTypeCode.Int32);

private static readonly Parser<char, PrimitiveTypeCode> UInt32TypeParser =
String("uint").ThenReturn(PrimitiveTypeCode.UInt32);

private static readonly Parser<char, PrimitiveTypeCode> Int64TypeParser =
String("long").ThenReturn(PrimitiveTypeCode.Int64);

private static readonly Parser<char, PrimitiveTypeCode> UInt64TypeParser =
String("ulong").ThenReturn(PrimitiveTypeCode.UInt64);

private static readonly Parser<char, PrimitiveTypeCode> IntPtrTypeParser =
String("nint").ThenReturn(PrimitiveTypeCode.IntPtr);

private static readonly Parser<char, PrimitiveTypeCode> UIntPtrTypeParser =
String("nuint").ThenReturn(PrimitiveTypeCode.UIntPtr);

private static readonly Parser<char, PrimitiveTypeCode> SingleTypeParser =
String("float").ThenReturn(PrimitiveTypeCode.Single);

private static readonly Parser<char, PrimitiveTypeCode> DoubleTypeParser =
String("double").ThenReturn(PrimitiveTypeCode.Double);

private static readonly Parser<char, PrimitiveTypeCode> StringTypeParser =
String("string").ThenReturn(PrimitiveTypeCode.String);

private static readonly Parser<char, PrimitiveTypeCode> ObjectTypeParser =
String("object").ThenReturn(PrimitiveTypeCode.Object);

private static readonly Parser<char, PrimitiveTypeCode> TypedReferenceTypeParser =
String("typedref").ThenReturn(PrimitiveTypeCode.TypedReference);

private static readonly Parser<char, MType> PrimitiveTypeParser =
OneOf(
Try(VoidTypeParser),
Try(BooleanTypeParser),
Try(CharTypeParser),
Try(SByteTypeParser),
Try(ByteTypeParser),
Try(Int16TypeParser),
Try(UInt16TypeParser),
Try(Int32TypeParser),
Try(UInt32TypeParser),
Try(Int64TypeParser),
Try(UInt64TypeParser),
Try(IntPtrTypeParser),
Try(UIntPtrTypeParser),
Try(SingleTypeParser),
Try(DoubleTypeParser),
Try(StringTypeParser),
Try(ObjectTypeParser),
TypedReferenceTypeParser)
.Select(code => (MType) new MTypePrimitive(code)).Labelled("Primitive type");

private static readonly Parser<char, string> NamespacedIdentifier =
Token(c => char.IsLetterOrDigit(c) || c == '.' || c == '_' || c == '`')
.AtLeastOnceString()
.Labelled("valid identifier");

private static readonly Parser<char, IEnumerable<MType>> GenericParametersParser =
Rec(() => MaybeArrayTypeParser!)
.Between(SkipWhitespaces)
.Separated(Char(','))
.Between(Char('<'), Char('>'));

private static readonly Parser<char, MType> GenericMethodPlaceholderParser =
String("!!")
.Then(Digit.AtLeastOnceString())
.Select(p => (MType) new MTypeGenericMethodPlaceHolder(int.Parse(p, CultureInfo.InvariantCulture)));

private static readonly Parser<char, MType> GenericTypePlaceholderParser =
String("!")
.Then(Digit.AtLeastOnceString())
.Select(p => (MType) new MTypeGenericTypePlaceHolder(int.Parse(p, CultureInfo.InvariantCulture)));

private static readonly Parser<char, MType> GenericPlaceholderParser = Try(GenericTypePlaceholderParser)
.Or(Try(GenericMethodPlaceholderParser)).Labelled("Generic placeholder");

private static readonly Parser<char, MTypeParsed> TypeNameParser =
Parser.Map(
(a, b) => b.Aggregate(new MTypeParsed(a), (parsed, s) => new MTypeParsed(s, parsed)),
NamespacedIdentifier,
Char('/').Then(NamespacedIdentifier).Many());

private static readonly Parser<char, MType> ConstructedObjectTypeParser =
Parser.Map((arg1, arg2) =>
{
MType type = arg1;
if (arg2.HasValue)
{
type = new MTypeGeneric(type, arg2.Value.ToImmutableArray());
}

return type;
},
TypeNameParser,
GenericParametersParser.Optional());

private static readonly Parser<char, MType> MaybeArrayTypeParser = Parser.Map(
(a, b) => b.Aggregate(a, (type, _) => new MTypeSZArray(type)),
Try(GenericPlaceholderParser).Or(Try(PrimitiveTypeParser)).Or(ConstructedObjectTypeParser),
String("[]").Many());

private static readonly Parser<char, MType> ByRefTypeParser =
String("ref")
.Then(SkipWhitespaces)
.Then(MaybeArrayTypeParser)
.Select(t => (MType) new MTypeByRef(t))
.Labelled("ByRef type");

private static readonly Parser<char, MType> TypeParser = Try(ByRefTypeParser).Or(MaybeArrayTypeParser);

private static readonly Parser<char, ImmutableArray<MType>> MethodParamsParser =
TypeParser
.Between(SkipWhitespaces)
.Separated(Char(','))
.Between(Char('('), Char(')'))
.Select(p => p.ToImmutableArray());

internal static readonly Parser<char, int> MethodGenericParameterCountParser =
Try(Char(',').Many().Select(p => p.Count() + 1).Between(Char('<'), Char('>'))).Or(Return(0));

internal static readonly Parser<char, WhitelistMethodDefine> MethodParser =
Parser.Map(
(a, b, d, c) => new WhitelistMethodDefine(b, a, c.ToList(), d),

SkipWhitespaces.Then(TypeParser),

SkipWhitespaces.Then(NamespacedIdentifier),

MethodGenericParameterCountParser,

SkipWhitespaces.Then(MethodParamsParser));

internal static readonly Parser<char, WhitelistFieldDefine> FieldParser = Parser.Map(
(a, b) => new WhitelistFieldDefine(b, a),
MaybeArrayTypeParser.Between(SkipWhitespaces),
NamespacedIdentifier);

}
Loading