public HardwareInfo(IIssueReceiver sink) { try { var sortedMacAddresses = NetworkInterface.GetAllNetworkInterfaces() .Select(nic => nic.GetPhysicalAddress().ToString().ToLowerInvariant()) .OrderBy(s => s).ToArray(); MachineDigest = Utilities.Sha256TruncatedBase64(string.Join("|", sortedMacAddresses), 16); } catch (NetworkInformationException e) { sink.AcceptIssue(new Issue("Failed to query network interface. Function not affected.", e.ToString(), IssueSeverity.Warning)); MachineDigest = "none"; } LogicalCores = Environment.ProcessorCount; OperatingSystem64Bit = Environment.Is64BitOperatingSystem; var appDriveRoot = Path.GetPathRoot(HostingEnvironment.ApplicationPhysicalPath ?? Environment.CurrentDirectory); var allDrives = DriveInfo.GetDrives(); NetworkDrives = allDrives.Count(d => d.DriveType == DriveType.Network); OtherDrives = allDrives.Count(d => d.DriveType != DriveType.Network && d.DriveType != DriveType.Fixed); FixedDrives = allDrives.Where(d => d.DriveType == DriveType.Fixed && d.IsReady) .Select(d => new FixedDriveInfo { Filesystem = d.DriveFormat + (d.Name == appDriveRoot ? "*" : ""), TotalBytes = d.TotalSize, AvailableBytes = d.AvailableFreeSpace }).ToArray(); // TODO: cpu feature support }
/// <summary> /// Builds a tree of Nodes from the specified XML subtree. Duplicate attributes are sent to 'ir' /// </summary> /// <param name="e"></param> /// <param name="ir"></param> public Node(XmlElement e, IIssueReceiver ir) { name = e.LocalName; //Copy attributes, raising an issue if duplicates are found foreach (XmlAttribute a in e.Attributes) { if (attrs[a.LocalName] != null){ ir.AcceptIssue(new Issue("Two or more attributes named " + a.LocalName + " found on element " + name + " in " + e.ParentNode != null ? e.ParentNode.Name : "(unknown node)")); } attrs[a.LocalName] = a.Value; } //Parse children if (e.HasChildNodes) { StringBuilder sb = null; foreach (XmlNode n in e.ChildNodes) { if (n.NodeType == XmlNodeType.Element) { XmlElement child = n as XmlElement; if (child != null) children.Add(new Node(child, ir)); //Collect text and whitespace } else if (n.NodeType == XmlNodeType.Text || n.NodeType == XmlNodeType.EntityReference || n.NodeType == XmlNodeType.SignificantWhitespace) { //|| n.NodeType == XmlNodeType.Whitespace if (sb == null) sb = new StringBuilder(); sb.Append(n.Value); } } //Save text/whitespace if (sb != null) TextContents = sb.ToString(); } }
GetDomainMappings(ILicenseConfig c, IIssueReceiver sink, IReadOnlyCollection <string> knownDomains) //c.configurationSectionIssue { var mappings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var pair in c.GetDomainMappings()) { var from = pair.Key; var to = pair.Value; if (string.IsNullOrEmpty(from) || string.IsNullOrEmpty(to)) { sink.AcceptIssue(new Issue($"Both from= and to= attributes are required on maphost, found {from} and {to}", IssueSeverity.ConfigurationError)); } else if (!from.EndsWith(".local") && from.IndexOf('.') > -1) { sink.AcceptIssue(new Issue( $"You can only map non-public hostnames to arbitrary licenses. Skipping {from}", IssueSeverity.ConfigurationError)); } else if (!knownDomains.Contains(to)) { sink.AcceptIssue(new Issue( $"You have mapped {from} to {to}. {to} is not one of the known domains: {string.Join(" ", knownDomains.OrderBy(s => s))}", IssueSeverity.ConfigurationError)); } else { mappings[from] = to; } } return(mappings); }
public DomainLookup(ILicenseConfig c, IIssueReceiver sink, IEnumerable <ILicenseChain> licenseChains) { // What domains are mentioned in which licenses? var chainsByDomain = GetChainsByDomain(licenseChains); var knownDomains = chainsByDomain.Keys.ToList(); // What custom mappings has the user set up? var customMappings = GetDomainMappings(c, sink, knownDomains); // Start with identity mappings and the mappings for the normalized domains. lookupTable = new ConcurrentDictionary <string, string>( customMappings.Concat( knownDomains.Select(v => new KeyValuePair <string, string>(v, v))) , StringComparer.Ordinal); lookupTableSize = lookupTable.Count; // Set up a list for suffix searching suffixSearchList = knownDomains.Select(known => { var d = known.TrimStart('.'); d = d.StartsWith("www.") ? d.Substring(4) : d; return(new KeyValuePair <string, string>("." + d, known)); }) .ToList(); }
public MultiFolderStorage(string issueSource, string dataKind, IIssueReceiver sink, string[] candidateFolders, FolderOptions options) { this.dataKind = dataKind; this.issueSource = issueSource; this.candidateFolders = candidateFolders; this.sink = sink; this.options = options; }
internal LicenseEnforcer(LicenseManagerSingleton mgr, IIssueReceiver permanentIssueSink, Func <Uri> getCurrentRequestUrl) { this.mgr = mgr; this.GetCurrentRequestUrl = getCurrentRequestUrl; Clock = mgr.Clock; PermanentIssueSink = permanentIssueSink; trustedKeys = mgr.TrustedKeys; }
internal WriteThroughCache(string keyPrefix) { this.prefix = keyPrefix ?? prefix; sink = new IssueSink(sinkSource); var appPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath; var candidates = ((appPath != null) ? new string[] { Path.Combine(appPath, "imagecache"), Path.Combine(appPath, "App_Data"), Path.GetTempPath() } : new string[] { Path.GetTempPath() }).ToArray(); store = new MultiFolderStorage(sinkSource, dataKind, sink, candidates, FolderOptions.Default); }
public LicenseFetcher(ILicenseClock clock, Func <HttpClient> getClient, Action <string, IReadOnlyCollection <FetchResult> > licenseResult, Func <IInfoAccumulator> getInfo, IIssueReceiver sink, string licenseId, string licenseSecret, string[] baseUrls, long?licenseFetchIntervalSeconds) { this.clock = clock; LicenseFetchIntervalSeconds = licenseFetchIntervalSeconds ?? LicenseFetchIntervalSeconds; regular = new ImperfectDebounce(() => QueueLicenseFetch(false), LicenseFetchIntervalSeconds, clock); error = new ImperfectDebounce(() => QueueLicenseFetch(true), 0, clock); this.getClient = getClient; this.getInfo = getInfo; this.licenseResult = licenseResult; this.baseUrls = baseUrls; id = licenseId; secret = licenseSecret; this.sink = sink; }
/// <summary> /// Builds a tree of Nodes from the specified XML subtree. Duplicate attributes are sent to 'ir' /// </summary> /// <param name="e"></param> /// <param name="ir"></param> public Node(XmlElement e, IIssueReceiver ir) { name = e.LocalName; //Copy attributes, raising an issue if duplicates are found foreach (XmlAttribute a in e.Attributes) { if (attrs[a.LocalName] != null) { ir.AcceptIssue(new Issue("Two or more attributes named " + a.LocalName + " found on element " + name + " in " + e.ParentNode != null ? e.ParentNode.Name : "(unknown node)")); } attrs[a.LocalName] = a.Value; } //Parse children if (e.HasChildNodes) { StringBuilder sb = null; foreach (XmlNode n in e.ChildNodes) { if (n.NodeType == XmlNodeType.Element) { XmlElement child = n as XmlElement; if (child != null) { children.Add(new Node(child, ir)); } //Collect text and whitespace } else if (n.NodeType == XmlNodeType.Text || n.NodeType == XmlNodeType.EntityReference || n.NodeType == XmlNodeType.SignificantWhitespace) //|| n.NodeType == XmlNodeType.Whitespace { if (sb == null) { sb = new StringBuilder(); } sb.Append(n.Value); } } //Save text/whitespace if (sb != null) { TextContents = sb.ToString(); } } }
GetDomainMappings(Config c, IIssueReceiver sink, IReadOnlyCollection <string> knownDomains) //c.configurationSectionIssue { var mappings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); var fromWebConfig = c.getNode("licenses")?.childrenByName("maphost") .Select(n => new KeyValuePair <string, string>( n.Attrs["from"]?.Trim().ToLowerInvariant(), n.Attrs["to"]?.Trim().ToLowerInvariant())) ?? Enumerable.Empty <KeyValuePair <string, string> >(); var fromPluginsConfig = c.Plugins.GetLicensedDomainMappings(); foreach (var pair in fromWebConfig.Concat(fromPluginsConfig)) { var from = pair.Key; var to = pair.Value; if (string.IsNullOrEmpty(from) || string.IsNullOrEmpty(to)) { sink.AcceptIssue(new Issue($"Both from= and to= attributes are required on maphost, found {from} and {to}", IssueSeverity.ConfigurationError)); } else if (!from.EndsWith(".local") && from.IndexOf('.') > -1) { sink.AcceptIssue(new Issue( $"You can only map non-public hostnames to arbitrary licenses. Skipping {from}", IssueSeverity.ConfigurationError)); } else if (!knownDomains.Contains(to)) { sink.AcceptIssue(new Issue( $"You have mapped {from} to {to}. {to} is not one of the known domains: {string.Join(" ", knownDomains.OrderBy(s => s))}", IssueSeverity.ConfigurationError)); } else { mappings[from] = to; } } return(mappings); }
/// <summary> /// Here's how the original version calculated candidateFolders. /// /// <code> /// var appPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath; /// var candidates = ((appPath != null) ? /// new string[] { Path.Combine(appPath, "imagecache"), /// Path.Combine(appPath, "App_Data"), Path.GetTempPath() } /// : new string[] { Path.GetTempPath() }).ToArray(); /// </code> /// </summary> /// <param name="keyPrefix"></param> /// <param name="candidateFolders"></param> internal WriteThroughCache(string keyPrefix, string[] candidateFolders) { prefix = keyPrefix ?? prefix; sink = new IssueSink(sinkSource); store = new MultiFolderStorage(sinkSource, dataKind, sink, candidateFolders, FolderOptions.Default); }
public Computation(Config c, IReadOnlyCollection <RSADecryptPublic> trustedKeys, IIssueReceiver permanentIssueSink, ILicenseManager mgr, ILicenseClock clock, bool enforcementEnabled) : base("Computation") { permanentIssues = permanentIssueSink; EnforcementEnabled = enforcementEnabled; this.clock = clock; Scope = c.Plugins.LicenseScope; LicenseError = c.Plugins.LicenseError; this.mgr = mgr; if (mgr.FirstHeartbeat == null) { throw new ArgumentException("ILicenseManager.Heartbeat() must be called before Computation.new"); } // What features are installed on this instance? // For a license to be OK, it must have one of each of this nested list; IEnumerable <IEnumerable <string> > pluginFeaturesUsed = c.Plugins.GetAll <ILicensedPlugin>().Select(p => p.LicenseFeatureCodes).ToList(); // Create or fetch all relevant license chains; ignore the empty/invalid ones, they're logged to the manager instance chains = c.Plugins.GetAll <ILicenseProvider>() .SelectMany(p => p.GetLicenses()) .Select(str => mgr.GetOrAdd(str, c.Plugins.LicenseScope)) .Where(x => x != null && x.Licenses().Any()) .Concat(Scope.HasFlag(LicenseAccess.ProcessReadonly) ? mgr.GetSharedLicenses() : Enumerable.Empty <ILicenseChain>()) .Distinct() .ToList(); // Set up our domain map/normalize/search manager domainLookup = new DomainLookup(c, permanentIssueSink, chains); // Check for tampering via interfaces if (chains.Any(chain => chain.Licenses().Any(b => !b.Revalidate(trustedKeys)))) { EverythingDenied = true; permanentIssueSink.AcceptIssue(new Issue( "Licenses failed to revalidate; please contact [email protected]", IssueSeverity.Error)); } // Look for grace periods var gracePeriods = chains.Where(IsPendingLicense).Select(GetGracePeriodFor).ToList(); // Look for fetched and valid licenses var validLicenses = chains.Where(chain => !IsPendingLicense(chain)) .SelectMany(chain => chain.Licenses()) .Where(b => !b.Fields.IsRemotePlaceholder() && IsLicenseValid(b)) .ToList(); // This computation expires when we cross an expires, issued date, or NetworkGracePeriod expiration ComputationExpires = chains.SelectMany(chain => chain.Licenses()) .SelectMany(b => new[] { b.Fields.Expires, b.Fields.Issued }) .Concat(gracePeriods) .Where(date => date != null) .OrderBy(d => d) .FirstOrDefault(d => d > clock.GetUtcNow()); AllDomainsLicensed = gracePeriods.Any(t => t != null) || validLicenses .Any(license => !license.Fields.GetAllDomains().Any() && AreFeaturesLicensed(license, pluginFeaturesUsed, false)); KnownDomainStatus = validLicenses.SelectMany( b => b.Fields.GetAllDomains() .SelectMany(domain => b.Fields.GetFeatures() .Select( feature => new KeyValuePair <string, string>( domain, feature)))) .GroupBy(pair => pair.Key, pair => pair.Value, (k, v) => new KeyValuePair <string, IEnumerable <string> >(k, v)) .Select(pair => new KeyValuePair <string, bool>(pair.Key, pluginFeaturesUsed.All( set => set.Intersect(pair.Value, StringComparer.OrdinalIgnoreCase) .Any()))) .ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.Ordinal); if (UpgradeNeeded()) { foreach (var b in validLicenses) { AreFeaturesLicensed(b, pluginFeaturesUsed, true); } } }