2 using System
.Collections
.Generic
;
4 using System
.Reflection
;
7 using Mono
.Configuration
.Crypto
;
9 [assembly
: AssemblyTitle ("mono-configuration-crypto")]
10 [assembly
: AssemblyDescription ("Mono configuration utility to manage encryption keys and encrypt/decrypt config file sections")]
11 [assembly
: AssemblyCompany (Consts
.MonoCompany
)]
12 [assembly
: AssemblyProduct ("Mono Configuration Cryptography Tools")]
13 [assembly
: AssemblyCopyright ("Copyright (c) 2010 Novell, Inc (http://novell.com, http://mono-project.com/)")]
14 [assembly
: AssemblyVersion (Consts
.FxVersion
)]
16 namespace MonoConfigurationCrypto
18 class MonoConfigurationCrypto
22 Console
.WriteLine ("Success.");
25 void Failure (Exception ex
, Config cfg
)
27 Failure (ex
, cfg
, null);
30 void Failure (Config cfg
, string message
, params object[] parms
)
32 Failure (null, cfg
, message
, parms
);
35 void Failure (Exception ex
, Config cfg
, string message
, params object[] parms
)
37 if (!String
.IsNullOrEmpty (message
)) {
38 if (parms
== null || parms
.Length
== 0)
39 Console
.Error
.WriteLine (message
);
41 Console
.Error
.WriteLine (message
, parms
);
46 Console
.Error
.WriteLine (ex
.ToString ());
48 Console
.Error
.WriteLine (ex
.Message
);
50 Console
.Error
.WriteLine ("Failure.");
53 bool ListContainers (Config cfg
)
56 var kc
= new KeyContainerCollection (cfg
.UseMachinePath
);
58 foreach (KeyContainer c
in kc
) {
60 Console
.WriteLine ("{0} container '{1}' ({2} key{3})", c
.Local
? "Local" : "Global", c
.Name
, count
,
61 count
== 1 ? String
.Empty
: "s");
63 } catch (Exception ex
) {
70 string FindConfigFile (string path
, string configFileName
)
72 if (!Directory
.Exists (path
))
75 string fileName
= null;
76 foreach (var s
in Directory
.GetFiles (path
, "*.*", SearchOption
.TopDirectoryOnly
)) {
77 string fn
= Path
.GetFileName (s
);
78 if (String
.Compare (fn
, configFileName
, StringComparison
.OrdinalIgnoreCase
) == 0) {
87 return Path
.Combine (path
, fileName
);
90 bool EncryptSection (Config cfg
)
92 string configSection
= cfg
.ConfigSectionName
;
93 string containerName
= cfg
.ContainerName
;
94 string configFile
= FindConfigFile (cfg
.ApplicationPhysicalPath
, cfg
.ConfigFileName
);
96 Console
.WriteLine ("Encrypting section '{0}' in config file '{1}' using key container '{2}'...", configSection
, configFile
, containerName
);
98 if (String
.IsNullOrEmpty (configFile
)) {
99 Failure (cfg
, "No config file found in directory '{0}'", cfg
.ApplicationPhysicalPath
);
103 if (String
.IsNullOrEmpty (configSection
)) {
104 Failure (cfg
, "No config section name specified.");
109 var cs
= new ConfigSection ();
110 cs
.Encrypt (configFile
, configSection
, containerName
, cfg
.UseMachinePath
);
111 Console
.WriteLine ("Success.");
112 } catch (Exception ex
) {
120 bool DecryptSection (Config cfg
)
122 string configSection
= cfg
.ConfigSectionName
;
123 string containerName
= cfg
.ContainerName
;
124 string configFile
= FindConfigFile (cfg
.ApplicationPhysicalPath
, cfg
.ConfigFileName
);
126 Console
.WriteLine ("Decrypting section '{0}' in config file '{1}' using key container '{2}'...", configSection
, configFile
, containerName
);
128 if (String
.IsNullOrEmpty (configFile
)) {
129 Failure (cfg
, "No config file found in directory '{0}'", cfg
.ApplicationPhysicalPath
);
133 if (String
.IsNullOrEmpty (configSection
)) {
134 Failure (cfg
, "No config section name specified.");
139 var cs
= new ConfigSection ();
140 cs
.Decrypt (configFile
, configSection
, containerName
, cfg
.UseMachinePath
);
141 Console
.WriteLine ("Success.");
142 } catch (Exception ex
) {
150 bool CreateKey (Config cfg
)
152 string name
= cfg
.ContainerName
;
153 KeyContainerCollection kc
;
155 Console
.WriteLine ("Creating RSA key container '{0}'...", name
);
157 kc
= new KeyContainerCollection (cfg
.UseMachinePath
);
158 if (kc
.Contains (name
)) {
159 Failure (cfg
, "The RSA container already exists.");
163 var k
= new Key (name
, cfg
.KeySize
, cfg
.UseMachinePath
);
165 Failure (cfg
, "Failed to generate RSA key pair.");
170 } catch (Exception ex
) {
178 bool ImportKey (Config cfg
)
180 string containerName
= cfg
.ContainerName
;
181 string fileName
= cfg
.FileName
;
183 Console
.WriteLine ("Importing an RSA key from file '{0}' into the container '{1}'...", fileName
, containerName
);
184 if (String
.IsNullOrEmpty (containerName
)) {
185 Failure (cfg
, "Unspecified container name.");
189 if (String
.IsNullOrEmpty (fileName
)) {
190 Failure (cfg
, "Unspecified file name.");
194 if (!File
.Exists (fileName
)) {
195 Failure (cfg
, "Key file '{0}' does not exist.", fileName
);
199 KeyContainerCollection kcc
;
203 kcc
= new KeyContainerCollection (cfg
.UseMachinePath
);
204 kc
= kcc
[containerName
];
211 // No validation is performed on the key - this is left for the
212 // encryption algorithm implementation to do.
213 string keyvalue
= File
.ReadAllText (fileName
);
215 key
= new Key (containerName
, keyvalue
, cfg
.UseMachinePath
);
217 key
.KeyValue
= keyvalue
;
218 key
.ContainerName
= containerName
;
222 Console
.WriteLine ("Success.");
223 } catch (Exception ex
) {
231 bool ExportKey (Config cfg
)
233 string containerName
= cfg
.ContainerName
;
234 string fileName
= cfg
.FileName
;
236 Console
.WriteLine ("Exporting an RSA key from container '{0}' to file '{1}'...", containerName
, fileName
);
237 if (String
.IsNullOrEmpty (containerName
)) {
238 Failure (cfg
, "Unspecified container name.");
242 if (String
.IsNullOrEmpty (fileName
)) {
243 Failure (cfg
, "Unspecified file name.");
247 KeyContainerCollection kcc
;
251 kcc
= new KeyContainerCollection (cfg
.UseMachinePath
);
252 kc
= kcc
[containerName
];
257 Failure (cfg
, "Container '{0}' does not exist.", containerName
);
262 Failure (cfg
, "Container '{0}' exists but it does not contain any keys.", containerName
);
266 File
.WriteAllText (fileName
, key
.KeyValue
);
267 Console
.WriteLine ("Success.");
268 } catch (Exception ex
) {
276 bool RemoveContainer (Config cfg
)
278 string containerName
= cfg
.ContainerName
;
279 Console
.WriteLine ("Removing container '{0}'...", containerName
);
280 if (String
.IsNullOrEmpty (containerName
)) {
281 Failure (cfg
, "Unspecified container name.");
286 KeyContainer
.RemoveFromDisk (containerName
, cfg
.UseMachinePath
);
288 Console
.WriteLine ("Success.");
289 } catch (Exception ex
) {
299 string title
= String
.Empty
, version
= String
.Empty
, description
= String
.Empty
, copyright
= String
.Empty
;
300 Assembly asm
= Assembly
.GetExecutingAssembly ();
301 foreach (object o
in asm
.GetCustomAttributes (false)) {
302 if (o
is AssemblyTitleAttribute
)
303 title
= ((AssemblyTitleAttribute
)o
).Title
;
304 else if (o
is AssemblyCopyrightAttribute
)
305 copyright
= ((AssemblyCopyrightAttribute
)o
).Copyright
;
306 else if (o
is AssemblyDescriptionAttribute
)
307 description
= ((AssemblyDescriptionAttribute
)o
).Description
;
310 version
= asm
.GetName ().Version
.ToString ();
312 Console
.WriteLine ("{1} - version {2}{0}{3}{0}{4}{0}",
320 void Run (string[] args
)
322 var cfg
= new Config ();
323 var actions
= new List
<Func
<Config
, bool>> ();
324 var options
= new OptionSet () {
325 { "h|?|help", "Show usage information", v => cfg.ShowHelp = true }
,
326 { "v|verbose", "Show verbose information (including exception stacktraces)", v => cfg.Verbose = true }
,
327 { "m|machine|global", "Use machine (global) store for all the key actions", v => cfg.UseMachinePath = true }
,
328 { "u|user|local", "Use local (user) store for all the key actions [*]", v => cfg.UseMachinePath = false }
,
329 { "l|list", "List all the key container names in the store", v => actions.Add (ListContainers) }
,
330 { "c|create", "Creates an RSA public/private key pair", v => actions.Add (CreateKey) }
,
331 { "i|import", "Import key to a container", v => actions.Add (ImportKey) }
,
332 { "x|export", "Export key from a container", v => actions.Add (ExportKey) }
,
333 { "r|remove", "Remove a container", v => actions.Add (RemoveContainer) }
,
334 { "f=|file=", "File name for import or export operations", (string s) => cfg.FileName = s }
,
335 { "cf=|config-file=", String.Format ("Config file name (not path) [{0}
]", Config.DefaultConfigFileName), (string s) => cfg.ConfigFileName = s },
336 { "n=|name=", String.Format ("Container name [{0}]", Config
.DefaultContainerName
), (string s
) => cfg
.ContainerName
= s
},
337 { "s=|size=", String.Format ("Key size [{0}
]", Config.DefaultKeySize), (uint s) => cfg.KeySize = s },
338 { "p=|path=", String.Format ("Application physical path [{0}]", Config
.DefaultApplicationPhysicalPath
), (string s
) => cfg
.ApplicationPhysicalPath
= s
},
339 { "d=|dec=|decrypt=", "Decrypt configuration section", (string s) => { cfg.ConfigSectionName = s; actions.Add (DecryptSection);}
},
340 { "e=|enc=|encrypt=", "Encrypt configuration section", (string s) => { cfg.ConfigSectionName = s; actions.Add (EncryptSection);}
},
342 options
.Parse (args
);
346 options
.WriteOptionDescriptions (Console
.Out
);
350 foreach (var action
in actions
)
352 Environment
.Exit (0);
355 static void Main (string[] args
)
357 new MonoConfigurationCrypto ().Run (args
);