예제 #1
0
        public static byte[] Get(string name, TimeSpan cachePeriod)
        {
            var key           = Hex.ToHexString(Sha256.Compute(Encoding.UTF8.GetBytes(name)));
            var fileExtension = "cache";
            var fileName      = $"{key}.{fileExtension}";
            var filePath      = Path.Combine(DefaultCacheFolder, fileName);

            try
            {
                if (!Directory.Exists(DefaultCacheFolder))
                {
                    Directory.CreateDirectory(DefaultCacheFolder);
                }

                var fileInfo = new FileInfo(filePath);

                if (fileInfo.Length > MaxCacheFileSize)
                {
                    return(null);
                }

                if (cachePeriod != TimeSpan.MaxValue && fileInfo.LastWriteTimeUtc + cachePeriod < DateTime.UtcNow)
                {
                    return(null);
                }

                return(File.ReadAllBytes(filePath));
            }
            catch (Exception e)
            {
                Log.Error(e, "FileCache.Get error.");
            }

            return(null);
        }
예제 #2
0
        public string GetUserId(uint keyIndex = 0)
        {
            using var servicePublicKey = Wallet.GetServicePublicKey(keyIndex);
            using var publicKey        = servicePublicKey.ToUnsecuredBytes();

            return(Sha256.Compute(Sha256.Compute(publicKey)).ToHexString());
        }
예제 #3
0
        // FIXME: This is duplicate of beacon node, need to clean up
        public byte[] GeneratePrivateKey(ulong index)
        {
            Span <byte> input             = new Span <byte>(new byte[32]);
            BigInteger  bigIndex          = new BigInteger(index);
            bool        indexWriteSuccess = bigIndex.TryWriteBytes(input, out int indexBytesWritten, isUnsigned: true, isBigEndian: false);

            if (!indexWriteSuccess || indexBytesWritten == 0)
            {
                throw new Exception("Error getting input for quick start private key generation.");
            }

            Bytes32             bytes32 = Sha256.Compute(input);
            ReadOnlySpan <byte> hash    = bytes32.AsSpan();
            // Mocked start interop specifies to convert the hash as little endian (which is the default for BigInteger)
            BigInteger value      = new BigInteger(hash.ToArray(), isUnsigned: true);
            BigInteger privateKey = value % s_curveOrder;

            // Note that the private key is an *unsigned*, *big endian* number
            // However, we want to pad the big endian on the left to get 32 bytes.
            // So, write as little endian (will pad to right), then reverse.
            // NOTE: Alternative, write to Span 64, and then slice based on bytesWritten to get the padding.
            Span <byte> privateKeySpan  = new Span <byte>(new byte[32]);
            bool        keyWriteSuccess = privateKey.TryWriteBytes(privateKeySpan, out int keyBytesWritten, isUnsigned: true, isBigEndian: false);

            if (!keyWriteSuccess)
            {
                throw new Exception("Error generating quick start private key.");
            }
            privateKeySpan.Reverse();

            return(privateKeySpan.ToArray());
        }
예제 #4
0
            private static Stream RemoveHash(Stream stream)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }

                int type = (int)Varint.GetUInt64(stream);

                if (type == (int)ConvertHashAlgorithm.Sha256)
                {
                    var value = new byte[32];
                    stream.Read(value, 0, value.Length);

                    var dataStream = new RangeStream(stream, true);
                    if (!Unsafe.Equals(value, Sha256.Compute(new WrapperStream(dataStream))))
                    {
                        throw new ArgumentException("Hash");
                    }

                    dataStream.Seek(0, SeekOrigin.Begin);
                    return(dataStream);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
예제 #5
0
        public static byte[] GetSessionPasswordBytes(
            SecureString password,
            int hashIterationsCount = DefaultHashIterationsCount)
        {
            var passwordBytes = password.ToBytes();
            var passwordHash  = Sha256.Compute(passwordBytes, hashIterationsCount);

            Array.Clear(passwordBytes, 0, passwordBytes.Length);

            return(passwordHash);
        }
예제 #6
0
        private static void BuildZeroHashes()
        {
            Span <UInt256> concatenation = stackalloc UInt256[2];

            UInt256.CreateFromLittleEndian(out ZeroHashes[0], Hash32.Zero.Bytes);
            for (int i = 1; i < 64; i++)
            {
                var previous = ZeroHashes[i - 1];
                MemoryMarshal.CreateSpan(ref previous, 1).CopyTo(concatenation.Slice(0, 1));
                MemoryMarshal.CreateSpan(ref previous, 1).CopyTo(concatenation.Slice(1, 1));
                UInt256.CreateFromLittleEndian(out ZeroHashes[i], Sha256.Compute(MemoryMarshal.Cast <UInt256, byte>(concatenation)).Bytes);
            }
        }
        public AutoMapper_UserAPI_UsersProfile()
        {
            #region DB -> API
            CreateMap <UsersDB_UserDTO, UserAPI_GetProfileDTO>();
            #endregion

            #region API -> DB
            CreateMap <UserAPI_SignUpDTO, UsersDB_UserDTO>()
            .ForMember(x => x.PasswordHash,
                       x => x.MapFrom(m => Sha256.Compute(m.Password)))
            .ForMember(x => x.RegistrationDate,
                       x => x.MapFrom(m => DateTime.UtcNow));
            #endregion
        }
예제 #8
0
        public void MessageUpload()
        {
            _callback.Invoke("----- CoreManager Message Upload Test (Start) -----");
            _callback.Invoke("");

            var random = RandomProvider.GetThreadRandom();

            _coreManager.Resize((long)1024 * 1024 * 1024 * 32).Wait();

            Metadata metadata = null;
            Hash     hash;

            using (var stream = new RecyclableMemoryStream(_bufferManager))
            {
                using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                {
                    for (long remain = (long)1024 * 1024 * 256; 0 < remain; remain -= safeBuffer.Value.Length)
                    {
                        int length = (int)Math.Min(remain, safeBuffer.Value.Length);

                        random.NextBytes(safeBuffer.Value);
                        stream.Write(safeBuffer.Value, 0, length);
                    }
                }

                stream.Seek(0, SeekOrigin.Begin);
                hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(new WrapperStream(stream)));

                stream.Seek(0, SeekOrigin.Begin);
                metadata = _coreManager.VolatileSetStream(stream, new TimeSpan(1, 0, 0, 0), CancellationToken.None).Result;
            }

            using (var stream = metadata.Export(_bufferManager))
                using (var safeBuffer = _bufferManager.CreateSafeBuffer((int)stream.Length))
                {
                    stream.Read(safeBuffer.Value, 0, (int)stream.Length);
                    Console.WriteLine(NetworkConverter.ToBase64UrlString(safeBuffer.Value, 0, (int)stream.Length));
                }

            using (var stream = hash.Export(_bufferManager))
                using (var safeBuffer = _bufferManager.CreateSafeBuffer((int)stream.Length))
                {
                    stream.Read(safeBuffer.Value, 0, (int)stream.Length);
                    Console.WriteLine(NetworkConverter.ToBase64UrlString(safeBuffer.Value, 0, (int)stream.Length));
                }

            _callback.Invoke("----- CoreManager Message Upload Test (End) -----");
        }
예제 #9
0
        public static void Set(string name, byte[] data)
        {
            var key           = Hex.ToHexString(Sha256.Compute(Encoding.UTF8.GetBytes(name)));
            var fileExtension = "cache";
            var fileName      = $"{key}.{fileExtension}";
            var filePath      = Path.Combine(DefaultCacheFolder, fileName);

            try
            {
                File.WriteAllBytes(filePath, data);
            }
            catch (Exception e)
            {
                Log.Error(e, "FileCache.Set error.");
            }
        }
예제 #10
0
        public AutoMapper_MemberAPI_MembersProfile()
        {
            #region DB -> API
            CreateMap <MembersDB_MemberDTO, UserAPI_GetMembersItemDTO>();
            #endregion

            #region API -> DB
            CreateMap <MemberAPI_SignUpDTO, MembersDB_MemberDTO>()
            .ForMember(x => x.PasswordHash,
                       x => x.MapFrom(m =>
                                      Sha256.Compute(m.Password)))
            .ForMember(x => x.RoomId,
                       x => x.MapFrom(m =>
                                      ObjectId.Parse(m.RoomId)));
            #endregion
        }
예제 #11
0
            private static Stream AddHash(Stream stream)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }

                var hashStream = new RecyclableMemoryStream(_bufferManager);

                {
                    Varint.SetUInt64(hashStream, (uint)ConvertHashAlgorithm.Sha256);
                    var value = Sha256.Compute(new WrapperStream(stream));
                    hashStream.Write(value, 0, value.Length);
                }

                return(new UniteStream(hashStream, stream));
            }
예제 #12
0
        public void ReadWriteTest()
        {
            for (int i = 0; i < 256; i++)
            {
                int size = _random.Next(1, 1024 * 1024 * 4);

                using (var safeBuffer = _bufferManager.CreateSafeBuffer(size))
                {
                    _random.NextBytes(safeBuffer.Value);

                    var block = new ArraySegment <byte>(safeBuffer.Value, 0, size);
                    var hash  = new Hash(HashAlgorithm.Sha256, Sha256.Compute(block));

                    _cacheManager.Set(hash, block);
                    var result = _cacheManager.GetBlock(hash);

                    Assert.True(Unsafe.Equals(block.Array, block.Offset, result.Array, result.Offset, size));

                    _bufferManager.ReturnBuffer(result.Array);
                }
            }
        }
예제 #13
0
 public static byte[] CreateSwapSecretHash(byte[] secretBytes) =>
 Sha256.Compute(secretBytes, 2);
예제 #14
0
        public static ImportExternalTransactionDataResults ImportExternalTransactionData(ExternalBankData import, ImportExternalTransactionDataArgs args)
        {
            FinancialAccount assetAccount       = args.Account;
            FinancialAccount autoDepositAccount = args.Organization.FinancialAccounts.IncomeDonations;
            int autoDepositLimit = 0; // Disabled; TODO: this.CurrentOrganization.Parameters.AutoDonationLimit;

            bool autosetInitialBalance = false;
            ImportExternalTransactionDataResults result = new ImportExternalTransactionDataResults();
            int   count = 0;
            int   progressUpdateInterval = import.Records.Length / 40;
            Int64 importedCentsTotal     = 0;

            if (progressUpdateInterval > 100)
            {
                progressUpdateInterval = 100;
            }

            ProgressBarBackend progressDisplay = new ProgressBarBackend(args.Guid);

            Currency organizationCurrency = assetAccount.Organization.Currency;
            Currency accountCurrency      = assetAccount.ForeignCurrency;

            if (accountCurrency == null)
            {
                accountCurrency = organizationCurrency;
            }

            FinancialAccountRows existingRows = assetAccount.GetRows(Constants.DateTimeLow, Constants.DateTimeHigh);

            // gets all
            if (existingRows.Count == 0)
            {
                autosetInitialBalance = true;
            }


            foreach (ExternalBankDataRecord row in import.Records)
            {
                // Update progress.

                count++;
                if (progressUpdateInterval < 2 || count % progressUpdateInterval == 0)
                {
                    int percent = (count * 99) / import.Records.Length;

                    progressDisplay.Set(percent);
                }

                // Update high- and low-water marks.

                if (row.DateTime < result.EarliestTransaction)
                {
                    result.EarliestTransaction = row.DateTime;
                }

                if (row.DateTime > result.LatestTransaction)
                {
                    result.LatestTransaction = row.DateTime;
                }


                string importKey = row.ImportHash;

                Int64 amountCents = row.TransactionNetCents;

                if (amountCents == 0)
                // defensive programming - these _should_ be duplicated in the interpreter if no "fee" field
                {
                    amountCents = row.TransactionGrossCents;
                }

                Int64 foreignCents = amountCents;
                importedCentsTotal += amountCents;

                if (accountCurrency.Identity != organizationCurrency.Identity)
                {
                    amountCents =
                        new Money(amountCents, accountCurrency, row.DateTime).ToCurrency(organizationCurrency).Cents;
                }

                FinancialTransaction transaction = FinancialTransaction.ImportWithStub(args.Organization.Identity,
                                                                                       row.DateTime,
                                                                                       assetAccount.Identity, amountCents,
                                                                                       row.Description, importKey, Sha256.Compute(row.RawData),
                                                                                       args.CurrentUser.Identity);

                if (transaction != null)
                {
                    // The transaction was created.

                    result.TransactionsImported++;

                    // If non-presentation currency, log the account currency amount as well.

                    if (accountCurrency.Identity != organizationCurrency.Identity)
                    {
                        transaction.Rows[0].AmountForeignCents = new Money(foreignCents, accountCurrency);
                    }

                    if (row.Description.ToLowerInvariant().StartsWith(args.Organization.IncomingPaymentTag))
                    {
                        // Check for previously imported payment group

                        // TODO: MAKE FLEXIBLE - CALL PAYMENTREADERINTERFACE!
                        // HACK HACK HACK HACK

                        PaymentGroup group = PaymentGroup.FromTag(args.Organization,
                                                                  "SEBGM" + DateTime.Today.Year + // TODO: Get tags from org
                                                                  row.Description.Substring(args.Organization.IncomingPaymentTag.Length).Trim());

                        if (group != null && group.Open)
                        {
                            // There was a previously imported and not yet closed payment group matching this transaction
                            // Close the payment group and match the transaction against accounts receivable

                            transaction.Dependency = group;
                            group.Open             = false;
                            transaction.AddRow(args.Organization.FinancialAccounts.AssetsOutboundInvoices, -amountCents,
                                               args.CurrentUser);
                        }
                    }
                    else if (amountCents < 0)
                    {
                        // Autowithdrawal mechanisms removed, condition kept because of downstream else-if conditions
                    }
                    else if (amountCents > 0)
                    {
                        if (row.FeeCents < 0)
                        {
                            // This is always an autodeposit, if there is a fee (which is never > 0.0)

                            transaction.AddRow(args.Organization.FinancialAccounts.CostsBankFees, -row.FeeCents,
                                               args.CurrentUser);
                            transaction.AddRow(autoDepositAccount, -row.TransactionGrossCents, args.CurrentUser);
                        }
                        else if (amountCents < autoDepositLimit * 100)
                        {
                            // Book against autoDeposit account.

                            transaction.AddRow(autoDepositAccount, -amountCents, args.CurrentUser);
                        }
                    }
                }
                else
                {
                    // Transaction was not imported; assume duplicate

                    result.DuplicateTransactions++;
                }
            }

            // Import complete. Return true if the bookkeeping account matches the bank data.

            Int64 databaseAccountBalanceCents;

            if (accountCurrency.Identity == organizationCurrency.Identity)
            {
                databaseAccountBalanceCents = assetAccount.BalanceTotalCents;
            }
            else
            {
                // foreign-currency account
                databaseAccountBalanceCents = assetAccount.ForeignCurrencyBalance.Cents;
            }


            // Subtract any transactions made after the most recent imported transaction.
            // This is necessary in case of Paypal and others which continuously feed the
            // bookkeeping account with new transactions; it will already have fed transactions
            // beyond the end-of-file.

            Int64 beyondEofCents = assetAccount.GetDeltaCents(result.LatestTransaction.AddSeconds(1),
                                                              DateTime.Now.AddDays(2));

            // Caution: the "AddSeconds(1)" is not foolproof, there may be other new txs on the same second.

            if (databaseAccountBalanceCents - beyondEofCents == import.LatestAccountBalanceCents)
            {
                Payouts.AutomatchAgainstUnbalancedTransactions(args.Organization);
                OutboundInvoices.AutomatchAgainstUnbalancedTransactions(args.Organization, args.CurrentUser);
                result.AccountBalanceMatchesBank = true;
                result.BalanceMismatchCents      = 0;
            }
            else
            {
                result.AccountBalanceMatchesBank = false;
                result.BalanceMismatchCents      = (databaseAccountBalanceCents - beyondEofCents) -
                                                   import.LatestAccountBalanceCents;

                if (autosetInitialBalance)
                {
                    Int64 newInitialBalanceCents = -result.BalanceMismatchCents;
                    Money initialBalance         = new Money(newInitialBalanceCents, accountCurrency);

                    assetAccount.InitialBalance       = initialBalance;
                    result.InitialBalanceCents        = newInitialBalanceCents;
                    result.InitialBalanceCurrencyCode = accountCurrency.Code;

                    // make an approximation of conversion rate set for initial balance in presentation to tell user
                    initialBalance.ValuationDateTime = new DateTime(assetAccount.Organization.FirstFiscalYear, 1, 1);
                    result.BalanceMismatchCents      = initialBalance.ToCurrency(assetAccount.Organization.Currency).Cents;
                }
            }

            result.CurrencyCode = args.Organization.Currency.Code;
            GuidCache.Set(args.Guid + "-Results", result);
            return(result);
        }
예제 #15
0
        public bool Run()
        {
            try
            {
                // スリープを禁止する。
                NativeMethods.SetThreadExecutionState(NativeMethods.ExecutionState.Continuous);

                // カレントディレクトリをexeと同じディレクトリパスへ変更。
                Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));

                // ハンドルしていない例外をログ出力させる。
                Thread.GetDomain().UnhandledException += this.Program_UnhandledException;

                string sessionId = NetworkConverter.ToHexString(Sha256.Compute(Path.GetFullPath(Assembly.GetEntryAssembly().Location)));

                // 多重起動防止
                {
                    _mutex = new Mutex(false, sessionId);

                    if (!_mutex.WaitOne(0))
                    {
                        return(false);
                    }
                }

                // 既定のフォルダを作成する。
                {
                    foreach (var propertyInfo in typeof(AmoebaEnvironment.PathsEnvironment).GetProperties())
                    {
                        string path = propertyInfo.GetValue(AmoebaEnvironment.Paths) as string;
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                    }
                }

                // Tempフォルダを環境変数に登録。
                {
                    // Tempフォルダ内を掃除。
                    try
                    {
                        foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.TempDirectoryPath, "*", SearchOption.AllDirectories))
                        {
                            File.Delete(path);
                        }

                        foreach (string path in Directory.GetDirectories(AmoebaEnvironment.Paths.TempDirectoryPath, "*", SearchOption.AllDirectories))
                        {
                            Directory.Delete(path, true);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    Environment.SetEnvironmentVariable("TMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempDirectoryPath), EnvironmentVariableTarget.Process);
                    Environment.SetEnvironmentVariable("TEMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempDirectoryPath), EnvironmentVariableTarget.Process);
                }

                // ログファイルを設定する。
                this.Setting_Log();

                // アップデート
                {
                    // 一時的に作成された"Amoeba.Update.exe"を削除する。
                    {
                        string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Amoeba.Update.exe");

                        if (File.Exists(tempUpdateExeFilePath))
                        {
                            File.Delete(tempUpdateExeFilePath);
                        }
                    }

                    if (Directory.Exists(AmoebaEnvironment.Paths.UpdateDirectoryPath))
                    {
                        string zipFilePath = null;

                        // 最新のバージョンのzipを検索。
                        {
                            var map   = new Dictionary <string, Version>();
                            var regex = new Regex(@"Amoeba.+?((\d*)\.(\d*)\.(\d*)).*?\.zip", RegexOptions.Compiled);

                            foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.UpdateDirectoryPath))
                            {
                                var match = regex.Match(Path.GetFileName(path));
                                if (!match.Success)
                                {
                                    continue;
                                }

                                var version = new Version(match.Groups[1].Value);
                                if (version < AmoebaEnvironment.Version)
                                {
                                    continue;
                                }

                                map.Add(path, version);
                            }

                            if (map.Count > 0)
                            {
                                var sortedList = map.ToList();
                                sortedList.Sort((x, y) => y.Value.CompareTo(x.Value));

                                zipFilePath = sortedList.First().Key;
                            }
                        }

                        if (zipFilePath != null)
                        {
                            string tempUpdateDirectoryPath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Update");

                            if (Directory.Exists(tempUpdateDirectoryPath))
                            {
                                Directory.Delete(tempUpdateDirectoryPath, true);
                            }

                            using (var zipfile = new ZipFile(zipFilePath))
                            {
                                zipfile.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
                                zipfile.ExtractAll(tempUpdateDirectoryPath);
                            }

                            if (File.Exists(zipFilePath))
                            {
                                File.Delete(zipFilePath);
                            }

                            string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Amoeba.Update.exe");

                            File.Copy("Amoeba.Update.exe", tempUpdateExeFilePath);

                            var startInfo = new ProcessStartInfo();
                            startInfo.FileName  = Path.GetFullPath(tempUpdateExeFilePath);
                            startInfo.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"",
                                                                sessionId,
                                                                Path.GetFullPath(Path.Combine(tempUpdateDirectoryPath, "Core")),
                                                                Path.GetFullPath(AmoebaEnvironment.Paths.CoreDirectoryPath),
                                                                Path.GetFullPath(Assembly.GetEntryAssembly().Location));
                            startInfo.WorkingDirectory = Path.GetFullPath(Path.GetDirectoryName(tempUpdateExeFilePath));

                            Process.Start(startInfo);

                            return(false);
                        }
                    }
                }

                // マイグレーション
                {
                    if (AmoebaEnvironment.Config.Version <= new Version(5, 0, 60))
                    {
                        try
                        {
                            var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Service\Core\Cache");

                            if (!Directory.Exists(Path.Combine(basePath, "Blocks")))
                            {
                                Directory.CreateDirectory(Path.Combine(basePath, "Blocks"));
                            }

                            var renameList = new List <(string oldPath, string newPath)>();
                            renameList.Add((@"CacheInfos.json.gz", @"ContentInfos.json.gz"));
                            renameList.Add((@"Size.json.gz", @"Blocks\Size.json.gz"));
                            renameList.Add((@"ClusterIndex.json.gz", @"Blocks\ClusterIndex.json.gz"));

                            foreach (var(oldPath, newPath) in renameList)
                            {
                                if (File.Exists(Path.Combine(basePath, newPath)) ||
                                    !File.Exists(Path.Combine(basePath, oldPath)))
                                {
                                    continue;
                                }

                                File.Copy(Path.Combine(basePath, oldPath), Path.Combine(basePath, newPath));
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }

                    if (AmoebaEnvironment.Config.Version <= new Version(5, 1, 1))
                    {
                        try
                        {
                            var sourcePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"View\Settings");
                            var destPath   = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Control\Settings");

                            if (Directory.Exists(sourcePath))
                            {
                                if (!Directory.Exists(destPath))
                                {
                                    Directory.CreateDirectory(destPath);
                                }

                                foreach (var oldPath in Directory.GetFiles(sourcePath))
                                {
                                    var newPath = Path.Combine(destPath, Path.GetFileName(oldPath));
                                    if (File.Exists(newPath) || !File.Exists(oldPath))
                                    {
                                        continue;
                                    }

                                    File.Copy(oldPath, newPath);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }

                        try
                        {
                            var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Control\Settings");

                            var renameList = new List <(string oldPath, string newPath)>();
                            renameList.Add((@"AccountInfo.json.gz", @"AccountSetting.json.gz"));
                            renameList.Add((@"UpdateInfo.json.gz", @"UpdateSetting.json.gz"));

                            foreach (var(oldPath, newPath) in renameList
                                     .Select(tuple => (Path.Combine(basePath, tuple.oldPath), Path.Combine(basePath, tuple.newPath))))
                            {
                                if (File.Exists(newPath) || !File.Exists(oldPath))
                                {
                                    continue;
                                }

                                File.Copy(oldPath, newPath);
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }
                }

#if !DEBUG
                // デーモンプロセス起動。
                {
                    var daemonExeFilePath    = Path.Combine(AmoebaEnvironment.Paths.DaemonDirectoryPath, "Amoeba.Daemon.exe");
                    var daemonConfigFilePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, "Daemon.toml");

                    if (!File.Exists(daemonConfigFilePath))
                    {
                        // 「Amoeba/Core/Daemon」のような階層を想定。
                        var basePath = "../../";

                        var config = new DaemonConfig(
                            new Version(0, 0, 0),
                            new DaemonConfig.CommunicationConfig("tcp:127.0.0.1:4040"),
                            new DaemonConfig.CacheConfig(Path.Combine(basePath, "Config", "Cache.blocks")),
                            new DaemonConfig.PathsConfig(
                                Path.Combine(basePath, "Temp"),
                                Path.Combine(basePath, "Config", "Service"),
                                Path.Combine(basePath, "Log")));

                        var tomlSettings = TomlSettings.Create(builder => builder
                                                               .ConfigureType <Version>(type => type
                                                                                        .WithConversionFor <TomlString>(convert => convert
                                                                                                                        .ToToml(tt => tt.ToString())
                                                                                                                        .FromToml(ft => Version.Parse(ft.Value)))));

                        Toml.WriteFile(config, daemonConfigFilePath, tomlSettings);
                    }

                    var startInfo = new ProcessStartInfo();
                    startInfo.FileName        = daemonExeFilePath;
                    startInfo.Arguments       = string.Format("-c \"{0}\"", daemonConfigFilePath);
                    startInfo.CreateNoWindow  = true;
                    startInfo.UseShellExecute = false;

                    try
                    {
                        _process = Process.Start(startInfo);
                    }
                    catch (Exception)
                    {
                        return(false);
                    }
                }
#endif

                return(true);
            }
            catch (Exception ex)
            {
                Log.Error(ex);

                return(false);
            }
        }
예제 #16
0
 private static Chunk Compute(Span <Chunk> span)
 {
     return(MemoryMarshal.Cast <byte, Chunk>(Sha256.Compute(MemoryMarshal.Cast <Chunk, byte>(span)).Bytes)[0]);
 }
예제 #17
0
            public ArraySegment <byte>?Get(Hash hash)
            {
                ArraySegment <byte> result;

                lock (_lockObject)
                {
                    ClusterInfo clusterInfo = null;

                    if (_clusterIndex.TryGetValue(hash, out clusterInfo))
                    {
                        clusterInfo.UpdateTime = DateTime.UtcNow;
                    }

                    if (clusterInfo == null)
                    {
                        return(null);
                    }

                    var buffer = _bufferManager.TakeBuffer(clusterInfo.Length);

                    try
                    {
                        for (int i = 0, remain = clusterInfo.Length; i < clusterInfo.Indexes.Length; i++, remain -= SectorSize)
                        {
                            long posision = clusterInfo.Indexes[i] * SectorSize;
                            if (posision > _fileStream.Length)
                            {
                                throw new ArgumentOutOfRangeException();
                            }

                            if (_fileStream.Position != posision)
                            {
                                _fileStream.Seek(posision, SeekOrigin.Begin);
                            }

                            int length = Math.Min(remain, SectorSize);

                            _fileStream.Read(_sectorBuffer, 0, _sectorBuffer.Length);
                            Unsafe.Copy(_sectorBuffer, 0, buffer, SectorSize * i, length);
                        }

                        result = new ArraySegment <byte>(buffer, 0, clusterInfo.Length);
                    }
                    catch (Exception e)
                    {
                        _bufferManager.ReturnBuffer(buffer);

                        Log.Error(e);

                        return(null);
                    }
                }

                if (hash.Algorithm == HashAlgorithm.Sha256)
                {
                    if (Unsafe.Equals(Sha256.Compute(result), hash.Value))
                    {
                        return(result);
                    }
                    else
                    {
                        _bufferManager.ReturnBuffer(result.Array);

                        this.Remove(hash);

                        return(null);
                    }
                }
                else
                {
                    throw new FormatException();
                }
            }
예제 #18
0
            public void Set(Hash hash, ArraySegment <byte> value)
            {
                if (value.Count > 1024 * 1024 * 32)
                {
                    throw new BadBlockException();
                }

                if (hash.Algorithm == HashAlgorithm.Sha256)
                {
                    if (!Unsafe.Equals(Sha256.Compute(value), hash.Value))
                    {
                        throw new BadBlockException();
                    }
                }
                else
                {
                    throw new FormatException();
                }

                lock (_lockObject)
                {
                    if (this.Contains(hash))
                    {
                        return;
                    }

                    var sectorList = new List <long>();

                    try
                    {
                        sectorList.AddRange(this.GetFreeSectors((value.Count + (SectorSize - 1)) / SectorSize));

                        for (int i = 0, remain = value.Count; i < sectorList.Count && 0 < remain; i++, remain -= SectorSize)
                        {
                            long posision = sectorList[i] * SectorSize;

                            if ((_fileStream.Length < posision + SectorSize))
                            {
                                int  unit = 1024 * 1024 * 256; // 256MB
                                long size = Roundup((posision + SectorSize), unit);

                                _fileStream.SetLength(Math.Min(size, this.Size));
                            }

                            if (_fileStream.Position != posision)
                            {
                                _fileStream.Seek(posision, SeekOrigin.Begin);
                            }

                            int length = Math.Min(remain, SectorSize);

                            Unsafe.Copy(value.Array, value.Offset + (SectorSize * i), _sectorBuffer, 0, length);
                            Unsafe.Zero(_sectorBuffer, length, _sectorBuffer.Length - length);

                            _fileStream.Write(_sectorBuffer, 0, _sectorBuffer.Length);
                        }

                        _fileStream.Flush();
                    }
                    catch (SpaceNotFoundException e)
                    {
                        Log.Error(e);

                        throw e;
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);

                        throw e;
                    }

                    _clusterIndex[hash] = new ClusterInfo(sectorList.ToArray(), value.Count, DateTime.UtcNow);

                    // Event
                    _addedBlockEventQueue.Enqueue(hash);
                }
            }
예제 #19
0
        public Task <Metadata> Import(string path, DateTime creationTime, CancellationToken token)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            return(Task.Run(() =>
            {
                // Check
                lock (_lockObject)
                {
                    var info = _contentInfoManager.GetFileContentInfo(path);
                    if (info != null)
                    {
                        return info.Metadata;
                    }
                }

                Metadata metadata = null;
                var lockedHashes = new HashSet <Hash>();
                ShareInfo shareInfo = null;

                {
                    const int blockLength = 1024 * 1024;
                    const HashAlgorithm hashAlgorithm = HashAlgorithm.Sha256;
                    const CorrectionAlgorithm correctionAlgorithm = CorrectionAlgorithm.ReedSolomon8;

                    int depth = 0;

                    var groupList = new List <Group>();

                    // File
                    using (var stream = new UnbufferedFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None, _bufferManager))
                    {
                        if (stream.Length <= blockLength)
                        {
                            Hash hash;

                            using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength))
                            {
                                int length = (int)stream.Length;
                                stream.Read(safeBuffer.Value, 0, length);

                                if (hashAlgorithm == HashAlgorithm.Sha256)
                                {
                                    hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length));
                                }
                            }

                            shareInfo = new ShareInfo(path, stream.Length, (int)stream.Length, new Hash[] { hash });
                            metadata = new Metadata(depth, hash);
                        }
                        else
                        {
                            var sharedHashes = new List <Hash>();

                            for (; ;)
                            {
                                var targetHashes = new List <Hash>();
                                var targetBuffers = new List <ArraySegment <byte> >();
                                long sumLength = 0;

                                try
                                {
                                    for (int i = 0; stream.Position < stream.Length; i++)
                                    {
                                        token.ThrowIfCancellationRequested();

                                        var buffer = new ArraySegment <byte>();

                                        try
                                        {
                                            int length = (int)Math.Min(stream.Length - stream.Position, blockLength);
                                            buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length);
                                            stream.Read(buffer.Array, 0, length);

                                            sumLength += length;
                                        }
                                        catch (Exception)
                                        {
                                            if (buffer.Array != null)
                                            {
                                                _bufferManager.ReturnBuffer(buffer.Array);
                                            }

                                            throw;
                                        }

                                        Hash hash;

                                        if (hashAlgorithm == HashAlgorithm.Sha256)
                                        {
                                            hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer));
                                        }

                                        sharedHashes.Add(hash);

                                        targetHashes.Add(hash);
                                        targetBuffers.Add(buffer);

                                        if (targetBuffers.Count >= 128)
                                        {
                                            break;
                                        }
                                    }

                                    var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token);
                                    lockedHashes.UnionWith(parityHashes);

                                    groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray()));
                                }
                                finally
                                {
                                    foreach (var buffer in targetBuffers)
                                    {
                                        if (buffer.Array == null)
                                        {
                                            continue;
                                        }

                                        _bufferManager.ReturnBuffer(buffer.Array);
                                    }
                                }

                                if (stream.Position == stream.Length)
                                {
                                    break;
                                }
                            }

                            shareInfo = new ShareInfo(path, stream.Length, blockLength, sharedHashes);

                            depth++;
                        }
                    }

                    while (groupList.Count > 0)
                    {
                        // Index
                        using (var stream = (new Index(groupList)).Export(_bufferManager))
                        {
                            groupList.Clear();

                            if (stream.Length <= blockLength)
                            {
                                Hash hash;

                                using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength))
                                {
                                    int length = (int)stream.Length;
                                    stream.Read(safeBuffer.Value, 0, length);

                                    if (hashAlgorithm == HashAlgorithm.Sha256)
                                    {
                                        hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length));
                                    }

                                    _blocksManager.Lock(hash);
                                    _blocksManager.Set(hash, new ArraySegment <byte>(safeBuffer.Value, 0, length));

                                    lockedHashes.Add(hash);
                                }

                                metadata = new Metadata(depth, hash);
                            }
                            else
                            {
                                for (; ;)
                                {
                                    var targetHashes = new List <Hash>();
                                    var targetBuffers = new List <ArraySegment <byte> >();
                                    long sumLength = 0;

                                    try
                                    {
                                        for (int i = 0; stream.Position < stream.Length; i++)
                                        {
                                            token.ThrowIfCancellationRequested();

                                            var buffer = new ArraySegment <byte>();

                                            try
                                            {
                                                int length = (int)Math.Min(stream.Length - stream.Position, blockLength);
                                                buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length);
                                                stream.Read(buffer.Array, 0, length);

                                                sumLength += length;
                                            }
                                            catch (Exception)
                                            {
                                                if (buffer.Array != null)
                                                {
                                                    _bufferManager.ReturnBuffer(buffer.Array);
                                                }

                                                throw;
                                            }

                                            Hash hash;

                                            if (hashAlgorithm == HashAlgorithm.Sha256)
                                            {
                                                hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer));
                                            }

                                            _blocksManager.Lock(hash);
                                            _blocksManager.Set(hash, buffer);

                                            lockedHashes.Add(hash);

                                            targetHashes.Add(hash);
                                            targetBuffers.Add(buffer);

                                            if (targetBuffers.Count >= 128)
                                            {
                                                break;
                                            }
                                        }

                                        var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token);
                                        lockedHashes.UnionWith(parityHashes);

                                        groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray()));
                                    }
                                    finally
                                    {
                                        foreach (var buffer in targetBuffers)
                                        {
                                            if (buffer.Array == null)
                                            {
                                                continue;
                                            }

                                            _bufferManager.ReturnBuffer(buffer.Array);
                                        }
                                    }

                                    if (stream.Position == stream.Length)
                                    {
                                        break;
                                    }
                                }

                                depth++;
                            }
                        }
                    }
                }

                lock (_lockObject)
                {
                    if (!_contentInfoManager.ContainsFileContentInfo(path))
                    {
                        _contentInfoManager.Add(new ContentInfo(creationTime, Timeout.InfiniteTimeSpan, metadata, lockedHashes, shareInfo));

                        foreach (var hash in lockedHashes)
                        {
                            _blocksManager.Lock(hash);
                        }
                    }
                }

                return metadata;
            }, token));
        }
예제 #20
0
        private IEnumerable <Hash> ParityEncoding(IEnumerable <ArraySegment <byte> > buffers, HashAlgorithm hashAlgorithm, CorrectionAlgorithm correctionAlgorithm, CancellationToken token)
        {
            if (correctionAlgorithm == CorrectionAlgorithm.ReedSolomon8)
            {
                if (buffers.Count() > 128)
                {
                    throw new ArgumentOutOfRangeException(nameof(buffers));
                }

                var createBuffers = new List <ArraySegment <byte> >();

                try
                {
                    var targetBuffers = new ArraySegment <byte> [buffers.Count()];
                    var parityBuffers = new ArraySegment <byte> [buffers.Count()];

                    int blockLength = buffers.Max(n => n.Count);

                    // Normalize
                    {
                        int index = 0;

                        foreach (var buffer in buffers)
                        {
                            token.ThrowIfCancellationRequested();

                            if (buffer.Count < blockLength)
                            {
                                var tempBuffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(blockLength), 0, blockLength);
                                Unsafe.Copy(buffer.Array, buffer.Offset, tempBuffer.Array, tempBuffer.Offset, buffer.Count);
                                Unsafe.Zero(tempBuffer.Array, tempBuffer.Offset + buffer.Count, tempBuffer.Count - buffer.Count);

                                createBuffers.Add(tempBuffer);

                                targetBuffers[index] = tempBuffer;
                            }
                            else
                            {
                                targetBuffers[index] = buffer;
                            }

                            index++;
                        }
                    }

                    for (int i = 0; i < parityBuffers.Length; i++)
                    {
                        parityBuffers[i] = new ArraySegment <byte>(_bufferManager.TakeBuffer(blockLength), 0, blockLength);
                    }

                    var indexes = new int[parityBuffers.Length];

                    for (int i = 0; i < parityBuffers.Length; i++)
                    {
                        indexes[i] = targetBuffers.Length + i;
                    }

                    using (var reedSolomon = new ReedSolomon8(targetBuffers.Length, targetBuffers.Length + parityBuffers.Length, _threadCount, _bufferManager))
                    {
                        reedSolomon.Encode(targetBuffers, parityBuffers, indexes, blockLength, token).Wait();
                    }

                    token.ThrowIfCancellationRequested();

                    var parityHashes = new List <Hash>();

                    for (int i = 0; i < parityBuffers.Length; i++)
                    {
                        Hash hash;

                        if (hashAlgorithm == HashAlgorithm.Sha256)
                        {
                            hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(parityBuffers[i]));
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }

                        _blocksManager.Lock(hash);
                        _blocksManager.Set(hash, parityBuffers[i]);

                        parityHashes.Add(hash);
                    }

                    return(parityHashes);
                }
                finally
                {
                    foreach (var buffer in createBuffers)
                    {
                        if (buffer.Array == null)
                        {
                            continue;
                        }

                        _bufferManager.ReturnBuffer(buffer.Array);
                    }
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
예제 #21
0
        public Task <Metadata> Import(Stream stream, TimeSpan lifeSpan, CancellationToken token)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            return(Task.Run(() =>
            {
                Metadata metadata = null;
                var lockedHashes = new HashSet <Hash>();

                try
                {
                    const int blockLength = 1024 * 1024;
                    const HashAlgorithm hashAlgorithm = HashAlgorithm.Sha256;
                    const CorrectionAlgorithm correctionAlgorithm = CorrectionAlgorithm.ReedSolomon8;

                    int depth = 0;
                    var creationTime = DateTime.UtcNow;

                    var groupList = new List <Group>();

                    for (; ;)
                    {
                        if (stream.Length <= blockLength)
                        {
                            Hash hash;

                            using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength))
                            {
                                int length = (int)stream.Length;
                                stream.Read(safeBuffer.Value, 0, length);

                                if (hashAlgorithm == HashAlgorithm.Sha256)
                                {
                                    hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length));
                                }

                                _blocksManager.Lock(hash);
                                _blocksManager.Set(hash, new ArraySegment <byte>(safeBuffer.Value, 0, length));

                                lockedHashes.Add(hash);
                            }

                            // Stream Dispose
                            {
                                stream.Dispose();
                                stream = null;
                            }

                            metadata = new Metadata(depth, hash);

                            break;
                        }
                        else
                        {
                            for (; ;)
                            {
                                var targetHashes = new List <Hash>();
                                var targetBuffers = new List <ArraySegment <byte> >();
                                long sumLength = 0;

                                try
                                {
                                    for (int i = 0; stream.Position < stream.Length; i++)
                                    {
                                        token.ThrowIfCancellationRequested();

                                        var buffer = new ArraySegment <byte>();

                                        try
                                        {
                                            int length = (int)Math.Min(stream.Length - stream.Position, blockLength);
                                            buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length);
                                            stream.Read(buffer.Array, 0, length);

                                            sumLength += length;
                                        }
                                        catch (Exception)
                                        {
                                            if (buffer.Array != null)
                                            {
                                                _bufferManager.ReturnBuffer(buffer.Array);
                                            }

                                            throw;
                                        }

                                        Hash hash;

                                        if (hashAlgorithm == HashAlgorithm.Sha256)
                                        {
                                            hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer));
                                        }

                                        _blocksManager.Lock(hash);
                                        _blocksManager.Set(hash, buffer);

                                        lockedHashes.Add(hash);

                                        targetHashes.Add(hash);
                                        targetBuffers.Add(buffer);

                                        if (targetBuffers.Count >= 128)
                                        {
                                            break;
                                        }
                                    }

                                    var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token);
                                    lockedHashes.UnionWith(parityHashes);

                                    groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray()));
                                }
                                finally
                                {
                                    foreach (var buffer in targetBuffers)
                                    {
                                        if (buffer.Array == null)
                                        {
                                            continue;
                                        }

                                        _bufferManager.ReturnBuffer(buffer.Array);
                                    }
                                }

                                if (stream.Position == stream.Length)
                                {
                                    break;
                                }
                            }

                            depth++;

                            // Stream Dispose
                            {
                                stream.Dispose();
                                stream = null;
                            }

                            stream = (new Index(groupList)).Export(_bufferManager);
                        }
                    }
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                        stream = null;
                    }
                }

                lock (_lockObject)
                {
                    if (!_contentInfoManager.ContainsMessageContentInfo(metadata))
                    {
                        _contentInfoManager.Add(new ContentInfo(DateTime.UtcNow, lifeSpan, metadata, lockedHashes, null));

                        foreach (var hash in lockedHashes)
                        {
                            _blocksManager.Lock(hash);
                        }
                    }
                }

                return metadata;
            }, token));
        }
예제 #22
0
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            try
            {
                string sessionId = NetworkConverter.ToHexString(Sha256.Compute(Path.GetFullPath(Assembly.GetEntryAssembly().Location)));

                // 多重起動防止
                {
                    _mutex = new Mutex(false, sessionId);

                    if (!_mutex.WaitOne(0))
                    {
                        this.Shutdown();

                        return;
                    }
                }

                // アップデート
                {
                    // 一時的に作成された"Amoeba.Update.exe"を削除する。
                    {
                        string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Amoeba.Update.exe");

                        if (File.Exists(tempUpdateExeFilePath))
                        {
                            File.Delete(tempUpdateExeFilePath);
                        }
                    }

                    if (Directory.Exists(AmoebaEnvironment.Paths.UpdatePath))
                    {
                        string zipFilePath = null;

                        // 最新のバージョンのzipを検索。
                        {
                            var map   = new Dictionary <string, Version>();
                            var regex = new Regex(@"Amoeba.+?((\d*)\.(\d*)\.(\d*)).*?\.zip", RegexOptions.Compiled);

                            foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.UpdatePath))
                            {
                                var match = regex.Match(Path.GetFileName(path));
                                if (!match.Success)
                                {
                                    continue;
                                }

                                var version = new Version(match.Groups[1].Value);
                                if (version < AmoebaEnvironment.Version)
                                {
                                    continue;
                                }

                                map.Add(path, version);
                            }

                            if (map.Count > 0)
                            {
                                var sortedList = map.ToList();
                                sortedList.Sort((x, y) => y.Value.CompareTo(x.Value));

                                zipFilePath = sortedList.First().Key;
                            }
                        }

                        if (zipFilePath != null)
                        {
                            string tempUpdateDirectoryPath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Update");

                            if (Directory.Exists(tempUpdateDirectoryPath))
                            {
                                Directory.Delete(tempUpdateDirectoryPath, true);
                            }

                            using (var zipfile = new ZipFile(zipFilePath))
                            {
                                zipfile.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
                                zipfile.ExtractAll(tempUpdateDirectoryPath);
                            }

                            if (File.Exists(zipFilePath))
                            {
                                File.Delete(zipFilePath);
                            }

                            string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Amoeba.Update.exe");

                            File.Copy("Amoeba.Update.exe", tempUpdateExeFilePath);

                            var startInfo = new ProcessStartInfo();
                            startInfo.FileName  = Path.GetFullPath(tempUpdateExeFilePath);
                            startInfo.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"",
                                                                sessionId,
                                                                Path.Combine(tempUpdateDirectoryPath, "Core"),
                                                                Directory.GetCurrentDirectory(),
                                                                Path.Combine(Directory.GetCurrentDirectory(), "Amoeba.Interface.exe"));
                            startInfo.WorkingDirectory = Path.GetFullPath(Path.GetDirectoryName(tempUpdateExeFilePath));

                            Process.Start(startInfo);

                            this.Shutdown();

                            return;
                        }
                    }
                }

                // 既定のフォルダを作成する。
                {
                    foreach (var propertyInfo in typeof(AmoebaEnvironment.EnvironmentPaths).GetProperties())
                    {
                        string path = propertyInfo.GetValue(AmoebaEnvironment.Paths) as string;
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                    }
                }

                // Tempフォルダを環境変数に登録。
                {
                    // Tempフォルダ内を掃除。
                    try
                    {
                        foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.TempPath, "*", SearchOption.AllDirectories))
                        {
                            File.Delete(path);
                        }

                        foreach (string path in Directory.GetDirectories(AmoebaEnvironment.Paths.TempPath, "*", SearchOption.AllDirectories))
                        {
                            Directory.Delete(path, true);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    Environment.SetEnvironmentVariable("TMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempPath), EnvironmentVariableTarget.Process);
                    Environment.SetEnvironmentVariable("TEMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempPath), EnvironmentVariableTarget.Process);
                }

                // アップグレード処理。
                {
                    if (AmoebaEnvironment.Config.Version <= new Version(5, 0, 60))
                    {
                        var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigPath, @"Service\Core\Cache");
                        Directory.CreateDirectory(Path.Combine(basePath, "Blocks"));

                        var renameList = new List <(string oldPath, string newPath)>();
                        renameList.Add((@"CacheInfos.json.gz", @"ContentInfos.json.gz"));
                        renameList.Add((@"Size.json.gz", @"Blocks\Size.json.gz"));
                        renameList.Add((@"ClusterIndex.json.gz", @"Blocks\ClusterIndex.json.gz"));

                        foreach (var(oldPath, newPath) in renameList)
                        {
                            File.Copy(Path.Combine(basePath, oldPath), Path.Combine(basePath, newPath));
                        }
                    }
                }

                this.StartupUri = new Uri("Mvvm/Windows/Main/MainWindow.xaml", UriKind.Relative);
            }
            catch (Exception ex)
            {
                Log.Error(ex);

                this.Shutdown();

                return;
            }
        }
예제 #23
0
 public static byte[] CreateSwapSecretHash160(byte[] secretBytes)
 {
     return(Ripemd160.Compute(Sha256.Compute(secretBytes)));
 }
예제 #24
0
        private void Init()
        {
            {
                IObservable <object> clipboardObservable;
                {
                    var returnObservable = Observable.Return((object)null);
                    var watchObservable  = Observable.FromEventPattern <EventHandler, EventArgs>(h => Clipboard.ClipboardChanged += h, h => Clipboard.ClipboardChanged -= h).Select(n => (object)null);
                    clipboardObservable = Observable.Merge(returnObservable, watchObservable);
                }

                this.TabViewModel = new ReactiveProperty <ChatCategoryViewModel>().AddTo(_disposable);

                this.TabSelectedItem = new ReactiveProperty <TreeViewModelBase>().AddTo(_disposable);
                this.TabSelectedItem.Subscribe((viewModel) => this.TabSelectChanged(viewModel)).AddTo(_disposable);

                this.Info         = new ReactiveProperty <AvalonEditChatMessagesInfo>().AddTo(_disposable);
                this.SelectedText = new ReactiveProperty <string>().AddTo(_disposable);

                this.TabClickCommand = new ReactiveCommand().AddTo(_disposable);
                this.TabClickCommand.Where(n => n == this.TabSelectedItem.Value).Subscribe((_) => this.Refresh()).AddTo(_disposable);

                this.TabNewCategoryCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable);
                this.TabNewCategoryCommand.Subscribe(() => this.TabNewCategory()).AddTo(_disposable);

                this.TabEditCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable);
                this.TabEditCommand.Subscribe(() => this.TabEdit()).AddTo(_disposable);

                this.TabDeleteCommand = this.TabSelectedItem.Select(n => n != this.TabViewModel.Value).ToReactiveCommand().AddTo(_disposable);
                this.TabDeleteCommand.Subscribe(() => this.TabDelete()).AddTo(_disposable);

                this.TabCutCommand = new ReactiveCommand().AddTo(_disposable);
                this.TabCutCommand.Subscribe(() => this.TabCut()).AddTo(_disposable);

                this.TabCopyCommand = new ReactiveCommand().AddTo(_disposable);
                this.TabCopyCommand.Subscribe(() => this.TabCopy()).AddTo(_disposable);

                this.TabPasteCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel)
                                       .CombineLatest(clipboardObservable.Select(n => Clipboard.ContainsTags() || Clipboard.ContainsChatCategoryInfo() || Clipboard.ContainsChatThreadInfo()), (r1, r2) => r1 && r2).ToReactiveCommand().AddTo(_disposable);
                this.TabPasteCommand.Subscribe(() => this.TabPaste()).AddTo(_disposable);

                this.TabTagListCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable);
                this.TabTagListCommand.Subscribe(() => this.TabTagList()).AddTo(_disposable);

                this.TrustFilterCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable);
                this.TrustFilterCommand.Subscribe(() => this.TrustFilter()).AddTo(_disposable);

                this.IsTrustFilterEnable = new ReactiveProperty <bool>().AddTo(_disposable);

                this.NewFilterCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable);
                this.NewFilterCommand.Subscribe(() => this.NewFilter()).AddTo(_disposable);

                this.IsNewFilterEnable = new ReactiveProperty <bool>().AddTo(_disposable);

                this.MiningLimits        = new ObservableCollection <int>(Enumerable.Range(0, 256 + 1));
                this.SelectedMiningLimit = new ReactiveProperty <int>().AddTo(_disposable);
                this.SelectedMiningLimit.Subscribe((_) => this.Refresh()).AddTo(_disposable);

                this.NewMessageCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable);
                this.NewMessageCommand.Subscribe(() => this.NewMessage()).AddTo(_disposable);

                this.CopyCommand = this.SelectedText.Select(n => !string.IsNullOrEmpty(n)).ToReactiveCommand().AddTo(_disposable);
                this.CopyCommand.Subscribe(() => this.Copy()).AddTo(_disposable);

                this.ResponseCommand = this.SelectedText.Select(n => !string.IsNullOrEmpty(n)).ToReactiveCommand().AddTo(_disposable);
                this.ResponseCommand.Subscribe(() => this.Response()).AddTo(_disposable);
            }

            {
                string configPath = Path.Combine(AmoebaEnvironment.Paths.ConfigPath, "View", nameof(ChatControl));
                if (!Directory.Exists(configPath))
                {
                    Directory.CreateDirectory(configPath);
                }

                _settings = new Settings(configPath);
                int version = _settings.Load("Version", () => 0);

                {
                    var model = _settings.Load("ChatCategoryInfo", () =>
                    {
                        var categoryInfo = new ChatCategoryInfo()
                        {
                            Name = "Category", IsExpanded = true
                        };
                        categoryInfo.ThreadInfos.Add(new ChatThreadInfo()
                        {
                            Tag = new Tag("Amoeba", Sha256.Compute("Amoeba"))
                        });
                        categoryInfo.ThreadInfos.Add(new ChatThreadInfo()
                        {
                            Tag = new Tag("Random", Sha256.Compute("Random"))
                        });

                        return(categoryInfo);
                    });

                    this.TabViewModel.Value = new ChatCategoryViewModel(null, model);
                }

                this.SelectedMiningLimit.Value = _settings.Load("MiningLimit", () => 0);

                this.DynamicOptions.SetProperties(_settings.Load(nameof(DynamicOptions), () => Array.Empty <DynamicOptions.DynamicPropertyInfo>()));
            }

            {
                Backup.Instance.SaveEvent += this.Save;
            }
        }
예제 #25
0
 public string UserId()
 {
     return(Sha256.Compute(Sha256.Compute(PublicKey)).ToHexString());
 }
예제 #26
0
        public void Save(Stream output, IList <IArchiveFileInfo> files)
        {
            var ciaAfis = files.Cast <CiaArchiveFileInfo>().ToArray();
            var sha     = new Sha256();

            // Update content chunks
            foreach (var ciaAfi in ciaAfis)
            {
                var ncchStream = ciaAfi.GetFileData().Result;

                ciaAfi.ContentChunkRecord.sha256      = sha.Compute(ncchStream);
                ciaAfi.ContentChunkRecord.contentSize = ncchStream.Length;
            }
            _tmd.contentChunkRecords = ciaAfis.Select(x => x.ContentChunkRecord).ToArray();

            // Write content chunks
            var contentChunkStream = new MemoryStream();

            using (var chunkBw = new BinaryWriterX(contentChunkStream, true))
                chunkBw.WriteMultiple(_tmd.contentChunkRecords);

            // Update content info records
            foreach (var contentInfoRecord in _tmd.contentInfoRecords)
            {
                if (contentInfoRecord.contentChunkCount == 0)
                {
                    continue;
                }

                var offset = contentInfoRecord.contentChunkIndex * _contentChunkRecordSize;
                var size   = contentInfoRecord.contentChunkCount * _contentChunkRecordSize;
                contentInfoRecord.sha256 = sha.Compute(new SubStream(contentChunkStream, offset, size));
            }

            // Write content info records
            var contentInfoStream = new MemoryStream();

            using (var infoBw = new BinaryWriterX(contentInfoStream, true))
                infoBw.WriteMultiple(_tmd.contentInfoRecords);

            // Update content info hash
            contentInfoStream.Position = 0;
            _tmd.header.sha256         = sha.Compute(contentInfoStream);

            // --- Write CIA ---
            using var bw = new BinaryWriterX(output);
            var ciaOffset = bw.BaseStream.Position = _headerSize;

            // Write certificate chain
            bw.WriteType(_certChain);
            _header.certChainSize = (int)(bw.BaseStream.Length - ciaOffset);
            bw.WriteAlignment(0x40);
            ciaOffset = bw.BaseStream.Length;

            // Write ticket
            bw.WriteType(_ticket);
            _header.ticketSize = (int)(bw.BaseStream.Length - ciaOffset);
            bw.WriteAlignment(0x40);
            ciaOffset = bw.BaseStream.Length;

            // Write TMD
            bw.WriteType(_tmd);
            _header.tmdSize = (int)(bw.BaseStream.Length - ciaOffset);
            bw.WriteAlignment(0x40);
            ciaOffset = bw.BaseStream.Length;

            // Write content
            foreach (var ciaAfi in ciaAfis)
            {
                ciaAfi.SaveFileData(bw.BaseStream);
            }
            _header.contentSize = bw.BaseStream.Length - ciaOffset;
            bw.WriteAlignment(0x40);
            ciaOffset = bw.BaseStream.Length;

            // Write meta data
            if (_meta != null)
            {
                bw.WriteType(_meta);
                _header.metaSize = (int)(bw.BaseStream.Length - ciaOffset);
                bw.WriteAlignment(0x40);
            }

            // Write header
            bw.BaseStream.Position = 0;
            bw.WriteType(_header);
        }
예제 #27
0
        public void CheckBrokenTest()
        {
            string targetPath = Path.Combine(_workPath, "CheckBroken");
            string configPath = Path.Combine(targetPath, "CacheManager");
            string blockPath  = Path.Combine(targetPath, "cache.blocks");;

            Directory.CreateDirectory(targetPath);
            Directory.CreateDirectory(configPath);

            var list = new List <Hash>();

            {
                var cacheManager = new CacheManager(configPath, blockPath, _bufferManager);
                cacheManager.Load();

                for (int i = 0; i < 256; i++)
                {
                    int size = _random.Next(1, 1024 * 256);

                    using (var safeBuffer = _bufferManager.CreateSafeBuffer(size))
                    {
                        _random.NextBytes(safeBuffer.Value);

                        var block = new ArraySegment <byte>(safeBuffer.Value, 0, size);
                        var hash  = new Hash(HashAlgorithm.Sha256, Sha256.Compute(block));

                        cacheManager.Set(hash, block);
                        list.Add(hash);
                    }
                }

                cacheManager.Save();
                cacheManager.Dispose();
            }

            using (var stream = new FileStream(blockPath, FileMode.Open))
            {
                int b = stream.ReadByte();
                stream.Seek(0, SeekOrigin.Begin);
                stream.WriteByte((byte)(b ^ 0xFF));
            }

            {
                var cacheManager = new CacheManager(configPath, blockPath, _bufferManager);
                cacheManager.Load();

                Assert.True(new HashSet <Hash>(list).SetEquals(cacheManager.ToArray()));

                Assert.Throws <BlockNotFoundException>(() =>
                {
                    var result = cacheManager.GetBlock(list[0]);
                });

                foreach (var hash in list.Skip(1))
                {
                    var result = cacheManager.GetBlock(hash);
                    _bufferManager.ReturnBuffer(result.Array);
                }

                cacheManager.Save();
                cacheManager.Dispose();
            }
        }
예제 #28
0
 public static byte[] CreateSwapSecretHash(byte[] secretBytes)
 {
     return(Sha256.Compute(secretBytes, 2));
 }
예제 #29
0
        public ArraySegment <byte> GetBlock(Hash hash)
        {
            // Cache
            {
                var result = _blocksManager.Get(hash);

                if (result != null)
                {
                    return(result.Value);
                }
            }

            // Share
            {
                ArraySegment <byte>?result = null;
                string path = null;

                lock (_lockObject)
                {
                    var shareInfo = _contentInfoManager.GetShareInfo(hash);

                    if (shareInfo != null)
                    {
                        var buffer = _bufferManager.TakeBuffer(shareInfo.BlockLength);

                        try
                        {
                            int length;

                            try
                            {
                                using (var stream = new UnbufferedFileStream(shareInfo.Path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None, _bufferManager))
                                {
                                    stream.Seek((long)shareInfo.GetIndex(hash) * shareInfo.BlockLength, SeekOrigin.Begin);

                                    length = (int)Math.Min(stream.Length - stream.Position, shareInfo.BlockLength);
                                    stream.Read(buffer, 0, length);
                                }
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                throw new BlockNotFoundException();
                            }
                            catch (IOException)
                            {
                                throw new BlockNotFoundException();
                            }

                            result = new ArraySegment <byte>(buffer, 0, length);
                            path   = shareInfo.Path;
                        }
                        catch (Exception)
                        {
                            _bufferManager.ReturnBuffer(buffer);

                            throw;
                        }
                    }
                }

                if (result != null)
                {
                    if (hash.Algorithm == HashAlgorithm.Sha256 &&
                        Unsafe.Equals(Sha256.Compute(result.Value), hash.Value))
                    {
                        return(result.Value);
                    }
                    else
                    {
                        _bufferManager.ReturnBuffer(result.Value.Array);
                        result = null;

                        this.RemoveContent(path);
                    }
                }
            }

            throw new BlockNotFoundException();
        }