Exemple #1
0
        private static string downloadUpdateFile(string dirName, string update, string name, string version, string[] args)
        {
            var r   = new response();
            var url = "http://" + (update + "/update/" + name + "-" + version + ".updt").Replace("//", "/");

            var savePath = Path.Combine(dirName, name + "-" + version + ".updt");
            var fi       = new FileInfo(savePath);

            if (fi.Exists)
            {
                toUpdateLog("target file always downloaded");
                if (
                    DateTime.Now.ToFileTime() - fi.CreationTime.ToFileTime() < 24 * (3600L * 1000 * 10000)
                    )
                {
                    if (fi.Length == 0)
                    {
                        toUpdateLog("update is cancelled: file already loaded and applied - " + savePath);
                        // File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Данный файл уже закачан", savePath));
                        return("");
                    }
                    else
                    {
                        toUpdateLog("update: file already loaded, but not applied - " + savePath);
                        return(savePath);
                    }
                }
                else
                {
                    toUpdateLog("early downloaded file to delete");
                    File.Delete(savePath);
                    toUpdateLog("early downloaded file deleted");
                }
            }

            deleteOldUpdtFiles(dirName, name, savePath);

            toUpdateLog("try to get file from url " + url);

            byte[] file         = null;
            int    countOfTryes = 0;
            bool   loaded       = false;

            do
            {
                try
                {
                    countOfTryes++;

                    file = r.getFile(url, null);

                    loaded = file != null;
                    if (!loaded)
                    {
                        stopEvent.WaitOne(7148);
                    }
                }
                catch (Exception e)
                {
                    toUpdateLog("get file return null - update failure. Error message " + e.Message + "\r\n" + e.StackTrace);
                    if (countOfTryes > 3 || stopEvent.WaitOne(7148))    // ждём 7,148 секунд
                    {
                        return(null);
                    }
                }
            }while (!loaded && countOfTryes < 4);

            if (file == null)
            {
                toUpdateLog("get file return null - update failure");
                return(null);
            }
            toUpdateLog("" + file.Length + " bytes getted from url " + url);

            // :$$$.проверкаПодлинности\ :проверкаПодлинности :безопасность
            using (var ms = new MemoryStream(file))
            {
                var totalSize = readInt(ms);
                if (totalSize != file.Length)
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: размер файла не совпадает с заявленным", "Отсутствует / downloadUpdateFile"));
                    MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет неверный формат.", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                var headersSize   = readInt(ms);
                var size          = readInt(ms);
                var headSignature = Encoding.UTF8.GetBytes("\r\nFDSC PACK / prg.8vs.ru\r\n");
                if (headSignature.Length != size)
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: размер сигнатуры не совпадает с заявленным", "Отсутствует / downloadUpdateFile"));
                    MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет неверный формат.", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                var b = readArray(ms, headSignature.Length);
                if (!checkArray(headSignature, b))
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: неверная сигнатура типа файла", "Отсутствует / downloadUpdateFile"));
                    MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет неверный формат.", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                size = readInt(ms); // Длинна имени ключа
                var keyNameBlob = readArray(ms, size);
                var keyName     = Encoding.GetEncoding("windows-1251").GetString(keyNameBlob);

                size = readInt(ms); // подпись sha512
                var shas = readArray(ms, size);

                size = readInt(ms); // подпись md5
                var md5s = readArray(ms, size);

                if (headersSize != ms.Position - 8)
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: размер заголовков не совпадает с заявленным", "Отсутствует / downloadUpdateFile"));
                    MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет неверный формат.", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                var packetSize = readInt(ms);
                if (totalSize - ms.Position != packetSize)
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: размер пакета не совпадает с заявленным", "Отсутствует / downloadUpdateFile"));
                    MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет неверный формат.", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }
                var packet = readArray(ms, packetSize);

                var keyFileName = keyName + ".pub";
                if (!File.Exists(keyFileName))
                {
                    File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл, полученный с " + url + ", имеет неизвестный ключ подписи: это может быть следствием ошибки обновления или атаки со стороны третьих лиц", keyFileName));
                    MessageBox.Show("Файл, полученный с " + url + ", имеет неизвестный ключ подписи: это может быть следствием ошибки обновления или атаки со стороны третьих лиц", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                using (CngKey DSKey = CngKey.Import(File.ReadAllBytes(keyFileName), CngKeyBlobFormat.EccPublicBlob))
                {
                    using (var ecdsa = new ECDsaCng(DSKey))
                    {
                        ecdsa.HashAlgorithm = CngAlgorithm.Sha512;
                        if (!ecdsa.VerifyData(packet, shas))
                        {
                            File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: подпись sha512 не подлинная. Это может быть ошибка обновления или неуспешная попытка атаки на обновляемый компьютер со стороны третьих лиц", "Отсутствует / downloadUpdateFile"));
                            MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет подпись sha512, которая не прошла проверку подлинности. Это может быть ошибка обновления или неуспешная попытка атаки на обновляемый компьютер со стороны третьих лиц", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return(null);
                        }

                        ecdsa.HashAlgorithm = CngAlgorithm.MD5;
                        if (!ecdsa.VerifyData(packet, md5s))
                        {
                            File.AppendAllText(errorFileName, String.Format(errorMessage, DateTime.Now, "Файл имеет неверный формат: подпись md5 не подлинная. Это может быть ошибка обновления или неуспешная попытка атаки на обновляемый компьютер со стороны третьих лиц", "Отсутствует / downloadUpdateFile"));
                            MessageBox.Show("Файл обновления, полученный с '" + url + "' имеет подпись md5, которая не прошла проверку подлинности. Это может быть ошибка обновления или неуспешная попытка атаки на обновляемый компьютер со стороны третьих лиц", "Ошибка обновления", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return(null);
                        }
                    }
                }
            }


            toUpdateLog("get and verify file - success");
            File.WriteAllBytes(savePath, file);
            new FileInfo(savePath).CreationTime = DateTime.Now;

            toUpdateLog(String.Format("save file to '{0}' - success", savePath));
            return(savePath);
        }
Exemple #2
0
        static int Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException +=
                new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            Directory.SetCurrentDirectory(Path.GetDirectoryName(Application.ExecutablePath));

            toUpdateLog("started\r\n" + stringArrayToLogString(args, "\t"));
            if (!s.WaitOne(0))
            {
                Console.WriteLine("semaphore locked to umove.exe; exited");
                toUpdateLog("semaphore locked to umove.exe; exited");
                return(3);
            }

            var umove = false;

            try
            {
                argsString = getArgumentsFromArgArray(args);

                if (args.Length == 1 && args[0] == "-umove")
                {
                    var result = umoveRename();
                    toUpdateLog("-umove");
                    umove = true;
                }
                else
                {
                    umoveRename();
                }

                if (args.Length == 1 && args[0] == "-v")
                {
                    AllocConsole();
                    Console.WriteLine(version);
                    Console.ReadKey();
                    FreeConsole();
                    return(0);
                }

                createOrParseIni();

                var uuPath = downloadUpdate(Directory.GetCurrentDirectory(), opts["updatorDir", ""].Replace("$$$", "update"), "update", version, args);
                if (!String.IsNullOrEmpty(uuPath))
                {
                    try
                    {
                        File.WriteAllText("uup.flag", Path.GetFullPath(uuPath) + "\r\n");
                        Process.Start("umove.exe", "uup.flag \"vs8.ru updator semaphore\" 50 \"\"");
                    }
                    catch (Exception e)
                    {
                        toUpdateLog(e.Message + "\r\n" + e.StackTrace);
                    }
                }

                if (umove)
                {
                    return(51);
                }

                if (
                    args.Length > 3 || args.Length < 3 ||
                    (args.Length == 1 && (args[0] == "-?" || args[0] == "/?" || args[0] == "/help" || args[0].ToLower() == "--help"))
                    )
                {
                    AllocConsole();
                    Console.WriteLine("updatorvs8.exe updateName version path_to_dwnl");
                    Console.WriteLine("for example: updatorvs8.exe relaxtime 20110929 D:/rtbd/");
                    Console.WriteLine("warning: umove.exe must be place to same directory updatorvs8.exe");
                    Console.ReadKey();
                    FreeConsole();
                    return(1);
                }

                var dirName = args[2];
                if (!Directory.Exists(dirName))
                {
                    Console.WriteLine(String.Format("update directory '{0}' is not exists", args[1]));
                    return(2);
                }

                var updateFlagFile = Path.Combine(new string[] { dirName, "update.flag" });
                File.Delete(updateFlagFile);

                var updatedPath =
                    downloadUpdate(dirName, opts["updateDir", ""].Replace("$$$", args[0]), args[0], args[1], args);

                var updated = !String.IsNullOrEmpty(updatedPath);
                if (updated)
                {
                    File.WriteAllText(updateFlagFile, Path.GetFullPath(updatedPath) + "\r\n");
                    Console.WriteLine("success");
                    toUpdateLog("success");

                    if (args[0] == "relaxtime")
                    {
                        try
                        {
                            var resp = new response();
                            resp.getFile("http://mc.yandex.ru/watch/15915832", @"http://relaxtime.8vs.ru/success.html?guid=" + opts["updatorGUID"]);
                        }
                        catch (Exception e)
                        {
                            toUpdateLog("success and error: " + e.Message);
                        }
                    }
                }
                else
                {
                    if (updatedPath == null)
                    {
                        Console.WriteLine("failure");
                        toUpdateLog("failure");

                        if (args[0] == "relaxtime")
                        {
                            try
                            {
                                var resp = new response();
                                resp.getFile("http://mc.yandex.ru/watch/15915832", @"http://relaxtime.8vs.ru/failure.html?guid=" + opts["updatorGUID"]);
                            }
                            catch (Exception e)
                            {
                                toUpdateLog("failure and error: " + e.Message);
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("neutral");
                        toUpdateLog("neutral");

                        if (args[0] == "relaxtime")
                        {
                            try
                            {
                                var resp = new response();
                                resp.getFile("http://mc.yandex.ru/watch/15915832", @"http://relaxtime.8vs.ru/neutral.html?guid=" + opts["updatorGUID"]);
                            }
                            catch (Exception e)
                            {
                                toUpdateLog("neutral and error: " + e.Message);
                            }
                        }
                    }
                }

                toUpdateLog("ended");

                var fi = new FileInfo(updatorLogFileName);
                truncateLog(fi);

                if (updated)
                {
                    return(0);
                }
                else
                {
                    return(11);
                }
            }
            finally
            {
                s.Release();
                s.Close();
            }
        }