#region License
// CryptoManager - Logiciel de chiffrement de fichiers
// Copyright (C) 2008 G. Villard
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#endregion
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.CSharp;
namespace CryptoManager {
public partial class MainForm : Form {
#region Variables
private SecureEraseMode _eraseMode = SecureEraseMode.Rand;
public const string FILE_EXT = ".cmcrypted";
public const string TABLE_FILE = "table.data";
private StringBuilder _log = new StringBuilder();
#endregion
#region Procédure de lancement du cryptage
private void CryptageMain(object data) {
WorkData wd = data as WorkData;
ICryptoObject cb = GetTransformPair(wd.UsePwd, true);
if(cb == null) {
return;
}
int cnt = 0;
foreach(string entry in wd.Targets) {
cnt++;
ChangerTache(cnt.ToString() + "/" + wd.Targets.Length.ToString());
if(Directory.Exists(entry)) {
Working();
CrypterDossier(entry, cb, wd);
}
else if(File.Exists(entry)) {
Working();
CrypterFichier(entry, cb, wd);
}
if(!btnAnnuler.Enabled)
break;
}
cb.Dispose();
cb = null;
ChangerTache(string.Empty);
Waiting();
if(_log.Length > 0) {
string f = DateTime.Now.ToString("yyyyMMddHHmmss") + "_cm.log";
try {
StreamWriter sw = new StreamWriter(f);
sw.Write(_log.ToString());
sw.Flush();
sw.Close();
MessageBox.Show("Création d'un fichier d'erreurs : " + f);
} finally {
_log.Clear();
}
}
GC.Collect();
}
#endregion
#region Procédure de lancement du decryptage
private void DecryptageMain(object data) {
WorkData wd = data as WorkData;
ICryptoObject cb = GetTransformPair(wd.UsePwd, false);
if(cb == null) {
return;
}
int cnt = 0;
foreach(string entry in wd.Targets) {
cnt++;
ChangerTache(cnt.ToString() + "/" + wd.Targets.Length.ToString());
if(Directory.Exists(entry)) {
Working();
DecrypterDossier(entry, cb, wd);
}
else if(File.Exists(entry)) {
Working();
DecrypterFichier(entry, cb, wd);
}
if(!btnAnnuler.Enabled)
break;
}
cb.Dispose();
cb = null;
ChangerTache(string.Empty);
Waiting();
if(_log.Length > 0) {
string f = DateTime.Now.ToString("yyyyMMddHHmmss") + "_cm.log";
try {
StreamWriter sw = new StreamWriter(f);
sw.Write(_log.ToString());
sw.Flush();
sw.Close();
MessageBox.Show("Création d'un fichier d'erreurs : " + f);
} finally {
_log.Clear();
}
}
GC.Collect();
}
#endregion
#region Création d'une instance de transformation
private ICryptoObject GetTransformPair(bool usePwd, bool withPassCheck) {
if(usePwd) {
using (SecureString password = GetSecureString.Demand(withPassCheck)) {
if(password == null) {
return null;
}
return new CryptoPwd(password.CreateKeyIV());
}
} else {
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = X509Certificate2UI.SelectFromCollection(st.Certificates, "Choix d'un certificat", "Veuillez choisir un certificat.", X509SelectionFlag.SingleSelection);
if(col == null)
return null;
if(col.Count == 0)
return null;
return new CryptoCert(col[0]);
}
}
#endregion
#region Procédure de cryptage d'un fichier
public void CrypterFichier(string fileBase, ICryptoObject cb, WorkData wd) {
Application.DoEvents();
FileAttributes fa = File.GetAttributes(fileBase);
if((fa & FileAttributes.System) == FileAttributes.System) {
if(MessageBox.Show("C'est un fichier système, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
}
if((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) {
if(MessageBox.Show("Le fichier est en lecture seule, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
fa &= ~FileAttributes.ReadOnly;
File.SetAttributes(fileBase, fa);
}
// Traitement
ChangerAction("-- Cryptage en cours --");
InitPB(1);
ChangerFichier(fileBase);
Application.DoEvents();
string fout = string.Empty;
try {
if(wd.CryptFileName)
fout = Path.Combine(Path.GetDirectoryName(fileBase), Path.GetFileName(fileBase).Encrypt(cb, true) + FILE_EXT);
else
fout = fileBase + FILE_EXT;
} catch(Exception ex) {
MessageBox.Show("Erreur de cryptage.");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
// Le fichier existe, on demande confirmation
if(File.Exists(fout)) {
if(MessageBox.Show("Un fichier existe déjà en crypté. Le remplacer ?\r\n\r\n" + fout, "Remplacement", MessageBoxButtons.YesNo,MessageBoxIcon.Question) != DialogResult.Yes)
return;
SecureFile.Delete(fout, _eraseMode);
}
// Transformation
try {
SecureFile.Encrypt(fileBase, fout, cb);
File.SetAttributes(fout, fa);
if(!wd.MakeAutoExtractable)
SecureFile.Delete(fileBase, _eraseMode);
} catch(Exception ex) {
MessageBox.Show(ex.Message);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
Increment();
if(wd.MakeAutoExtractable) {
ChangerAction("-- Génération de l'éxécutable --");
Stack<string> done = new Stack<string>();
done.Push(fout);
MakeFolderAutoExctractable(done, fileBase.Remove(fileBase.LastIndexOf(Path.GetExtension(fileBase))) + ".exe", fileBase, true);
SecureFile.Delete(fout, _eraseMode);
}
}
#endregion
#region Procédure de decryptage d'un fichier
public void DecrypterFichier(string fileBase, ICryptoObject cb, WorkData wd) {
if(!fileBase.EndsWith(FILE_EXT))
return;
Application.DoEvents();
FileAttributes fa = File.GetAttributes(fileBase);
if((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) {
if(MessageBox.Show("Le fichier est en lecture seule, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
fa &= ~FileAttributes.ReadOnly;
File.SetAttributes(fileBase, fa);
}
// Traitement
ChangerAction("-- Decryptage en cours --");
InitPB(1);
ChangerFichier(fileBase);
Application.DoEvents();
string fout = string.Empty;
try {
fout = Path.Combine( Path.GetDirectoryName(fileBase), Path.GetFileName(fileBase.Remove(fileBase.LastIndexOf(FILE_EXT))).Decrypt(cb, true));
} catch {
fout = fileBase.Remove(fileBase.LastIndexOf(FILE_EXT));
}
if(File.Exists(fout)) {
if(MessageBox.Show("Un fichier existe déjà en decrypté. Le remplacer ?\r\n\r\n" + fout, "Remplacement", MessageBoxButtons.YesNo,MessageBoxIcon.Question) != DialogResult.Yes)
return;
SecureFile.Delete(fout, _eraseMode);
}
try {
SecureFile.Decrypt(fileBase, fout, cb);
File.SetAttributes(fout, fa);
SecureFile.Delete(fileBase, _eraseMode);
} catch(PwdException ex) {
MessageBox.Show(ex.Message);
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
} catch(Exception ex) {
MessageBox.Show(ex.Message);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
Increment();
}
#endregion
#region Procédure de cryptage d'un dossier
public void CrypterDossier(string dirBase, ICryptoObject cb, WorkData wd) {
Application.DoEvents();
string dirWork;
try {
if(wd.MakeAutoExtractable) {
dirWork = Path.Combine(Path.GetTempPath(), "CryptoManager");
if(Directory.Exists(dirWork)) {
DirectorySecure.Delete(dirWork, _eraseMode);
}
Directory.CreateDirectory(dirWork);
}
else
dirWork = dirBase;
} catch(Exception ex) {
dirWork = Path.Combine(Directory.GetParent(dirBase).FullName, "CMTEMPDIR");
if(Directory.Exists(dirWork)) {
MessageBox.Show("Impossible d'accéder à un dossier temporaire.");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
}
// Initialisation
ChangerAction("-- Préparation --");
ChangerFichier(string.Empty);
string dataFile = Path.Combine(dirWork, TABLE_FILE + FILE_EXT);
bool fsys = false, fro = false;
foreach(string file in Directory.GetFiles(dirWork, "*", SearchOption.AllDirectories)) {
try {
new FileIOPermission(FileIOPermissionAccess.AllAccess, file).Demand();
FileAttributes fa = File.GetAttributes(file);
if((fa & FileAttributes.System) == FileAttributes.System) {
if(!fsys)
if(MessageBox.Show("Des fichiers système sont présents, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
fsys = true;
}
if((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) {
if(!fro)
if(MessageBox.Show("Des fichiers en lecture seule sont présents, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
fro = true;
File.SetAttributes(file, fa & ~FileAttributes.ReadOnly);
}
} catch(Exception ex) {
MessageBox.Show(ex.Message);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
}
// Copie des fichiers en cas d'auto-extractable
if(wd.MakeAutoExtractable) {
foreach(string dir in Directory.GetDirectories(dirBase, "*", SearchOption.AllDirectories))
Directory.CreateDirectory(dir.Replace(dirBase, dirWork));
try {
Parallel.ForEach(Directory.GetFiles(dirBase, "*", SearchOption.AllDirectories), fichier => { File.Copy(fichier, fichier.Replace(dirBase, dirWork)); });
} catch(Exception ex) {
MessageBox.Show("Impossible de créer les fichiers temporaires.");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
try {
DirectorySecure.Delete(dirWork);
} finally {}
return;
}
}
// Comptage des fichiers
int i = Directory.GetFiles(dirWork, "*", SearchOption.AllDirectories).Length;
if(i == 0)
return;
InitPB(i);
#region Renomage des dossiers et enregistrement dans une table
if(wd.CryptFileName) {
MemoryStream dataIn = null;
FileStream dataOut = null;
try {
dataIn = new MemoryStream();
dataOut = File.Open(dataFile, FileMode.CreateNew, FileAccess.ReadWrite);
} catch(Exception ex) {
MessageBox.Show("Impossible de créer la table des dossiers !");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
Stack<string> dirList = new Stack<string>();
Stack<string> dataList = new Stack<string>();
Stack<string> dataSave = new Stack<string>();
foreach(string rep in Directory.GetDirectories(dirWork, "*", SearchOption.AllDirectories))
dirList.Push(rep);
// Renommage des dossiers
try {
while(dirList.Count > 0) {
string dir = dirList.Pop();
string dest = Path.Combine(Directory.GetParent(dir).FullName, "." + dirList.Count);
Directory.Move(dir, dest);
dataList.Push(dir.Substring(dirWork.Length + 1) + ":" + dest.Substring(dirWork.Length + 1));
dataSave.Push(dataList.Peek());
}
} catch(Exception ex) {
MessageBox.Show("Impossible de renommer un des dossiers. Vérifiez vos permissions.");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
while(dataList.Count > 0) {
string tmp = dataList.Pop();
Directory.Move(Path.Combine(dirWork, tmp.Split(':')[1]), Path.Combine(dirWork, tmp.Split(':')[0]));
}
dataOut.Close();
File.Delete(dataFile);
return;
}
// Ecriture dans les flux
try {
StreamWriter sw = new StreamWriter(dataIn);
while(dataList.Count > 0)
sw.WriteLine(dataList.Pop());
sw.Flush();
dataIn.Position = 0;
cb.Encrypt(dataIn, dataOut);
if(dataOut != null)
dataOut.Close();
if(dataIn != null)
dataIn.Close();
sw = null;
} catch {
MessageBox.Show("Impossible d'ecrire dans les flux, annulation !");
while(dataSave.Count > 0) {
string tmp = dataSave.Pop();
Directory.Move(Path.Combine(dirWork, tmp.Split(':')[1]), Path.Combine(dirWork, tmp.Split(':')[0]));
}
dataOut.Close();
File.Delete(dataFile);
return;
}
}
#endregion
// Traitement
ChangerAction("-- Cryptage en cours --");
Stack<string> done = new Stack<string>();
bool cancel = false;
Parallel.ForEach(Directory.GetFiles(dirWork, "*", SearchOption.AllDirectories), (string fichier, ParallelLoopState state, long cnt) => {
// Affichage du fichier en cours
ChangerFichier(fichier);
// Test d'annulation
if(state.IsStopped || state.ShouldExitCurrentIteration) {
return;
}
// Table des dossiers, on ignore
if(string.Equals(fichier, dataFile, StringComparison.CurrentCultureIgnoreCase)) {
return;
}
string fout = string.Empty;
try {
if(wd.CryptFileName)
fout = Path.Combine(Path.GetDirectoryName(fichier), Path.GetFileName(fichier).Encrypt(cb, true) + FILE_EXT);
else
fout = fichier + FILE_EXT;
} catch(Exception ex) {
state.Break();
MessageBox.Show("Erreur de cryptage.\r\n");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
try {
// Le fichier existe, on demande confirmation
if(File.Exists(fout)) {
if(MessageBox.Show("Un fichier existe déjà en crypté. Le remplacer ?\r\n\r\n" + fout, "Remplacement", MessageBoxButtons.YesNo,MessageBoxIcon.Question) != DialogResult.Yes) {
SecureFile.Delete(fichier, _eraseMode);
return;
}
File.SetAttributes(fout, FileAttributes.Normal);
SecureFile.Delete(fout, _eraseMode);
}
SecureFile.Encrypt(fichier, fout, cb);
File.SetAttributes(fout, File.GetAttributes(fichier));
} catch(Exception ex) {
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
state.Break();
cancel = true;
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
// Test d'annulation
if(state.IsStopped || state.ShouldExitCurrentIteration) {
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
SecureFile.Delete(fichier, _eraseMode);
Increment();
done.Push(fout);
Application.DoEvents();
if(!btnAnnuler.Enabled)
state.Break();
});
if(!btnAnnuler.Enabled || cancel) {
#region Revert, on prend tous les fichiers en inverse et on decrypte
ChangerAction("-- Annulation --");
if(wd.MakeAutoExtractable) {
DirectorySecure.Delete(dirWork, _eraseMode);
} else {
Parallel.ForEach(done.ToArray(), (string fichier, ParallelLoopState state, long cnt) => {
string fout;
if(wd.CryptFileName)
fout = Path.Combine(Path.GetDirectoryName(fichier), Path.GetFileName(fichier.Remove(fichier.LastIndexOf(FILE_EXT))).Decrypt(cb, true));
else
fout = fichier.Remove(fichier.LastIndexOf(FILE_EXT));
ChangerFichier(fichier);
FileAttributes fa = File.GetAttributes(fichier);
if(!File.Exists(fout)) {
SecureFile.Decrypt(fichier, fout, cb);
SecureFile.Delete(fichier, _eraseMode);
}
File.SetAttributes(fout, fa);
Decrement();
});
}
#endregion
#region Revert du renomage de la table des dossiers.
if(File.Exists(dataFile) && wd.CryptFileName) {
MemoryStream dataDec = null;
FileStream fs= File.Open(dataFile, FileMode.Open);
byte[] tmp = new byte[fs.Length];
fs.Read(tmp, 0, (int)fs.Length);
dataDec = new MemoryStream(cb.Decrypt(tmp));
if(fs != null)
fs.Close(_eraseMode);
dataDec.Position = 0;
StreamReader sr = null;
try {
sr = new StreamReader(dataDec);
string line;
string[] val;
while((line = sr.ReadLine()) != null) {
val = line.Split(':');
Directory.Move(Path.Combine(dirWork, val[1]), Path.Combine(dirWork, val[0]));
}
} catch(Exception ex) {
MessageBox.Show("Table des dossiers corrompue. Revert incomplet.\r\n" + ex.Message + "\r\n" + ex.StackTrace);
} finally {
try {
sr.Close();
sr.Dispose();
sr = null;
} catch {}
}
try {
if(!wd.MakeAutoExtractable)
SecureFile.Delete(dataFile, _eraseMode);
} catch {
MessageBox.Show("Impossible de supprimer la table des dossiers.");
}
}
#endregion
} else {
if(wd.MakeAutoExtractable) {
ChangerAction("-- Génération de l'éxécutable --");
done.Push(dataFile);
MakeFolderAutoExctractable(done, Path.Combine(Directory.GetParent(dirBase).FullName, dirBase.Substring(dirBase.LastIndexOf(@"\") + 1) + ".exe"), dirWork, false);
DirectorySecure.Delete(dirWork, _eraseMode);
}
}
}
#endregion
#region Procédure de decryptage d'un dossier
public void DecrypterDossier(string dirBase, ICryptoObject cb, WorkData wd) {
Application.DoEvents();
ChangerAction("-- Préparation --");
InitPB(10);
bool fro = false;
foreach(string file in Directory.GetFiles(dirBase, "*" + FILE_EXT, SearchOption.AllDirectories)) {
try {
new FileIOPermission(FileIOPermissionAccess.AllAccess, file).Demand();
FileAttributes fa = File.GetAttributes(file);
if((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) {
if(!fro)
if(MessageBox.Show("Des fichiers en lecture seule sont présents, voulez vous continuer ?", string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
return;
fro = true;
File.SetAttributes(file, fa & ~FileAttributes.ReadOnly);
}
} catch(Exception ex) {
MessageBox.Show(ex.Message);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
}
int i = Directory.GetFiles(dirBase, "*" + FILE_EXT, SearchOption.AllDirectories).Length;
if(i == 0)
return;
InitPB(i);
try {
cb.CheckPassword(Directory.GetFiles(dirBase, "*" + FILE_EXT, SearchOption.AllDirectories)[0]);
} catch(PwdException ex) {
MessageBox.Show(ex.Message);
return;
} catch(Exception ex) {
MessageBox.Show(ex.Message);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
return;
}
ChangerAction("-- Decryptage en cours --");
Stack<string> done = new Stack<string>();
bool cancel = false;
Parallel.ForEach(Directory.GetFiles(dirBase, "*" + FILE_EXT, SearchOption.AllDirectories), (string fichier, ParallelLoopState state, long cnt) => {
// Test d'annulation
if(state.IsStopped || state.ShouldExitCurrentIteration) {
return;
}
ChangerFichier(fichier);
string fout = string.Empty;
if(!fichier.EndsWith(FILE_EXT))
return;
try {
fout = Path.Combine( Path.GetDirectoryName(fichier), Path.GetFileName(fichier.Remove(fichier.LastIndexOf(FILE_EXT))).Decrypt(cb, true));
} catch {
fout = fichier.Remove(fichier.LastIndexOf(FILE_EXT));
}
try {
if(File.Exists(fout)) {
if(MessageBox.Show("Un fichier existe déjà en decrypté. Le remplacer ?\r\n\r\n" + fout, "Remplacement", MessageBoxButtons.YesNo,MessageBoxIcon.Question) != DialogResult.Yes) {
SecureFile.Delete(fichier, _eraseMode);
return;
}
SecureFile.Delete(fout, _eraseMode);
}
SecureFile.Decrypt(fichier, fout, cb);
File.SetAttributes(fout, File.GetAttributes(fichier));
} catch(Exception ex) {
state.Break();
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
cancel = true;
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
// Test d'annulation
if(state.IsStopped || state.ShouldExitCurrentIteration) {
if(File.Exists(fout))
SecureFile.Delete(fout, _eraseMode);
return;
}
SecureFile.Delete(fichier, _eraseMode);
Increment();
done.Push(fout);
Application.DoEvents();
if(!btnAnnuler.Enabled)
state.Break();
});
if(!btnAnnuler.Enabled || cancel) {
ChangerAction("-- Annulation --");
Parallel.ForEach(done.ToArray(), (string fichier, ParallelLoopState state, long cnt) => {
string fout;
try {
if(string.Compare(Path.GetFileName(fichier), TABLE_FILE, true) == 0)
fout = fichier + FILE_EXT;
else
fout = Path.Combine(Path.GetDirectoryName(fichier), Path.GetFileName(fichier).Encrypt(cb, true) + FILE_EXT);
} catch {
fout = fichier + FILE_EXT;
}
ChangerFichier(fichier);
if(!File.Exists(fout)) {
FileAttributes fa = File.GetAttributes(fichier);
SecureFile.Encrypt(fichier, fout, cb);
SecureFile.Delete(fichier, _eraseMode);
File.SetAttributes(fout, fa);
}
Decrement();
});
} else {
ChangerAction("-- Finalisation --");
ChangerFichier(string.Empty);
string data = Path.Combine(dirBase, "table.data");
if(File.Exists(data)) {
StreamReader sr = null;
try {
sr = new StreamReader(data);
string line;
string[] val;
while((line = sr.ReadLine()) != null) {
val = line.Split(':');
Directory.Move(Path.Combine(dirBase, val[1]), Path.Combine(dirBase, val[0]));
}
} catch(Exception ex) {
MessageBox.Show("Table des dossiers corrompue. Finalisation incomplète.\r\n" + ex.Message + "\r\n" + ex.StackTrace);
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
} finally {
try {
sr.Close();
sr.Dispose();
sr = null;
} catch {}
}
try {
SecureFile.Delete(data, _eraseMode);
} catch(Exception ex) {
MessageBox.Show("Impossible de supprimer la table des dossiers.");
_log.AppendLine(ex.Message);
_log.AppendLine(ex.StackTrace);
}
}
}
}
#endregion
#region Cryptage du presse-papiers
private void CrypterClipboard(object sender, EventArgs e) {
string data = null;
if(Clipboard.ContainsText(TextDataFormat.UnicodeText)) {
data = Clipboard.GetText(TextDataFormat.UnicodeText);
}
else if(Clipboard.ContainsText(TextDataFormat.Rtf)) {
data = Clipboard.GetText(TextDataFormat.Rtf);
}
else if(Clipboard.ContainsText()) {
data = Clipboard.GetText();
}
if(data == null) {
MessageBox.Show("Le presse-papiers ne contient pas de texte.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
ICryptoObject cb = GetTransformPair(true, true);
if(cb == null) {
MessageBox.Show("Erreur dans l'obtention du mot de passe ou de la clé.", "Echec", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Clipboard.SetText(data.Encrypt(cb));
cb.Dispose();
GC.Collect();
MessageBox.Show("La chaine cryptée est dans le presse-papiers !", "Réussite", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
#region Decryptage du presse-papiers
private void DecrypterClipboard(object sender, EventArgs e) {
string data = null;
if(Clipboard.ContainsText()) {
data = Clipboard.GetText();
}
if(data == null) {
MessageBox.Show("Le presse-papiers ne contient pas de texte.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
ICryptoObject cb = GetTransformPair(false, false);
if(cb == null) {
MessageBox.Show("Erreur dans l'obtention du mot de passe ou de la clé.", "Echec", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string output = data.Decrypt(cb);
if(output == null) {
MessageBox.Show("Password incorrect !", "Echec", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
Clipboard.SetText(output);
cb.Dispose();
GC.Collect();
MessageBox.Show("La chaine decryptée est dans le presse-papiers !", "Réussite", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
#region Fabrication d'un dossier auto-extractable
private void MakeFolderAutoExctractable(Stack<string> Fichiers, string fileOutput, string origin, bool singleFile) {
Compilation(Fichiers, fileOutput, origin, singleFile);
}
#endregion
#region Récupération d'une resource et écriture dans un fichier
private static void WriteResToFile(string inName) {
using(Stream st = Assembly.GetExecutingAssembly().GetManifestResourceStream(inName)) {
using(FileStream fs= new FileStream(inName, FileMode.Create)) {
byte[] tmp = new byte[4096];
int bytesRead = 0;
do {
bytesRead = st.Read(tmp, 0, tmp.Length);
fs.Write(tmp, 0, bytesRead);
fs.Flush();
} while(bytesRead != 0);
}
}
}
#endregion
#region Compilation
private void Compilation(Stack<string> Fichiers, string fileOutput, string origin, bool singleFile) {
Dictionary<string, string> options = new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } };
CSharpCodeProvider provider = new CSharpCodeProvider(options);
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = true;
cp.OutputAssembly = fileOutput;
cp.ReferencedAssemblies.Add( "System.dll" );
cp.ReferencedAssemblies.Add( "System.Core.dll" );
cp.ReferencedAssemblies.Add( "System.Drawing.dll" );
cp.ReferencedAssemblies.Add( "System.Windows.Forms.dll" );
cp.ReferencedAssemblies.Add( "System.Xml.dll" );
cp.GenerateInMemory = false;
cp.WarningLevel = 3;
cp.TreatWarningsAsErrors = false;
cp.CompilerOptions = "/optimize /unsafe /target:winexe /win32icon:CryptoManager.autoexec.ico";
cp.TempFiles = new TempFileCollection(".", false);
if (provider.Supports(GeneratorSupport.EntryPointMethod)) {
cp.MainClass = "CryptoManager.AutoExtractable";
}
string[] compFiles = new string[] {
"CryptoManager.SecureFile.cs","CryptoManager.AutoExtractable.cs","CryptoManager.AutoExtractable.Designer.cs",
"CryptoManager.AutoExtractableAssemblyInfo.cs","CryptoManager.GetSecureString.cs",
"CryptoManager.GetSecureString.Designer.cs","CryptoManager.SecureEraseMode.cs","CryptoManager.Extension.cs",
"CryptoManager.autoexec.ico","CryptoManager.NativeMethods.cs","CryptoManager.SecureDirectory.cs",
"CryptoManager.CryptoPwd.cs","CryptoManager.CryptoCert.cs","CryptoManager.ICryptoObject.cs","CryptoManager.PwdException.cs"
};
foreach(string fichier in compFiles)
WriteResToFile(fichier);
WriteResToFile("CryptoManager.AutoExtractable.resources");
if (provider.Supports(GeneratorSupport.Resources)) {
cp.EmbeddedResources.Add("CryptoManager.AutoExtractable.resources");
StreamWriter sw = new StreamWriter("base.data", false);
if(singleFile) {
string tmpf = Fichiers.Peek().Substring(Path.GetDirectoryName(origin).Length + 1);
cp.EmbeddedResources.Add(Path.Combine(Path.GetDirectoryName(origin), tmpf));
sw.WriteLine(tmpf);
} else {
foreach(string fichier in Fichiers) {
string tmpf = fichier.Substring(origin.Length + 1).Replace(Path.DirectorySeparatorChar + "", ".¤R¤");
File.Move(fichier, Path.Combine(origin, tmpf));
cp.EmbeddedResources.Add(Path.Combine(origin, tmpf));
sw.WriteLine(tmpf);
}
}
sw.Flush();
sw.Close();
cp.EmbeddedResources.Add("base.data");
}
foreach(CompilerError ce in provider.CompileAssemblyFromFile(cp, compFiles).Errors) {
MessageBox.Show(ce.ToString());
}
cp.TempFiles.Delete();
foreach(string fichier in compFiles)
SecureFile.Delete(fichier, _eraseMode);
SecureFile.Delete("base.data", _eraseMode);
}
#endregion
}
}