private async static Task WritePayloadToSyncFileAsync(string lockFile, string protectedFile)
        {
            string pid       = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture);
            string errorFile = protectedFile + $"{pid}.e.txt";
            string pidFIle   = Path.Combine(Path.GetDirectoryName(protectedFile), "finished", pid + ".txt");

            Console.WriteLine("Starting process: " + pid);
            CrossPlatLock crossPlatLock = null;

            try
            {
                crossPlatLock = new CrossPlatLock(lockFile);
                using (StreamWriter sw = new StreamWriter(protectedFile, true))
                {
                    sw.WriteLine($"< {pid} {DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}");

                    // increase contention by simulating a slow writer
                    await Task.Delay(s_artificialContention).ConfigureAwait(false);

                    sw.WriteLine($"> {pid} {DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)}");
                    Console.WriteLine("Process finished: " + pid);
                }
            }
            catch (Exception e)
            {
                File.WriteAllText(errorFile, e.ToString());
                throw;
            }
            finally
            {
                File.WriteAllText(pidFIle, "done");
                crossPlatLock.Dispose();
            }
        }
        [WorkItem(187)] // https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/issues/187
        public void DirNotExists()
        {
            // Arrange

            string cacheFileDir;

            // ensure the cache directory does not exist
            do
            {
                string tempDirName = System.IO.Path.GetRandomFileName();
                cacheFileDir = Path.Combine(Path.GetTempPath(), tempDirName);
            } while (Directory.Exists(cacheFileDir));

            using (var crossPlatLock = new CrossPlatLock(
                       Path.Combine(cacheFileDir, "file.lockfile"), // the directory is guaranteed to not exist
                       100,
                       1))
            {
                // no-op
            }

            // before fixing the bug, an exception would occur here:
            // System.InvalidOperationException: Could not get access to the shared lock file.
            // ---> System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\....
        }
Esempio n. 3
0
        public static async Task Main(string[] args)
        {
            if (args.Length < 2)
            {
                PrintUsage();
                Console.Read();
                return;
            }

            string filePath = args[0];

            if (!File.Exists(filePath))
            {
                File.Create(filePath);
            }
            int delay = int.Parse(args[1], CultureInfo.InvariantCulture);

            // this object tries to acquire the file lock every 100ms and gives up after 600 attempts (about 1 min)
            using (var crossPlatLock = new CrossPlatLock(filePath + ".lockfile"))
            {
                Console.WriteLine("Acquired the lock...");

                Console.WriteLine("Writing...");

                File.WriteAllText(filePath, "< " + Process.GetCurrentProcess().Id);
                Console.WriteLine($"Waiting for {delay}s");

                await Task.Delay(delay * 1000).ConfigureAwait(false);

                Console.WriteLine("Writing...");
                File.WriteAllText(filePath, "> " + Process.GetCurrentProcess().Id);
            }
        }
Esempio n. 4
0
        // Triggered right after ADAL accessed the cache.
        // Internal for testing.
        internal void AfterAccessNotification(TokenCacheNotificationArgs args)
        {
            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After access");

            try
            {
                // if the access operation resulted in a cache update
                if (HasStateChanged)
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After access, cache in memory HasChanged");
                    try
                    {
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before Write Store");
                        byte[] data = SerializeAdalV3();
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Serializing '{data.Length}' bytes");
                        _store.WriteData(data);

                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After write store");
                        HasStateChanged = false;
                    }
                    catch (Exception e)
                    {
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while serializing the {nameof(AdalCache)} : {e}");
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"No data found in the store, clearing the cache in memory.");

                        // The cache is corrupt clear it out
                        DeserializeAdalV3(null);
                        _store.Clear();
                        throw;
                    }
                }
            }
            finally
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Releasing lock");
                // Get a local copy and call null before disposing because when the lock is disposed the next thread will replace CacheLock with its instance,
                // therefore we do not want to null out CacheLock after dispose since this may orphan a CacheLock.
                var localLockCopy = _cacheLock;
                _cacheLock = null;
                localLockCopy?.Dispose();
            }
        }
Esempio n. 5
0
        // Triggered right before ADAL needs to access the cache.
        // Reload the cache from the persistent store in case it changed since the last access.
        private void BeforeAccessNotification(TokenCacheNotificationArgs args)
        {
            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before access");

            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Acquiring lock for token cache");
            _cacheLock = new CrossPlatLock(
                Path.GetFileNameWithoutExtension(_store.CreationProperties.CacheFileName),
                Path.Combine(_store.CreationProperties.CacheDirectory, _store.CreationProperties.CacheFileName) + ".lockfile");

            if (_store.HasChanged)
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before access, the store has changed");
                byte[] fileData = _store.ReadData();
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Read '{fileData?.Length}' bytes from storage");

                if (fileData != null && fileData.Length > 0)
                {
                    try
                    {
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Deserializing the store");
                        DeserializeAdalV3(fileData);
                    }
                    catch (Exception e)
                    {
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while deserializing the {nameof(AdalCache)} : {e}");
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"No data found in the store, clearing the cache in memory.");

                        // Clear the memory cache
                        DeserializeAdalV3(null);
                        _store.Clear();
                        throw;
                    }
                }
                else
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"No data found in the store, clearing the cache in memory.");

                    // Clear the memory cache
                    DeserializeAdalV3(null);
                }
            }
        }
        // Triggered right after ADAL accessed the cache.
        private void AfterAccessNotification(TokenCacheNotificationArgs args)
        {
            _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After access");

            try
            {
                // if the access operation resulted in a cache update
                if (HasStateChanged)
                {
                    _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After access, cache in memory HasChanged");
                    try
                    {
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before Write Store");
                        byte[] data = SerializeAdalV3();
                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Serializing '{data.Length}' bytes");
                        _store.WriteData(data);

                        _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"After write store");
                        HasStateChanged = false;
                    }
                    catch (Exception e)
                    {
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while serializing the {nameof(AdalCache)} : {e}");
                        _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"No data found in the store, clearing the cache in memory.");

                        // The cache is corrupt clear it out
                        DeserializeAdalV3(null);
                        _store.Clear();
                        throw;
                    }
                }
            }
            finally
            {
                _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Releasing lock");
                _cacheLock?.Dispose();
                _cacheLock = null;
            }
        }
Esempio n. 7
0
        // Triggered right before ADAL needs to access the cache.
        // Reload the cache from the persistent store in case it changed since the last access.
        // Internal for testing.
        internal void BeforeAccessNotification(TokenCacheNotificationArgs args)
        {
            _logger.LogInformation($"Before access");

            _logger.LogInformation($"Acquiring lock for token cache");
            _cacheLock = new CrossPlatLock(Path.Combine(_store.CreationProperties.CacheDirectory, _store.CreationProperties.CacheFileName) + ".lockfile", this._lockFileRetryDelay, this._lockFileRetryCount);

            _logger.LogInformation($"Before access, the store has changed");
            byte[] fileData = _store.ReadData();
            _logger.LogInformation($"Read '{fileData?.Length}' bytes from storage");

            if (fileData != null && fileData.Length > 0)
            {
                try
                {
                    _logger.LogInformation($"Deserializing the store");
                    DeserializeAdalV3(fileData);
                }
                catch (Exception e)
                {
                    _logger.LogError($"An exception was encountered while deserializing the {nameof(AdalCache)} : {e}");
                    _logger.LogError($"No data found in the store, clearing the cache in memory.");

                    // Clear the memory cache
                    DeserializeAdalV3(null);
                    _store.Clear();
                    throw;
                }
            }
            else
            {
                _logger.LogInformation($"No data found in the store, clearing the cache in memory.");

                // Clear the memory cache
                DeserializeAdalV3(null);
            }
        }