Example #1
0
        //A worker for Compare mode
        private static async Task doWork(MinSizeQueue <KeyValuePair <string, string> > queue, IDictionary <string, string> creds, string obj, ICryptoTransform cryptoTrans, TextWriter writer)
        {
            SynchronizedIds psid = new SynchronizedIds();
            int             currentId;
            Guid            guid = Guid.NewGuid();

            Trace.TraceInformation($"A worker {guid} has started.");
            while (true)
            {
                currentId = psid.GetCurrentID();
                KeyValuePair <string, string> att;
                HttpResponseMessage           response = null;

                if (minSizeQueue.TryDequeue(out att))
                {
                    byte[] valueBytes = null;
                    try
                    {
                        valueBytes = Convert.FromBase64String(att.Value);
                    }
                    catch
                    {
                        Trace.TraceError($"Error decoding Base64 value for {att.Key}");
                        continue;
                    }
                    if (valueBytes.Length > 0)
                    {
                        using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(att.Value)))
                        {
                            using (CryptoStream cstream = new CryptoStream(stream, cryptoTrans, CryptoStreamMode.Read))
                            {
                                byte[] decrypted = new byte[valueBytes.Length];
                                try
                                {
                                    int bytesRead = cstream.Read(decrypted, 0, valueBytes.Length);
                                    if (bytesRead > 0)
                                    {
                                        string decryptedValue = Convert.ToBase64String(decrypted);
                                        try
                                        {
                                            response = await ReadFromSalesForce(new Uri(creds["serverUrl"] + "/sobjects/" + obj + "/" + att.Key + "/Body"),
                                                                                creds, HttpMethod.Get, null);
                                        }
                                        catch (Exception ex)
                                        {
                                            Trace.TraceError("An error occured while working in Compare mode.\n" +
                                                             ex.Message);
                                        }

                                        if (response != null && response.Content != null && response.StatusCode == HttpStatusCode.OK)
                                        {
                                            using (MemoryStream ms = new MemoryStream())
                                            {
                                                response.Content.ReadAsStreamAsync().Result.CopyTo(ms);
                                                byte[] res = ms.ToArray();
                                                Array.Resize <byte>(ref decrypted, res.Length);
                                                if (res.SequenceEqual(decrypted))
                                                {
                                                    Trace.TraceInformation($"#{currentId} - {att.Key} is Equal from {guid}.");
                                                    writer.WriteLine(att.Key + ",EQ");
                                                }
                                                else
                                                {
                                                    Trace.TraceInformation($"#{currentId} - {att.Key} is OK from {guid}.");
                                                }
                                            }
                                        }
                                        else
                                        {
                                            Trace.TraceWarning($"#{currentId} - {att.Key} failed to read from {guid}.");
                                            writer.WriteLine(att.Key + ",SF_ERROR");
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Trace.TraceError($"{ex.Message}\noccured while trying to compare {att.Key} from {guid}");
                                }
                            }
                        }
                    }
                }
                else
                {
                    minSizeQueue.Close();
                    break;
                }
            }
            Trace.TraceInformation($"A worker {guid} has finished the work.");
        }
Example #2
0
        static async Task Main(string[] args)
        {
            int result = Parser.Default.ParseArguments <Options>(args)
                         .MapResult(
                (Options opt) =>
            {
                domainName            = opt.SalesForceDomain;
                groupName             = opt.GroupName;
                entryName             = opt.EntryName;
                pathToKeePassDb       = opt.KDBXPath;
                objectWithAttachments = Enum.GetName(typeof(SFObjectsWithAttachments), opt.SFObject);
                resultFileName        = opt.EcryptedAttachmentsTargetFile == null ?
                                        "encrypted_" + objectWithAttachments + ".dat" : opt.EcryptedAttachmentsTargetFile;
                workingMode     = opt.WorkMode;
                numberOfThreads = opt.NumberOfWorkingThreads;
                if (opt.LogFilePath != null && !opt.LogFilePath.Equals(String.Empty))
                {
                    Trace.Listeners.Add(new TextWriterTraceListener(opt.LogFilePath, "Backup_fileTracer"));
                    Trace.Listeners["Backup_fileTracer"].TraceOutputOptions |= TraceOptions.DateTime;
                }
                if (opt.LogToConsole != 0)
                {
                    Trace.Listeners.Add(consoleTraceListener);
                }
                Trace.AutoFlush = true;
                Trace.Listeners.Remove("Default");
                if (workingMode == WorkingModes.Compare &&
                    (opt.ComparisonResultsFilePath == null || opt.ComparisonResultsFilePath.Equals(String.Empty)))
                {
                    Trace.TraceError($"If workmode is set to compare then comparison file must be provided.");
                    WaitExitingCountdown(waittime);
                    Environment.Exit(-1);
                    return(0);
                }
                else
                {
                    pathToComparisonResults = opt.ComparisonResultsFilePath;
                    if (workingMode == WorkingModes.Read)
                    {
                        filter = "+WHERE+" + opt.ReadModeFilter;
                    }
                }
                Trace.TraceInformation("Arguments have been successfully parsed");
                return(1);
            },
                (IEnumerable <Error> errs) =>
            {
                WaitExitingCountdown(waittime);
                Environment.Exit(-1);
                return(0);
            });

            SecureString securePwd = new SecureString();

            Console.Write("Enter password for KeePass: "******"*");
                }
                else
                {
                    if (securePwd.Length > 0)
                    {
                        securePwd.RemoveAt(securePwd.Length - 1);
                        Console.Write("\b \b");
                    }
                }
                // Exit if Enter key is pressed.
            } while (key.Key != ConsoleKey.Enter);
            Console.WriteLine();

            Dictionary <string, ProtectedString> credentialsDict = new Dictionary <string, ProtectedString>(OpenKeePassDB(securePwd));

            Trace.TraceInformation($"Got {credentialsDict.Count} credentials");
            if (credentialsDict.Where(t => t.Key == "IV" || t.Key == "AESPass" || t.Key == "Salt").Count() < 3)
            {
                Trace.TraceError("Necessary cryptographic input is absent in the provided entry in the KDBX.");
                WaitExitingCountdown(waittime);
                return;
            }
            else if (workingMode == WorkingModes.Prepare)
            {
                Trace.TraceInformation("Preparation of KDBX has been successfully completed");
                WaitExitingCountdown(waittime);
                return;
            }
            Dictionary <string, string> salesForceSID = new Dictionary <string, string>(await GetSalesForceSessionId(credentialsDict));

            if (salesForceSID.Count == 0)
            {
                Trace.TraceError("Error getting SalesForce session ID. Exiting...");
                WaitExitingCountdown(waittime);
                return;
            }

            #region ChecksOfNeededFiles
            switch (workingMode)
            {
            case WorkingModes.Read:
                listOfIds = (await GetListOfIds(salesForceSID, objectWithAttachments)).ToList();
                if (listOfIds.Count != 0)
                {
                    Trace.TraceInformation($"Got {listOfIds.Count} Ids in the {objectWithAttachments} object");
                }
                else
                {
                    Trace.TraceError("Nothing to extract. Exiting...");
                    WaitExitingCountdown(waittime);
                    Environment.Exit(-2);
                }
                break;

            case WorkingModes.Write:
            case WorkingModes.Compare:
                if (!File.Exists(resultFileName))
                {
                    Trace.TraceError("Source file does not exist. Exiting...");
                    WaitExitingCountdown(waittime);
                    Environment.Exit(-3);
                }
                break;;
            }
            #endregion

            #region CryptographicStuff
            SymmetricAlgorithm cipher = SymmetricAlgorithm.Create("AesManaged");
            cipher.Mode    = CipherMode.CBC;
            cipher.Padding = PaddingMode.PKCS7;
            cipher.IV      = Convert.FromBase64String(credentialsDict["IV"].ReadString());
            Byte[] passwordKey = NewPasswordKey(SecureStringExtension.ToSecureString(credentialsDict["AESPass"].ReadString()),
                                                credentialsDict["Salt"].ReadString());
            #endregion

            #region StartWorkers
            List <Task> tasks = new List <Task>();
            switch (workingMode)
            {
            case WorkingModes.Read:
                using (TextWriter resultStream = TextWriter.Synchronized(new StreamWriter(resultFileName, false, Encoding.ASCII)))
                {
                    Trace.TraceInformation($"Initiating {numberOfThreads} workers to read data.");
                    for (int i = 0; i < numberOfThreads; i++)
                    {
                        tasks.Add(Task.Run(
                                      () => doWork(listOfIds.ToList(), salesForceSID, objectWithAttachments, cipher.CreateEncryptor(passwordKey, cipher.IV), resultStream)));
                    }
                    Task.WaitAll(tasks.ToArray());
                }
                break;

            case WorkingModes.Write:
                minSizeQueue = new MinSizeQueue <KeyValuePair <string, string> >(numberOfThreads);
                _            = FillQueue();
                Trace.TraceInformation($"Initiating {numberOfThreads} workers to write data.");
                for (int i = 0; i < numberOfThreads; i++)
                {
                    tasks.Add(Task.Run(
                                  () => doWork(minSizeQueue, salesForceSID, objectWithAttachments, cipher.CreateDecryptor(passwordKey, cipher.IV))));
                }
                Task.WaitAll(tasks.ToArray());
                break;

            case WorkingModes.Compare:
                minSizeQueue = new MinSizeQueue <KeyValuePair <string, string> >(numberOfThreads);
                _            = FillQueue();
                using (TextWriter resultStream = TextWriter.Synchronized(new StreamWriter(pathToComparisonResults, false, Encoding.ASCII)))
                {
                    Trace.TraceInformation($"Initiating {numberOfThreads} workers to compare data.");
                    for (int i = 0; i < numberOfThreads; i++)
                    {
                        tasks.Add(Task.Run(
                                      () => doWork(minSizeQueue, salesForceSID, objectWithAttachments, cipher.CreateDecryptor(passwordKey, cipher.IV), resultStream)));
                    }
                    Task.WaitAll(tasks.ToArray());
                }
                break;
            }
            Trace.TraceInformation("All threads complete");
            WaitExitingCountdown(waittime);
        }
Example #3
0
        //A worker for Write mode
        private static async Task doWork(MinSizeQueue <KeyValuePair <string, string> > queue, IDictionary <string, string> creds, string obj, ICryptoTransform cryptoTrans)
        {
            Guid guid = Guid.NewGuid();

            Trace.TraceInformation($"A worker {guid} has started.");
            HttpResponseMessage response = null;

            while (true)
            {
                KeyValuePair <string, string> att;
                if (minSizeQueue.TryDequeue(out att))
                {
                    byte[] valueBytes = null;
                    try
                    {
                        valueBytes = Convert.FromBase64String(att.Value);
                    }
                    catch
                    {
                        Trace.TraceError($"Error decoding Base64 value for {att.Key}");
                        continue;
                    }
                    if (valueBytes.Length > 0)
                    {
                        //MemoryStream to store decrypted body to
                        using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(att.Value)))
                        {
                            using (CryptoStream cstream = new CryptoStream(stream, cryptoTrans, CryptoStreamMode.Read))
                            {
                                byte[] decrypted = new byte[valueBytes.Length];
                                try
                                {
                                    int bytesRead = cstream.Read(decrypted, 0, valueBytes.Length);
                                    if (bytesRead > 0)
                                    {
                                        string decryptedValue = Convert.ToBase64String(decrypted);
                                        string json           = "{\"Body\":\"" + decryptedValue + "\"}";
                                        try
                                        {
                                            response = await ReadFromSalesForce(new Uri(creds["serverUrl"] + "/sobjects/" + obj + "/" + att.Key),
                                                                                creds, new HttpMethod("PATCH"), json);
                                        }
                                        catch (Exception ex)
                                        {
                                            Trace.TraceError("An exception occured while working in write mode.\n" +
                                                             ex.Message);
                                        }

                                        if (response != null && response.Content != null && response.StatusCode == HttpStatusCode.OK)
                                        {
                                            Trace.TraceInformation($"{att.Key} has been successfully updated by {guid}.");
                                        }
                                        else if (response.StatusCode == HttpStatusCode.NoContent)
                                        {
                                            Trace.TraceInformation($"{att.Key}'s content has obviously been modified by {guid}, though \"no content\" has been returned.");
                                        }
                                        else
                                        {
                                            Trace.TraceError($"{att.Key} failed to update by {guid}. {response?.StatusCode}");
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Trace.TraceError($"{ex.Message}\noccured while trying to update {att.Key} from {guid}");
                                }
                            }
                        }
                    }
                    else
                    {
                        Trace.TraceError($"{att.Key} didn't give any body for writing.");
                    }
                }
                else
                {
                    minSizeQueue.Close();
                    break;
                }
            }
            Trace.TraceInformation($"A worker {guid} has finished the work.");
        }