Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Assert.cs
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.IO;
5using System.Reflection;
6using System.Text.RegularExpressions;
7using Waher.Events;
8
10{
14 public static class Assert
15 {
20 public static void CallFromAssembly(params Assembly[] Assemblies)
21 {
22 AssertSource(Assemblies);
23 }
24
29 public static void CallFromClass(params Type[] Classes)
30 {
31 AssertSource(Classes);
32 }
33
39 public static void CallFromSource(params string[] Sources)
40 {
41 AssertSource(Sources);
42 }
43
49 public static void CallFromSource(params Regex[] Sources)
50 {
51 AssertSource(Sources);
52 }
53
59 public static void CallFromSource(params object[] Sources)
60 {
61 AssertSource(Sources);
62 }
63
69 private static void AssertSource(params object[] Sources)
70 {
71 StackFrame Frame;
72 MethodBase Method;
73 Type Type;
74 Assembly Assembly;
75 string TypeName;
76 string AssemblyName;
77 int Skip = 1;
78 bool WaherPersistence = false;
79 bool AsynchTask = false;
80 bool Other = false;
81
82 while (true)
83 {
84 Frame = new StackFrame(Skip);
85 Method = Frame.GetMethod();
86 if (Method is null)
87 break;
88
89 Type = Method.DeclaringType;
90 if (Type != typeof(Assert))
91 break;
92
93 Skip++;
94 }
95
96 int Caller = Skip;
97
98 while (true)
99 {
100 Frame = new StackFrame(Skip++);
101 Method = Frame.GetMethod();
102 if (Method is null)
103 break;
104
105 Type = Method.DeclaringType;
106 TypeName = Type.FullName;
107 Assembly = Type.Assembly;
108 AssemblyName = Assembly.GetName().Name;
109
110 foreach (object Source in Sources)
111 {
112 if (Source is Assembly A)
113 {
114 if (A == Assembly)
115 return;
116 }
117 else if (Source is Type T)
118 {
119 if (T == Type)
120 return;
121 }
122 else if (Source is Regex Regex)
123 {
124 if (IsMatch(Regex, TypeName + "." + Method.Name) ||
125 IsMatch(Regex, TypeName) ||
126 IsMatch(Regex, AssemblyName))
127 {
128 return;
129 }
130 }
131 else if (Source is string s)
132 {
133 if (TypeName + "." + Method.Name == s ||
134 TypeName == s ||
135 AssemblyName == s)
136 {
137 return;
138 }
139 }
140 }
141
142 if (!Other || !AsynchTask || !WaherPersistence)
143 {
144 if (string.IsNullOrEmpty(Assembly.Location))
145 {
146 if (AssemblyName.StartsWith("WPSA."))
147 WaherPersistence = true;
148 else
149 Other = true;
150 }
151 else
152 {
153 if (Type == typeof(System.Threading.Tasks.Task))
154 AsynchTask = true;
155 else if (TypeName.StartsWith(AssemblyName) &&
156 AssemblyName + "." == Path.ChangeExtension(Path.GetFileName(Assembly.Location), string.Empty))
157 {
158 if (AssemblyName.StartsWith("Waher.Persistence."))
159 WaherPersistence = true;
160 else if (!AssemblyName.StartsWith("Waher.") && !AssemblyName.StartsWith("System."))
161 Other = true;
162 }
163 else if (!Path.GetFileName(Assembly.Location).StartsWith("System."))
164 Other = true;
165 }
166 }
167 }
168
169 if (AsynchTask && WaherPersistence && !Other)
170 return; // In asynch call - stack trace not showing asynchronous call stack. If loading from database, i.e. populating object asynchronously, (possibly, check is vulnerable), give check a pass. Access will be restricted at a later stage, when accessing properties synchronously.
171
172 Frame = new StackFrame(Skip = Caller);
173 Method = Frame.GetMethod();
174 Type = Method.DeclaringType;
175 Assembly = Type.Assembly;
176
177 string ObjectId = Type.FullName + "." + Method.Name;
178 StackTrace Trace = new StackTrace(Skip, false);
179 UnauthorizedAccessEventArgs e = new UnauthorizedAccessEventArgs(Method, Type, Assembly, Trace);
180 List<KeyValuePair<string, object>> Tags = new List<KeyValuePair<string, object>>()
181 {
182 new KeyValuePair<string, object>("Method", Method.Name),
183 new KeyValuePair<string, object>("Type", Type.FullName),
184 new KeyValuePair<string, object>("Assembly", Assembly.FullName)
185 };
186
187 Skip = 0;
188 while (true)
189 {
190 Frame = new StackFrame(Skip);
191 Method = Frame.GetMethod();
192 if (Method is null)
193 break;
194
195 Type = Method.DeclaringType;
196 TypeName = Type.FullName;
197 Assembly = Type.Assembly;
198 AssemblyName = Assembly.GetName().Name;
199
200 Tags.Add(new KeyValuePair<string, object>("Pos" + Skip.ToString(), Assembly.GetName().Name + ", " + TypeName + ", " + Method.Name));
201
202 Skip++;
203 }
204
205 Log.Warning("Unauthorized access detected and prevented.", ObjectId, string.Empty, "UnauthorizedAccess", EventLevel.Major,
206 string.Empty, Assembly.FullName, Trace.ToString(), Tags.ToArray());
207
209 if (!(h is null))
210 {
211 try
212 {
213 h(null, e);
214 }
215 catch (Exception ex)
216 {
217 Log.Exception(ex);
218 }
219 }
220
221 throw new UnauthorizedCallstackException("Unauthorized access.");
222 }
223
224 private static bool IsMatch(Regex Regex, string s)
225 {
226 Match M = Regex.Match(s);
227 return M.Success && M.Index == 0 && M.Length == s.Length;
228 }
229
234
235 }
236}
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
Definition: Log.cs:566
Static class containing methods that can be used to make sure calls are made from appropriate locatio...
Definition: Assert.cs:15
static void CallFromSource(params Regex[] Sources)
Makes sure the call is made from one of the listed sources.
Definition: Assert.cs:49
static UnauthorizedAccessEventHandler UnauthorizedAccess
Event raised when an unauthorized access has been detected.
Definition: Assert.cs:233
static void CallFromSource(params string[] Sources)
Makes sure the call is made from one of the listed sources.
Definition: Assert.cs:39
static void CallFromClass(params Type[] Classes)
Makes sure the call is made from one of the listed classes.
Definition: Assert.cs:29
static void CallFromSource(params object[] Sources)
Makes sure the call is made from one of the listed sources.
Definition: Assert.cs:59
static void CallFromAssembly(params Assembly[] Assemblies)
Makes sure the call is made from one of the listed assemblies.
Definition: Assert.cs:20
EventLevel
Event level.
Definition: EventLevel.cs:7
delegate void UnauthorizedAccessEventHandler(object Sender, UnauthorizedAccessEventArgs e)
Delegate for unauthorized access event handlers.