Пример #1
0
        // make a clone of all GraphNode except that only a few GraphEdge are kept
        // remove all uneeded GraphEdge to have only one GraphEdge between 2 GraphNodes (direct or indirect link)
        private GraphNode GenerateSimplifiedGraph(GraphNodeCollection nodes, GraphNode centralNode)
        {
            List <GraphNode> nodeAlreadyExamined = new List <GraphNode>();

            GraphNode output = GraphNode.CloneWithoutTrusts(centralNode);

            Dictionary <DomainKey, GraphNode> graph = new Dictionary <DomainKey, GraphNode>();

            graph.Add(output.Domain, output);

            List <GraphNode> nodesToExamine = new List <GraphNode>();

            nodesToExamine.Add(centralNode);
            // proceed layer by layer
            for (int currentLevel = 0; ; currentLevel++)
            {
                List <GraphNode> nodesToExamineForNextLevel = new List <GraphNode>();
                // this first iteration is important
                // it avoid a recursing exploration
                foreach (GraphNode nodeToExamine in nodesToExamine)
                {
                    nodeAlreadyExamined.Add(nodeToExamine);
                }
                foreach (GraphNode nodeToExamine in nodesToExamine)
                {
                    foreach (GraphEdge edge in nodeToExamine.Trusts.Values)
                    {
                        if (!nodeAlreadyExamined.Contains(edge.Destination) &&
                            !nodesToExamine.Contains(edge.Destination) &&
                            !nodesToExamineForNextLevel.Contains(edge.Destination))
                        {
                            // make a clone and add one GraphEdge
                            nodesToExamineForNextLevel.Add(edge.Destination);
                            graph.Add(edge.Destination.Domain, GraphNode.CloneWithoutTrusts(edge.Destination));
                            GraphEdge newEdge = new GraphEdge(graph[nodeToExamine.Domain], graph[edge.Destination.Domain], null, false);
                            graph[nodeToExamine.Domain].Trusts.Add(edge.Destination.Domain, newEdge);
                        }
                    }
                }
                if (nodesToExamineForNextLevel.Count == 0)
                {
                    break;
                }
                nodesToExamine = nodesToExamineForNextLevel;
            }
            return(output);
        }
Пример #2
0
        public bool IsEquivalentToReverseEdge(MigrationChecker migrationChecker)
        {
            if (TrustDirection != 3)
            {
                return(false);
            }
            // when there is a bidirectional trust, there are two GraphEdge
            // one starting from source and one starting from the other domain
            GraphEdge reverseEdge = Destination.Trusts[Source.Domain];

            if (reverseEdge.TrustAttributes == TrustAttributes &&
                GetSIDFilteringStatus(migrationChecker) == reverseEdge.GetSIDFilteringStatus(migrationChecker))
            {
                return(true);
            }
            return(false);
        }
Пример #3
0
 // authoritative data is considered as coming from the AD directly
 // non authoritative is deducted data
 private void Link(GraphNode destination, HealthCheckTrustData trust, bool isAuthoritative)
 {
     //Trace.WriteLine("Linking " + Domain + " to " + destination.Domain);
     if (!Trusts.ContainsKey(destination.Domain))
     {
         GraphEdge edge = new GraphEdge(this, destination, trust, isAuthoritative);
         Trusts[destination.Domain] = edge;
         edge = new GraphEdge(destination, this, GetReverseTrust(trust), false);
         destination.Trusts[this.Domain] = edge;
     }
     else if (isAuthoritative)
     {
         Trusts[destination.Domain].SetAuthorativeTrustData(trust);
     }
     else
     {
         //Trace.WriteLine("non authoritative data & trust already exists");
     }
 }
Пример #4
0
        public string GenerateJsonFileFull(MigrationChecker migrationChecker)
        {
            Dictionary <int, int> idconversiontable = new Dictionary <int, int>();
            StringBuilder         sb = new StringBuilder();

            sb.Append("{");
            // START OF NODES

            sb.Append("  \"nodes\": [");
            // it is important to put the root node as the first node for correct display
            int  nodenumber = 0;
            bool firstnode  = true;

            foreach (GraphNode node in Nodes)
            {
                if (!firstnode)
                {
                    sb.Append("    },");
                }
                else
                {
                    firstnode = false;
                }
                sb.Append("    {");
                sb.Append("      \"id\": " + nodenumber + ",");
                sb.Append("      \"shortname\": \"" + EscapeJsonString(node.Domain.DomainName.Split('.')[0]) + "\"");
                if (node.IsPartOfARealForest())
                {
                    sb.Append("      ,\"forest\": \"" + EscapeJsonString(node.Forest.DomainName) + "\"");
                }
                var entity = node.Entity;
                if (entity != null)
                {
                    sb.Append(entity.GetJasonOutput());
                }
                HealthcheckData data = node.HealthCheckData;
                sb.Append("      ,\"name\": \"" + EscapeJsonString(node.Domain.DomainName) + "\"");
                if (data != null)
                {
                    sb.Append("      ,\"score\": " + data.GlobalScore);
                    sb.Append("      ,\"staleObjectsScore\": " + data.StaleObjectsScore);
                    sb.Append("      ,\"privilegiedGroupScore\": " + data.PrivilegiedGroupScore);
                    sb.Append("      ,\"trustScore\": " + data.TrustScore);
                    sb.Append("      ,\"anomalyScore\": " + data.AnomalyScore);
                    if (data.UserAccountData != null)
                    {
                        sb.Append("      ,\"activeusers\": " + data.UserAccountData.NumberActive);
                    }
                    if (data.ComputerAccountData != null)
                    {
                        sb.Append("      ,\"activecomputers\": " + data.ComputerAccountData.NumberActive);
                    }
                }
                sb.Append("      ,\"dist\": null");
                idconversiontable[node.Id] = nodenumber++;
            }
            if (Nodes.Count > 0)
            {
                sb.Append("    }");
            }
            sb.Append("  ],");
            // END OF NODES
            // START LINKS
            sb.Append("  \"links\": [");
            // avoid a final ","
            bool absenceOfLinks = true;
            // subtility: try to regroup 2 links at one if all the properties match
            // SkipLink contains the edge to ignore
            List <GraphEdge> SkipLink = new List <GraphEdge>();

            // foreach edge
            foreach (GraphNode node in Nodes)
            {
                foreach (GraphEdge edge in node.Trusts.Values)
                {
                    if (SkipLink.Contains(edge))
                    {
                        continue;
                    }
                    // for unidirectional trusts
                    // keep only the remote part of the trust. SID Filtering is unknown (avoid evaluating SID Filtering when no value is available)
                    if (edge.TrustDirection == 2 && edge.IsAuthoritative == false)
                    {
                        continue;
                    }
                    // keep only the reception of the trust. SID Filtering status is sure
                    if (edge.TrustDirection == 1 && edge.Destination.Trusts[edge.Source.Domain].IsAuthoritative == true)
                    {
                        continue;
                    }
                    // trying to simplify bidirectional trusts
                    bool isBidirectional = false;
                    if (edge.IsEquivalentToReverseEdge(migrationChecker))
                    {
                        GraphEdge reverseEdge = edge.Destination.Trusts[edge.Source.Domain];
                        // keep only one of the two part of the bidirectional trust
                        SkipLink.Add(reverseEdge);
                        isBidirectional = true;
                    }
                    if (!absenceOfLinks)
                    {
                        sb.Append("    },");
                    }
                    else
                    {
                        absenceOfLinks = false;
                    }
                    sb.Append("    {");
                    if (edge.TrustDirection == 2)
                    {
                        sb.Append("      \"source\": " + idconversiontable[edge.Destination.Id] + ",");
                        sb.Append("      \"target\": " + idconversiontable[edge.Source.Id] + ",");
                    }
                    else
                    {
                        sb.Append("      \"source\": " + idconversiontable[edge.Source.Id] + ",");
                        sb.Append("      \"target\": " + idconversiontable[edge.Destination.Id] + ",");
                    }
                    // blue: 25AEE4
                    // orange: FA9426
                    string sidFiltering = edge.GetSIDFilteringStatus(migrationChecker);
                    if (!edge.IsActive)
                    {
                        // purple
                        sb.Append("      \"color\": \"#A856AA\",");
                    }
                    else
                    {
                        switch (sidFiltering)
                        {
                        case "Remote":
                            // yellow
                            sb.Append("      \"color\": \"#FDC334\",");
                            break;

                        case "Migration":
                            // blue
                            sb.Append("      \"color\": \"#25AEE4\",");
                            break;

                        case "No":
                            // red
                            sb.Append("      \"color\": \"#E75351\",");
                            break;

                        case "Yes":
                            // green
                            sb.Append("      \"color\": \"#74C25C\",");
                            break;
                        }
                    }
                    if (isBidirectional)
                    {
                        sb.Append("      \"type\": \"double\",");
                    }
                    sb.Append("      \"rels\": [\"");
                    sb.Append("Attributes=" + edge.GetTrustAttributes() + ",");
                    if (edge.CreationDate != DateTime.MinValue)
                    {
                        sb.Append("CreationDate=" + edge.CreationDate.ToString("yyyy-MM-dd") + ",");
                    }
                    sb.Append("SIDFiltering=" + sidFiltering);
                    sb.Append((edge.IsActive ? null : ",Inactive"));
                    sb.Append("\"]");
                }
            }
            if (!absenceOfLinks)
            {
                sb.Append("    }");
            }
            sb.Append("  ]");
            // END OF LINKS
            sb.Append("}");
            return(sb.ToString());
        }