예제 #1
0
        private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count)
        {
            length = Math.Min(length, MaxLength);
            count  = Math.Min(count, MaxCount);
            if (count <= 0 || length <= 0)
            {
                yield break;
            }

            var sw = System.Diagnostics.Stopwatch.StartNew();

            for (int i = 0; i < count; i++)
            {
                var bytes  = random.GetRandomBytes(length);
                var result = String.Join("", bytes.Select(x => x.ToString("x2")));

                yield return(result);
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("Hex", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count);
        }
예제 #2
0
        /// <summary>
        /// Stops listening on the specified remote endpoints.
        /// </summary>
        /// <param name="remoteEps">The remote eps.</param>
        public void StopListeningOn(params IPEndPoint[] remoteEps)
        {
            // If nothing specified then just stop listening on all
            if (remoteEps == null || remoteEps.Length == 0)
            {
                this.StopListening();
                return;
            }

            lock (this.Server)
            {
                if (!this.Server.IsListening)
                {
                    return;
                }

                // Drop all the multicast groups specified
                foreach (IPEndPoint ep in remoteEps.Where(ep => IPAddressHelpers.IsMulticast(ep.Address)))
                {
                    try
                    {
                        this.Server.DropMulticastGroup(ep.Address);
                    }
                    catch (SocketException)
                    {
                        // If we're not part of this group then it will throw an error so just ignore it
                    }
                }
            }
        }
예제 #3
0
        public void SearchAsync(params IPEndPoint[] destinations)
        {
            lock (this.SearchLock)
            {
                // If we're already searching then this is not allowed so throw an error
                if (this.IsSearching)
                {
                    throw new InvalidOperationException("Search is already in progress.");
                }

                this.IsSearching = true;
                this.Server.SsdpMessageReceived += OnSsdpMessageReceived;

                // TODO: Come up with a good calculation for this
                // Just double our mx value for the timeout for now
                this.CreateSearchTimeout(TimeSpan.FromSeconds(this.Mx * 2));
            }

            // If no destinations were specified then default to the IPv4 discovery
            if (destinations == null || destinations.Length == 0)
            {
                destinations = new[] { Protocol.DiscoveryEndpoints.IPv4 }
            }
            ;

            // Start the server and join our igmp groups
            this.Server.StartListening();

            // Do we really need to join the multicast group to send out multicast messages? Seems that way...
            foreach (IPEndPoint dest in destinations.Where(ep => IPAddressHelpers.IsMulticast(ep.Address)))
            {
                this.Server.JoinMulticastGroupAllInterfaces(dest.Address);
            }

            // If we're sending out any searches to the broadcast address then be sure to enable broadcasts
            if (!this.Server.EnableBroadcast)
            {
                this.Server.EnableBroadcast = destinations.Any(ep => ep.Address.Equals(IPAddress.Broadcast));
            }


            // Now send out our search data
            foreach (var dest in destinations)
            {
                // Make sure we respect our option as to whether we use the destination as the host value
                var host  = (this.UseRemoteEndpointAsHost ? dest : this.HostEndpoint);
                var req   = Protocol.CreateSearchRequest(host, this.SearchType, this.Mx);
                var bytes = Encoding.ASCII.GetBytes(req);
                var dest1 = dest;

                // TODO: Should we make this configurable?
                // NOTE: It's recommended to send two searches

                Trace.WriteLine(string.Format("Sending ssdp:discover [{0}, {1}] from {2} to {3}", this.SearchType, this.Mx, this.Server.LocalEndpoint, dest1), AppInfo.Application);
                this.Server.Send(bytes, bytes.Length, dest1);
                this.Server.Send(bytes, bytes.Length, dest1);
            }
        }
예제 #4
0
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?l)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            // Return information about the number of combinations as a JSON object.
            var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength);
            var result = new JsonCombinationContainer();

            result.combinations = Math.Pow(256, length);
            return(new JsonNetResult(result));
        }
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?sc)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            var syllableCount = Math.Min(sc.HasValue ? sc.Value : DefaultSyllableCount, MaxSyllableCount);

            // Return information about the number of combinations as a JSON object.
            var result = new JsonCombinationContainer();

            result.combinations = Math.Pow(ConsonantSounds.Length * VowelSounds.Length * (ConsonantSounds.Length * ProbabilityOfTwoConsonantsInOneSyllable), syllableCount);
            return(new JsonNetResult(result));
        }
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?wc)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            // Return information about the number of combinations as a JSON object.
            var result    = new JsonCombinationContainer();
            var wordCount = Math.Min(wc.HasValue ? wc.Value : DefaultWords, MaxWords);
            var dict      = Dictionary.Value;

            result.combinations = Math.Pow(dict.Count, wordCount);
            return(new JsonNetResult(result));
        }
        private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int syllableCount, int count, bool hyphansBetweenSyllables)
        {
            syllableCount = Math.Min(syllableCount, MaxSyllableCount);
            count         = Math.Min(count, MaxCount);
            if (count <= 0 || syllableCount <= 0)
            {
                yield break;
            }

            var sw = System.Diagnostics.Stopwatch.StartNew();
            var sb = new StringBuilder();

            for (int c = 0; c < count; c++)
            {
                // Generate a password.
                for (int l = 0; l < syllableCount; l++)
                {
                    sb.Append(ConsonantSounds[random.GetRandomInt32(ConsonantSounds.Length)]);
                    sb.Append(VowelSounds[random.GetRandomInt32(VowelSounds.Length)]);
                    if (sb[sb.Length - 2] != 'g' && sb[sb.Length - 1] != 'h' &&
                        random.GetRandomSingle() < ProbabilityOfTwoConsonantsInOneSyllable)
                    {
                        sb.Append(ConsonantSounds[random.GetRandomInt32(ConsonantSounds.Length)]);
                    }

                    if (hyphansBetweenSyllables)
                    {
                        sb.Append('-');
                    }
                }
                if (hyphansBetweenSyllables && sb[sb.Length - 1] == '-')
                {
                    sb.Remove(sb.Length - 1, 1);
                }


                // Yield the phrase and reset state.
                var result = sb.ToString();
                yield return(result);

                sb.Clear();
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("Pronouncable", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count);
        }
예제 #8
0
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?l)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            // Return information about the number of combinations as a JSON object.
            var result = new JsonCombinationContainer();
            var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength);

            result.combinations  = Math.Pow(Characters.Length, length);
            result.combinations -= (double)Blacklist.Value.Count(x => x.Length == l);       // Remove blacklist entries.
            result.rating        = PasswordRatingService.RatePin(result.combinations);
            return(new JsonNetResult(result));
        }
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?l, string sym)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            // Return information about the number of combinations as a JSON object.
            var result  = new JsonCombinationContainer();
            var length  = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength);
            var symbols = sym.IsTruthy(DefaultSymbols);

            var charCount = symbols ? AllCharacters.Length : AlphanumericCharacters.Length;

            result.combinations = Math.Pow(charCount, length);
            return(new JsonNetResult(result));
        }
예제 #10
0
파일: SsdpSocket.cs 프로젝트: sjndhkl/Upnp
        public virtual void JoinMulticastGroupAllInterfaces(IPEndPoint remoteEp)
        {
            var localIps = IPAddressHelpers.GetUnicastAddresses(ip => ip.AddressFamily == remoteEp.AddressFamily);

            foreach (var addr in localIps)
            {
                try
                {
                    this.JoinMulticastGroup(remoteEp.Address, addr);
                }
                catch (SocketException)
                {
                    // If we're already joined to this group we'll throw an error so just ignore it
                }
            }
        }
예제 #11
0
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
     if (IpThrottlerService.HasExceededLimit(IPAddressHelpers.GetHostOrCacheIp(filterContext.HttpContext.Request), filterContext.HttpContext.GetApiKeyId()))
     {
         bool isAjaxRequest = false;
         if (isAjaxRequest)
         {
             // TODO: return a friendly message about IP limiting with appropriate HTTP status code.
             filterContext.Result = new HttpStatusCodeResult(429, "{ 'message':'You have exceeded IP based limits. These will be lifted automatically within 2 hours.'");
         }
         else
         {
             // TODO: return plain text details about the error.
             filterContext.Result = new HttpStatusCodeResult(429, "You have exceeded IP based limits. These will be lifted automatically within 2 hours.");
         }
     }
 }
예제 #12
0
        private IEnumerable <string> SelectPins(IRandomNumberGenerator random, int length, int count)
        {
            length = Math.Min(length, MaxLength);
            count  = Math.Min(count, MaxCount);
            if (count <= 0 || length <= 0)
            {
                yield break;
            }

            var sw        = System.Diagnostics.Stopwatch.StartNew();
            var sb        = new StringBuilder();
            var blacklist = Blacklist.Value;

            for (int c = 0; c < count; c++)
            {
                for (int l = 0; l < length; l++)
                {
                    sb.Append(Characters[random.GetRandomInt32(Characters.Length)]);
                }

                var candidate = sb.ToString();
                if (!blacklist.Contains(candidate)
                    // 4 digit PINs starting with '19' are more likely, so weight them lower.
                    || (length == 4 && candidate.Substring(0, 2) == "19" && random.GetRandomInt32(0, 3) == 0))
                {
                    yield return(candidate);
                }

                sb.Clear();
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("Pin", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count);
        }
예제 #13
0
        /// <summary>
        /// Gets the locations to respond with.
        /// </summary>
        /// <param name="condition">Condition to use when determining locations.</param>
        /// <returns></returns>
        public virtual IEnumerable <string> GetLocations(Func <IPAddress, bool> condition)
        {
            Uri uri;

            if (!Uri.TryCreate(this.Location, UriKind.Absolute, out uri) || (uri.Host != "0.0.0.0" && uri.Host != "localhost"))
            {
                yield return(this.Location);
            }
            else
            {
                foreach (var addr in IPAddressHelpers.GetUnicastAddresses())
                {
                    // Don't include the loopback
                    if (IPAddress.IsLoopback(addr))
                    {
                        continue;
                    }

                    // Skip any addresses not matching our condition
                    if (!condition(addr))
                    {
                        continue;
                    }

                    var builder = new UriBuilder(uri);
                    if (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                    {
                        builder.Host = string.Format("[{0}]", addr);
                    }
                    else
                    {
                        builder.Host = addr.ToString();
                    }

                    yield return(builder.ToString());
                }
            }
        }
        private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count, bool includeSymbols)
        {
            length = Math.Min(length, MaxLength);
            count  = Math.Min(count, MaxCount);
            if (count <= 0 || length <= 0)
            {
                yield break;
            }

            var sw    = System.Diagnostics.Stopwatch.StartNew();
            var chars = includeSymbols ? AllCharacters : AlphanumericCharacters;
            var sb    = new StringBuilder();

            for (int c = 0; c < count; c++)
            {
                for (int l = 0; l < length; l++)
                {
                    sb.Append(chars[random.GetRandomInt32(chars.Length)]);
                }

                var result = sb.ToString();
                yield return(result);

                sb.Clear();
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("AlphaNumeric", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count);
        }
        [OutputCache(Duration = 60 * 60)]       // Cache for one hour.
#endif
        public ActionResult Combinations(int?l, string bmp, string asian)
        {
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), 1);

            var length = Math.Min(l.HasValue ? l.Value : DefaultLength, MaxLength);
            var onlyFromBasicMultilingualPlane = bmp.IsTruthy(DefaultBmp);
            var includeEastAsianCharacters     = asian.IsTruthy(DefaultAsian);

            var allowedCategories = includeEastAsianCharacters ? AsianCategories : DefaultCategories;
            var mask = onlyFromBasicMultilingualPlane ? 0x0000ffff : 0x001fffff;

            // This takes ~100ms to calculate on Murray's laptop, so we cache it.
            // Unless new unicode characters magicly appear, the result will always be the same for our 3 inputs.
            var cacheKey = (length
                            | (onlyFromBasicMultilingualPlane ? 0x01000000 : 0)
                            | (includeEastAsianCharacters ? 0x02000000 : 0)).ToString("x8");
            int keyspace      = 0;
            var maybeKeyspace = MemoryCache.Default[cacheKey];

            if (maybeKeyspace == null)
            {
                maybeKeyspace = Enumerable.Range(0, 0x001fffff & mask)
                                .Where(cp => !(this.InvalidSurrogateCodePoints(cp) || this.InvalidMaxCodePoints(cp)))
                                .Select(cp => Char.ConvertFromUtf32(cp))
                                .Where(s => allowedCategories.Contains(Char.GetUnicodeCategory(s, 0)))
                                .Count();
                MemoryCache.Default.Add(cacheKey, maybeKeyspace, DateTimeOffset.Now.AddHours(8));
            }
            keyspace = (int)maybeKeyspace;

            // Return information about the number of combinations as a JSON object.
            var result = new JsonCombinationContainer();

            result.combinations = Math.Pow(keyspace, length);
            return(new JsonNetResult(result));
        }
예제 #16
0
        /// <summary>
        /// Starts listening on the specified remote endpoints.
        /// </summary>
        /// <param name="remoteEps">The remote eps.</param>
        public void StartListening(params IPEndPoint[] remoteEps)
        {
            if (remoteEps == null || remoteEps.Length == 0)
            {
                remoteEps = new IPEndPoint[] { Protocol.DiscoveryEndpoints.IPv4 }
            }
            ;

            lock (this.Server)
            {
                if (!this.Server.IsListening)
                {
                    this.Server.StartListening();
                }

                this.Server.EnableBroadcast = true;

                // Join all the multicast groups specified
                foreach (IPEndPoint ep in remoteEps.Where(ep => IPAddressHelpers.IsMulticast(ep.Address)))
                {
                    this.Server.JoinMulticastGroupAllInterfaces(ep);
                }
            }
        }
        private IEnumerable <string> SelectPhrases(IRandomNumberGenerator random, int wordCount, int phraseCount, bool spaces, int minChars, int maxChars, NumericStyles whenNumeric, int numbersToAdd, AllUppercaseStyles whenUpper, int uppersToAdd)
        {
            if (minChars > maxChars)
            {
                yield break;
            }

            phraseCount = Math.Min(phraseCount, MaxCount);
            wordCount   = Math.Min(wordCount, MaxWords);
            if (phraseCount <= 0 || wordCount <= 0)
            {
                yield break;
            }

            var sw       = System.Diagnostics.Stopwatch.StartNew();
            var sb       = new StringBuilder();
            var dict     = Dictionary.Value;
            int attempts = 0;

            ICollection <IMutator> mutators = null;

            if (whenNumeric != NumericStyles.Never || whenUpper != AllUppercaseStyles.Never)
            {
                mutators = new List <IMutator>();
            }
            if (whenNumeric != NumericStyles.Never)
            {
                mutators.Add(new NumericMutator()
                {
                    When = whenNumeric, NumberOfNumbersToAdd = numbersToAdd
                });
            }
            if (whenUpper == AllUppercaseStyles.Anywhere)
            {
                mutators.Add(new UppercaseMutator()
                {
                    When = UppercaseStyles.Anywhere, NumberOfCharactersToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.StartOfWord)
            {
                mutators.Add(new UppercaseMutator()
                {
                    When = UppercaseStyles.StartOfWord, NumberOfCharactersToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.WholeWord)
            {
                mutators.Add(new UppercaseWordMutator()
                {
                    NumberOfWordsToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.RunOfLetters)
            {
                mutators.Add(new UppercaseRunMutator()
                {
                    NumberOfRuns = uppersToAdd
                });
            }
            MurrayGrant.ReadablePassphrase.Random.RandomSourceBase randomWrapper = null;
            if (mutators != null)
            {
                randomWrapper = new MurrayGrant.ReadablePassphrase.Random.ExternalRandomSource(random.GetRandomBytes);
            }

            for (int c = 0; c < phraseCount; c++)
            {
                do
                {
                    // Generate a phrase.
                    for (int l = 0; l < wordCount; l++)
                    {
                        sb.Append(dict[random.GetRandomInt32(dict.Count)]);
                        sb.Append(' ');
                    }
                    sb.Remove(sb.Length - 1, 1);

                    // Apply mutators.
                    if (mutators != null)
                    {
                        foreach (var m in mutators)
                        {
                            m.Mutate(sb, randomWrapper);
                        }
                    }

                    // Finally, remove spaces if required (as the mutators depend on whitespace to do their work).
                    if (!spaces)
                    {
                        for (int i = sb.Length - 1; i >= 0; i--)
                        {
                            if (sb[i] == ' ')
                            {
                                sb.Remove(i, 1);
                            }
                        }
                    }

                    attempts++;

                    // Ensure the final phrase is within the min / max chars.
                } while (attempts < MaxAttemptsPerCount && (sb.Length < minChars || sb.Length > maxChars));
                if (attempts >= MaxAttemptsPerCount)
                {
                    sb.Clear();
                    sb.Append("A passphrase could not be found matching your minimum and maximum length requirements");
                }


                // Yield the phrase and reset state.
                var result = sb.ToString();
                yield return(result);

                sb.Clear();
                attempts = 0;
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("Passphrase", phraseCount, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), phraseCount);
        }
예제 #18
0
        /// <summary>
        /// Starts listening on the specified remote endpoints.
        /// </summary>
        /// <param name="groups">The remote eps.</param>
        public virtual void StartListening(params IPAddress[] groups)
        {
            if (groups == null || groups.Length == 0)
            {
                groups = new[] { Protocol.DiscoveryEndpoints.IPv4 }
            }
            ;

            ForEachSocket(socket =>
            {
                if (!socket.IsListening)
                {
                    socket.StartListening();
                }

                /* TODO: might need to update this slightly. It was this way in SsdpSearch:
                 *
                 *             if (!this.Server.EnableBroadcast)
                 *                  this.Server.EnableBroadcast = destinations.Any(ep => ep.Address.Equals(IPAddress.Broadcast));
                 *
                 */
                socket.EnableBroadcast = true;

                Trace.WriteLine(string.Format("Listening on {0}", socket.LocalEndpoint), AppInfo.Application);
                // Join all the multicast groups specified
                foreach (var group in groups.Where(ep => ep.AddressFamily == socket.LocalEndpoint.AddressFamily && IPAddressHelpers.IsMulticast(ep)))
                {
                    socket.JoinMulticastGroup(group);
                    Trace.WriteLine(string.Format("Interface {0} joined igmp group {1}", socket.LocalEndpoint, group), AppInfo.Application);
                }
            });
        }
        private IEnumerable <string> SelectPasswords(IRandomNumberGenerator random, int length, int count, bool onlyFromBasicMultilingualPlane, bool includeEastAsianCharacters)
        {
            length = Math.Min(length, MaxLength);
            count  = Math.Min(count, MaxCount);
            if (count <= 0 || length <= 0)
            {
                yield break;
            }
            var allowedCategories = includeEastAsianCharacters ? AsianCategories : DefaultCategories;

            var sw = System.Diagnostics.Stopwatch.StartNew();
            int numberOfCharacters = 0, attempts = 0;
            var mask = onlyFromBasicMultilingualPlane ? 0x0000ffff : 0x001fffff;
            var sb   = new StringBuilder();

            for (int i = 0; i < count; i++)
            {
                numberOfCharacters = 0;
                attempts           = 0;
                sb.Clear();

                while (numberOfCharacters < length)
                {
                    // Get random int32 and create a code point from it.
                    // PERF: can reduce number of bytes required here based on the mask.
                    var codePoint = random.GetRandomInt32();
                    codePoint = codePoint & mask;       // Mask off the top bits, which aren't used.
                    attempts++;

                    // Break if too many attempts.
                    if (attempts > MaxAttemptsPerCodePoint)
                    {
                        continue;
                    }

                    // Surrogate code points are invalid.
                    if (this.InvalidSurrogateCodePoints(codePoint))
                    {
                        continue;
                    }
                    // Ensure the code point is not outside the maximum range.
                    if (this.InvalidMaxCodePoints(codePoint))
                    {
                        continue;
                    }

                    // the Int32 to up to 2 Char structs (in a string).
                    var s        = Char.ConvertFromUtf32(codePoint);
                    var category = Char.GetUnicodeCategory(s, 0);
                    if (!allowedCategories.Contains(category))
                    {
                        // Not allowed category.
                        continue;
                    }
                    sb.Append(s);
                    numberOfCharacters++;
                }

                var result = sb.ToString();
                yield return(result);

                attempts = 0;
            }
            sw.Stop();


            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("Unicode", count, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), count);
        }
예제 #20
0
        private IEnumerable <string> SelectPhrases(IRandomNumberGenerator random, PhraseStrength strength, int phraseCount, bool includeSpaces, int minChars, int maxChars, NumericStyles whenNumeric, int numbersToAdd, AllUppercaseStyles whenUpper, int uppersToAdd)
        {
            if (minChars > maxChars)
            {
                yield break;
            }

            phraseCount = Math.Min(phraseCount, MaxCount);
            if (phraseCount <= 0)
            {
                yield break;
            }

            var sw        = System.Diagnostics.Stopwatch.StartNew();
            var generator = this.GetGenerator(random);
            int attempts  = 0;
            ICollection <IMutator> mutators = null;

            if (whenNumeric != NumericStyles.Never || whenUpper != AllUppercaseStyles.Never)
            {
                mutators = new List <IMutator>();
            }
            if (whenNumeric != NumericStyles.Never)
            {
                mutators.Add(new NumericMutator()
                {
                    When = whenNumeric, NumberOfNumbersToAdd = numbersToAdd
                });
            }
            if (whenUpper == AllUppercaseStyles.Anywhere)
            {
                mutators.Add(new UppercaseMutator()
                {
                    When = UppercaseStyles.Anywhere, NumberOfCharactersToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.StartOfWord)
            {
                mutators.Add(new UppercaseMutator()
                {
                    When = UppercaseStyles.StartOfWord, NumberOfCharactersToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.WholeWord)
            {
                mutators.Add(new UppercaseWordMutator()
                {
                    NumberOfWordsToCapitalise = uppersToAdd
                });
            }
            else if (whenUpper == AllUppercaseStyles.RunOfLetters)
            {
                mutators.Add(new UppercaseRunMutator()
                {
                    NumberOfRuns = uppersToAdd
                });
            }

            for (int c = 0; c < phraseCount; c++)
            {
                string candidate = "";
                do
                {
                    // Generate a phrase.
                    candidate = generator.Generate(strength, " ", mutators);

                    // Finally, remove spaces if required (as the mutators depend on whitespace to do their work).
                    if (!includeSpaces)
                    {
                        candidate = new string(candidate.Where(ch => ch != ' ').ToArray());
                    }
                    attempts++;

                    // Ensure the final phrase is within the min / max chars.
                } while (attempts < MaxAttemptsPerCount && (candidate.Length < minChars || candidate.Length > maxChars));
                if (attempts >= MaxAttemptsPerCount)
                {
                    candidate = "A passphrase could not be found matching your minimum and maximum length requirements";
                }

                // Yield the phrase and reset state.
                yield return(candidate);

                attempts = 0;
            }
            sw.Stop();

            var bytesRequested = (int)((random as Terninger.Random.CypherBasedPrngGenerator)?.BytesRequested).GetValueOrDefault();

            RandomService.LogPasswordStat("ReadablePassphrase", phraseCount, sw.Elapsed, bytesRequested, IPAddressHelpers.GetHostOrCacheIp(Request).AddressFamily, HttpContext.GetApiKeyId());
            if (!IpThrottlerService.HasAnyUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request)))
            {
                RandomService.AddWebRequestEntropy(this.Request);
            }
            IpThrottlerService.IncrementUsage(IPAddressHelpers.GetHostOrCacheIp(this.HttpContext.Request), phraseCount);
        }