(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / tools / security / StrongNameManager.cs
blobe47b6b83de70d5a42f1a017f987063f1df9147d8
1 //
2 // StrongNameManager.cs - StrongName Management
3 //
4 // Author:
5 // Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2004 Novell (http://www.novell.com)
8 //
10 using System;
11 using System.Collections;
12 using System.Globalization;
13 using System.IO;
14 using System.Reflection;
15 using System.Security;
16 using System.Security.Cryptography;
17 using System.Text;
19 using Mono.Security.Cryptography;
20 using Mono.Xml;
22 namespace Mono.Security {
24 /* RUNTIME
25 * yes
26 * in_gac ---------------------------------\
27 * | |
28 * | no \/
29 * | return true
30 * CLASS LIBRARY|
31 * |
32 * |
33 * |
34 * bool StrongNameManager.MustVerify
35 * |
36 * |
37 * \/ not found
38 * Token --------------------------\
39 * | |
40 * | present ? |
41 * | |
42 * \/ not found |
43 * Assembly Name --------------------------|
44 * | |
45 * | present ? |
46 * | or "*" |
47 * \/ not found |
48 * User ---------------------------|
49 * | |
50 * | present ? |
51 * | or "*" |
52 * \/ \/
53 * return false return true
54 * SKIP VERIFICATION VERIFY ASSEMBLY
57 internal class StrongNameManager {
59 private class Element {
60 internal Hashtable assemblies;
62 public Element ()
64 assemblies = new Hashtable ();
67 public Element (string assembly, string users) : this ()
69 assemblies.Add (assembly, users);
72 public string GetUsers (string assembly)
74 return (string) assemblies [assembly];
78 static private Hashtable mappings;
79 static private Hashtable tokens;
81 static StrongNameManager ()
85 // note: more than one configuration file can be loaded at the
86 // same time (e.g. user specific and machine specific config).
87 static public void LoadConfig (string filename)
89 if (File.Exists (filename)) {
90 SecurityParser sp = new SecurityParser ();
91 using (StreamReader sr = new StreamReader (filename)) {
92 string xml = sr.ReadToEnd ();
93 sp.LoadXml (xml);
95 SecurityElement root = sp.ToXml ();
96 if ((root != null) && (root.Tag == "configuration")) {
97 SecurityElement strongnames = root.SearchForChildByTag ("strongNames");
98 if ((strongnames != null) && (strongnames.Children.Count > 0)) {
99 SecurityElement mapping = strongnames.SearchForChildByTag ("pubTokenMapping");
100 if ((mapping != null) && (mapping.Children.Count > 0)) {
101 LoadMapping (mapping);
104 SecurityElement settings = strongnames.SearchForChildByTag ("verificationSettings");
105 if ((settings != null) && (settings.Children.Count > 0)) {
106 LoadVerificationSettings (settings);
113 static private void LoadMapping (SecurityElement mapping)
115 if (mappings == null) {
116 mappings = new Hashtable ();
119 lock (mappings.SyncRoot) {
120 foreach (SecurityElement item in mapping.Children) {
121 if (item.Tag != "map")
122 continue;
124 string token = item.Attribute ("Token");
125 if ((token == null) || (token.Length != 16))
126 continue; // invalid entry
127 token = token.ToUpper (CultureInfo.InvariantCulture);
129 string publicKey = item.Attribute ("PublicKey");
130 if (publicKey == null)
131 continue; // invalid entry
133 // watch for duplicate entries
134 if (mappings [token] == null) {
135 mappings.Add (token, publicKey);
137 else {
138 // replace existing mapping
139 mappings [token] = publicKey;
145 static private void LoadVerificationSettings (SecurityElement settings)
147 if (tokens == null) {
148 tokens = new Hashtable ();
151 lock (tokens.SyncRoot) {
152 foreach (SecurityElement item in settings.Children) {
153 if (item.Tag != "skip")
154 continue;
156 string token = item.Attribute ("Token");
157 if (token == null)
158 continue; // bad entry
159 token = token.ToUpper (CultureInfo.InvariantCulture);
161 string assembly = item.Attribute ("Assembly");
162 if (assembly == null)
163 assembly = "*";
165 string users = item.Attribute ("Users");
166 if (users == null)
167 users = "*";
169 Element el = (Element) tokens [token];
170 if (el == null) {
171 // new token
172 el = new Element (assembly, users);
173 tokens.Add (token, el);
174 continue;
177 // existing token
178 string a = (string) el.assemblies [assembly];
179 if (a == null) {
180 // new assembly
181 el.assemblies.Add (assembly, users);
182 continue;
185 // existing assembly
186 if (users == "*") {
187 // all users (drop current users)
188 el.assemblies [assembly] = "*";
189 continue;
192 // new users, add to existing
193 string existing = (string) el.assemblies [assembly];
194 string newusers = String.Concat (existing, ",", users);
195 el.assemblies [assembly] = newusers;
200 static public byte[] GetMappedPublicKey (byte[] token)
202 if ((mappings == null) || (token == null))
203 return null;
205 string t = CryptoConvert.ToHex (token);
206 string pk = (string) mappings [t];
207 if (pk == null)
208 return null;
210 return CryptoConvert.FromHex (pk);
213 // it is possible to skip verification for assemblies
214 // or a strongname public key using the "sn" tool.
215 // note: only the runtime checks if the assembly is loaded
216 // from the GAC to skip verification
217 static public bool MustVerify (AssemblyName an)
219 if ((an == null) || (tokens == null))
220 return true;
222 string token = CryptoConvert.ToHex (an.GetPublicKeyToken ());
223 Element el = (Element) tokens [token];
224 if (el != null) {
225 // look for this specific assembly first
226 string users = el.GetUsers (an.Name);
227 if (users == null) {
228 // nothing for the specific assembly
229 // so look for "*" assembly
230 users = el.GetUsers ("*");
233 if (users != null) {
234 // applicable to any user ?
235 if (users == "*")
236 return false;
237 // applicable to the current user ?
238 return (users.IndexOf (Environment.UserName) < 0);
242 // we must check verify the strongname on the assembly
243 return true;
246 public override string ToString ()
248 StringBuilder sb = new StringBuilder ();
249 sb.Append ("Public Key Token\tAssemblies\t\tUsers");
250 sb.Append (Environment.NewLine);
251 if (tokens == null) {
252 sb.Append ("none");
253 return sb.ToString ();
256 foreach (DictionaryEntry token in tokens) {
257 sb.Append ((string)token.Key);
258 Element t = (Element) token.Value;
259 bool first = true;
260 foreach (DictionaryEntry assembly in t.assemblies) {
261 if (first) {
262 sb.Append ("\t");
263 first = false;
265 else {
266 sb.Append ("\t\t\t");
268 sb.Append ((string)assembly.Key);
269 sb.Append ("\t");
270 string users = (string)assembly.Value;
271 if (users == "*")
272 users = "All users";
273 sb.Append (users);
274 sb.Append (Environment.NewLine);
277 return sb.ToString ();