forked from dalefugier/RhinoScriptEncrypter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RhinoScriptEncrypterCommand.cs
324 lines (275 loc) · 9.5 KB
/
RhinoScriptEncrypterCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
using System;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Rhino;
using Rhino.Commands;
using Rhino.Geometry;
using Rhino.Input;
using Rhino.Input.Custom;
namespace RhinoScriptEncrypter
{
/// <summary>
/// RhinoScriptEncrypterCommand
/// </summary>
[System.Runtime.InteropServices.Guid("1da690e6-7e5c-4949-9c03-b9cafb333144")]
public class RhinoScriptEncrypterCommand : Command
{
int _optionIndex = 0;
/// <summary>
/// Public constructor
/// </summary>
public RhinoScriptEncrypterCommand()
{
}
/// <summary>
/// Returns the English command name
/// </summary>
public override string EnglishName
{
get { return "RhinoScriptEncrypter"; }
}
/// <summary>
/// RunCommand override
/// </summary>
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
string rhinoScriptFile = string.Empty;
// Prompt for a filename
if (mode == RunMode.Interactive)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "RhinoScript Files (*.rvb)|*.rvb";
openFileDialog.Title = "Select RhinoScript File";
if (openFileDialog.ShowDialog() != DialogResult.OK)
return Result.Cancel;
rhinoScriptFile = openFileDialog.FileName;
}
else
{
Result rc = GetOpenFileName("RhinoScript file to encrypt", ref rhinoScriptFile);
if (rc != Result.Success)
return rc;
}
// Verify the filename
rhinoScriptFile = rhinoScriptFile.Trim();
if (string.IsNullOrEmpty(rhinoScriptFile))
return Result.Nothing;
// Verify the file exists
if (!File.Exists(rhinoScriptFile))
{
string error = string.Format("RhinoScript file not found - {0}\n", rhinoScriptFile);
if (mode == RunMode.Interactive)
MessageBox.Show(error, EnglishName, MessageBoxButtons.OK, MessageBoxIcon.Error);
else
RhinoApp.WriteLine(error);
return Result.Failure;
}
// Generate an encryption password
string encryptPassword = Guid.NewGuid().ToString();
// Do the file encryption
string encryptedFileName = string.Empty;
try
{
// Read the script
string clearString = File.ReadAllText(rhinoScriptFile);
// Encrypt the script
string encryptedString = Encrypt(clearString, encryptPassword);
// Write the encrypted script
encryptedFileName = Path.ChangeExtension(rhinoScriptFile, ".rvbx");
File.WriteAllText(encryptedFileName, encryptedString);
}
catch (Exception ex)
{
string error = string.Format("Error encrypting RhinoScript file - {0}\n{1}\n", rhinoScriptFile, ex.Message);
if (mode == RunMode.Interactive)
MessageBox.Show(error, EnglishName, MessageBoxButtons.OK, MessageBoxIcon.Error);
else
RhinoApp.WriteLine(error);
return Result.Failure;
}
// Report the results
string outputString = "RhinoScript file encryption successful!\n";
outputString += string.Format(" Input filename: {0}\n", rhinoScriptFile);
outputString += string.Format(" Output filename: {0}\n", encryptedFileName);
outputString += string.Format(" Decrypt password: {0}\n", encryptPassword);
if (mode == RunMode.Interactive)
Rhino.UI.Dialogs.ShowTextDialog(outputString, EnglishName);
else
{
string[] values = new string[] { "HistoryWindow", "File", "Clipboard", "Dialog" };
GetOption go = new GetOption();
go.SetCommandPrompt(string.Format("Text destination <{0}>", values[_optionIndex]));
go.AcceptNothing(true);
go.AddOption(new Rhino.UI.LocalizeStringPair(values[0], values[0])); // 1
go.AddOption(new Rhino.UI.LocalizeStringPair(values[1], values[1])); // 2
go.AddOption(new Rhino.UI.LocalizeStringPair(values[2], values[2])); // 3
go.AddOption(new Rhino.UI.LocalizeStringPair(values[3], values[3])); // 4
GetResult res = go.Get();
if (res == GetResult.Option)
_optionIndex = go.OptionIndex() - 1;
else if (res != GetResult.Nothing)
return Result.Cancel;
switch (_optionIndex)
{
case 0: // HistoryWindow
RhinoApp.WriteLine(outputString);
break;
case 1: // File
{
string outputFileName = string.Empty;
Result cmd_rc = GetSaveFileName("Save file name", ref outputFileName);
if (cmd_rc != Result.Success)
return Result.Cancel;
outputFileName = outputFileName.Trim();
if (string.IsNullOrEmpty(outputFileName))
return Result.Nothing;
try
{
outputString = outputString.Replace("\n", "\r\n");
using (StreamWriter stream = new StreamWriter(outputFileName))
stream.Write(outputString);
}
catch
{
RhinoApp.WriteLine("Unable to write to file.\n");
return Result.Failure;
}
}
break;
case 2: // Clipboard
outputString = outputString.Replace("\n", "\r\n");
Clipboard.SetText(outputString);
break;
case 3: // Dialog
Rhino.UI.Dialogs.ShowTextDialog(outputString, EnglishName);
break;
}
}
return Result.Success;
}
/// <summary>
/// Prompts the user for the name of a file to open
/// </summary>
private Result GetOpenFileName(string prompt, ref string fileName)
{
Result rc = Result.Cancel;
if (string.IsNullOrEmpty(prompt))
prompt = "File name";
GetString gs = new GetString();
gs.SetCommandPrompt(prompt);
gs.AddOption(new Rhino.UI.LocalizeStringPair("Browse", "Browse"));
if (!string.IsNullOrEmpty(fileName))
gs.SetDefaultString(fileName);
GetResult res = gs.Get();
if (res == GetResult.String)
{
fileName = gs.StringResult();
rc = Result.Success;
}
else if (res == GetResult.Option)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = "RhinoScript Files (*.rvb)|*.rvb";
fileDialog.Title = "Select RhinoScript File";
if (fileDialog.ShowDialog() == DialogResult.OK)
{
fileName = fileDialog.FileName;
rc = Result.Success;
}
}
return rc;
}
/// <summary>
/// Prompts the user for the name of a file to save
/// </summary>
private Result GetSaveFileName(string prompt, ref string fileName)
{
Result rc = Result.Cancel;
if (string.IsNullOrEmpty(prompt))
prompt = "File name";
GetString gs = new GetString();
gs.SetCommandPrompt(prompt);
gs.AddOption(new Rhino.UI.LocalizeStringPair("Browse", "Browse"));
if (!string.IsNullOrEmpty(fileName))
gs.SetDefaultString(fileName);
GetResult res = gs.Get();
if (res == GetResult.String)
{
fileName = gs.StringResult();
rc = Result.Success;
}
else if (res == GetResult.Option)
{
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.Filter = "Text Documents|*.txt";
fileDialog.Title = "Save As";
if (fileDialog.ShowDialog() == DialogResult.OK)
{
fileName = fileDialog.FileName;
rc = Result.Success;
}
}
return rc;
}
/// <summary>
/// Encrypts a string with a password
/// </summary>
private string Encrypt(string text, string password)
{
if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(password))
return null;
string encryptedText = null;
try
{
byte[] buffer = System.Text.Encoding.Unicode.GetBytes(text);
byte[] encryptedBuffer = Encrypt(buffer, password);
encryptedText = Convert.ToBase64String(encryptedBuffer);
}
catch
{
encryptedText = null;
}
return encryptedText;
}
/// <summary>
/// Encrypts a byte array with a password
/// </summary>
private byte[] Encrypt(byte[] buffer, string password)
{
if (null == buffer || 0 == buffer.Length || string.IsNullOrEmpty(password))
return null;
byte[] encryptedBuffer = null;
CryptoStream cryptoStream = null;
try
{
Rfc2898DeriveBytes secretKey = new Rfc2898DeriveBytes(password, _keySalt);
RijndaelManaged cipher = new RijndaelManaged();
ICryptoTransform transform = cipher.CreateEncryptor(secretKey.GetBytes(32), secretKey.GetBytes(16));
MemoryStream memoryStream = new MemoryStream();
cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(buffer, 0, buffer.Length);
cryptoStream.FlushFinalBlock();
encryptedBuffer = memoryStream.ToArray();
}
catch
{
encryptedBuffer = null;
}
finally
{
if (null != cryptoStream)
cryptoStream.Close();
}
return encryptedBuffer;
}
/// <summary>
/// Key salt to use to derive the encryption key
/// </summary>
private byte[] _keySalt = new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
}
}