Skip to content

Commit

Permalink
Merge branch 'master' of github.com:lkarlslund/adalanche
Browse files Browse the repository at this point in the history
  • Loading branch information
lkarlslund committed Dec 12, 2024
2 parents 3799533 + 3671804 commit dd938d5
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 134 deletions.
31 changes: 29 additions & 2 deletions modules/aql/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import (
type AQLresolver interface {
Resolve(ResolverOptions) (*graph.Graph[*engine.Object, engine.EdgeBitmap], error)
}

type IndexLookup struct {
v engine.AttributeValue
a engine.Attribute
}

type NodeQuery struct {
IndexLookup IndexLookup // Possible start of search, quickly narrows it down
Selector query.NodeFilter // Where style boolean approval filter for objects
Expand Down Expand Up @@ -149,14 +151,26 @@ func (aqlq AQLquery) Resolve(opts ResolverOptions) (*graph.Graph[*engine.Object,
}
for i, q := range aqlq.Next {
if q.PathNodeRequirement != nil {
aqlq.sourceCache[i] = q.PathNodeRequirement.Populate(aqlq.datasource)
aqlq.Next[i].pathNodeRequirementCache = q.PathNodeRequirement.Populate(aqlq.datasource)
}
pb.Add(1)
}
pb.Add(1)
pb.Finish()
// nodes := make([]*engine.Objects, len(aqlq.Sources))
result := graph.NewGraph[*engine.Object, engine.EdgeBitmap]()

if len(aqlq.Sources) == 1 {
aqlq.sourceCache[0].Iterate(func(o *engine.Object) bool {
result.AddNode(o)
if aqlq.Sources[0].ReferenceName != "" {
result.SetNodeData(o, "reference", aqlq.Sources[0].ReferenceName)
}
return true
})
return &result, nil
}

var resultlock sync.Mutex
nodeindex := 0
// Iterate over all starting nodes
Expand Down Expand Up @@ -188,8 +202,10 @@ func (aqlq AQLquery) resolveEdgesFrom(
currentDepth int,
currentTotalDepth int,
currentOverAllProbability float64) {

es := aqlq.Next[currentSearchIndex]
targets := aqlq.sourceCache[currentSearchIndex+1] // next node query

if workingGraph == nil {
workingGraphTemp := (graph.NewGraph[*engine.Object, engine.EdgeBitmap]())
workingGraph = &workingGraphTemp
Expand All @@ -203,6 +219,7 @@ func (aqlq AQLquery) resolveEdgesFrom(
case engine.Any:
directions = directionsAny
}

// We don't need matches, so try skipping this one
if es.MinIterations == 0 && currentDepth == 0 {
if len(aqlq.Next) > currentSearchIndex+1 {
Expand Down Expand Up @@ -238,6 +255,7 @@ func (aqlq AQLquery) resolveEdgesFrom(
}
}
matchedEdges := es.FilterEdges.Bitmap.Intersect(eb)

// Check we have enough matches
if es.FilterEdges.Comparator != query.CompareInvalid {
if !query.Comparator[int64](es.FilterEdges.Comparator).Compare(int64(matchedEdges.Count()), es.FilterEdges.Count) {
Expand All @@ -248,17 +266,25 @@ func (aqlq AQLquery) resolveEdgesFrom(
return true
}
}

if es.pathNodeRequirementCache != nil && !es.pathNodeRequirementCache.Contains(nextObject) {
// Node we reached is not wanted
return true
}

edgeProbability := matchedEdges.MaxProbability(currentObject, nextObject)
// Honor query for this edge probability
if es.ProbabilityComparator != query.CompareInvalid {
if !query.Comparator[engine.Probability](es.ProbabilityComparator).Compare(edgeProbability, es.ProbabilityValue) {
return true
}
}

// Honor options for this edge probability
if edgeProbability < opts.MinEdgeProbability {
return true
}

// Honor options for overall probability
currentOverAllProbability *= float64(edgeProbability) / 100
if currentOverAllProbability*100 < float64(aqlq.OverAllProbability) {
Expand All @@ -269,6 +295,7 @@ func (aqlq AQLquery) resolveEdgesFrom(
if es.FilterEdges.NoTrimEdges {
addedge = eb
}

if currentDepth >= es.MinIterations && currentDepth <= es.MaxIterations {
// Add this to our working graph
hadCurrentNode := workingGraph.HasNode(currentObject)
Expand Down Expand Up @@ -297,7 +324,7 @@ func (aqlq AQLquery) resolveEdgesFrom(
}
}
// can we go deeper?
if currentDepth < es.MaxIterations && (es.pathNodeRequirementCache == nil || es.pathNodeRequirementCache.Contains(nextObject)) {
if currentDepth < es.MaxIterations {
aqlq.resolveEdgesFrom(opts, committedGraph, workingGraph, nextObject, currentSearchIndex, currentDepth, currentTotalDepth, currentOverAllProbability)
}
if direction == engine.Out {
Expand Down
9 changes: 4 additions & 5 deletions modules/frontend/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
<script src="external/popper.min.js"></script>
<script src="external/tippy.min.js"></script>
<script src="external/interact.min.js"></script>
<!-- <script src="external/jquery-ui-1.13.2.custom/jquery-ui.min.js"></script> -->
<script src="external/jstree/jstree.min.js"></script>
<script src="external/autosize.js"></script>

Expand Down Expand Up @@ -129,7 +128,7 @@
id="optionstogglevisibility"
class="d-inline-block align-top bs-bg-dark border p-1 pe-auto"
>
Options
Options <i class="bi-arrow-left-right"></i>
</div>
<div id="optionspanel" class="bg-dark overflow-y-auto pe-auto">
<div id="optionscontent" class="w-100">
Expand Down Expand Up @@ -458,7 +457,7 @@
<div id="status" class="border bg-dark p-2 shadow pe-auto z-40"></div>

<div id="outerquery" class="card border mb-0 mt-0 p-0 pe-auto z-50">
<div id="togglequeryvisible" class="text-center mx-4">AQL Search</div>
<div id="togglequeryvisible" class="text-center mx-4">AQL Search <i class="bi-arrow-down-up"></i></div>
<div id="querybox" class="mb-2 mx-2">
<form id="aqlqueryform" class="m-0">
<textarea
Expand Down Expand Up @@ -501,8 +500,8 @@
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</body>

<script type="text/javascript" src="external/bootstrap/js/bootstrap.min.js"></script>
Expand Down
17 changes: 5 additions & 12 deletions modules/frontend/html/preferences.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let prefs = {};

function loadprefs() {
$.ajax({
return $.ajax({
url: "/api/preferences",
dataType: "json",
success: function (data) {
Expand Down Expand Up @@ -34,16 +34,6 @@ function onchangepreference(ele) {
} else {
setpref(ele.attr("preference"), ele.val())
}
saveprefs()
}

function saveprefs() {
$.ajax({
method: "POST",
url: "/api/preferences",
dataType: "json",
data: JSON.stringify(prefs),
});
}

function getpref(key, defvalue) {
Expand All @@ -59,7 +49,10 @@ function getpref(key, defvalue) {

function setpref(key, value) {
prefs[key] = value;
saveprefs();
$.ajax({
method: "GET",
url: `/api/preferences/${key}/${value}`,
});
}

$(function () {
Expand Down
64 changes: 64 additions & 0 deletions modules/frontend/preferences.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package frontend

import (
"encoding/json"
"maps"

"github.com/gin-gonic/gin"
"github.com/lkarlslund/adalanche/modules/persistence"
)

type Preference struct {
Name string `json:"name"`
Value any `json:"value"`
}

func (p Preference) ID() string {
return p.Name
}

func AddPreferencesEndpoints(ws *WebService) {
// Saved preferences
sb := persistence.GetStorage[Preference]("preferences", false)

preferences := ws.API.Group("preferences")

preferences.GET("", func(c *gin.Context) {
prefs, err := sb.List()
if err != nil {
return
}
prefsmap := maps.Collect[string, any](func(yield func(string, any) bool) {
for _, pref := range prefs {
if !yield(pref.Name, pref.Value) {
break
}
}
})
c.JSON(200, prefsmap)
})
preferences.POST("", func(c *gin.Context) {
var prefsmap = make(map[string]any)
err := c.BindJSON(&prefsmap)
if err != nil {
c.String(500, err.Error())
}
for key, value := range prefsmap {
sb.Put(Preference{Name: key, Value: value})
}
})
preferences.GET(":key", func(c *gin.Context) {
key := c.Param("key")
pref, found := sb.Get(key)
if !found {
return
}
out, _ := json.Marshal(pref.Value)
c.Writer.Write(out)
})
preferences.GET(":key/:value", func(c *gin.Context) {
key := c.Param("key")
value := c.Param("value")
sb.Put(Preference{Name: key, Value: value})
})
}
35 changes: 0 additions & 35 deletions modules/frontend/webservicefuncs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package frontend

import (
"encoding/json"
"fmt"
"reflect"
"slices"
Expand All @@ -16,7 +15,6 @@ import (
"github.com/lkarlslund/adalanche/modules/engine"
"github.com/lkarlslund/adalanche/modules/integrations/activedirectory"
"github.com/lkarlslund/adalanche/modules/query"
"github.com/lkarlslund/adalanche/modules/settings"
"github.com/lkarlslund/adalanche/modules/ui"
"github.com/lkarlslund/adalanche/modules/util"
"github.com/lkarlslund/adalanche/modules/version"
Expand Down Expand Up @@ -173,39 +171,6 @@ func AddUIEndpoints(ws *WebService) {
ws.quit <- true
})
}
func AddPreferencesEndpoints(ws *WebService) {
// Saved preferences
err := settings.Load()
if err != nil {
ui.Warn().Msgf("Problem loading preferences: %v", err)
}
preferences := ws.API.Group("preferences")
preferences.GET("", func(c *gin.Context) {
c.JSON(200, settings.All())
})
preferences.POST("", func(c *gin.Context) {
var prefsmap = make(map[string]any)
err := c.BindJSON(&prefsmap)
if err != nil {
c.String(500, err.Error())
}
for key, value := range prefsmap {
settings.Set(key, value)
}
settings.Save()
})
preferences.GET(":key", func(c *gin.Context) {
key := c.Param("key")
out, _ := json.Marshal(settings.Get(key))
c.Writer.Write(out)
})
preferences.GET(":key/:value", func(c *gin.Context) {
key := c.Param("key")
value := c.Param("value")
settings.Set(key, value)
settings.Save()
})
}
func AddDataEndpoints(ws *WebService) {
api := ws.API
// Returns JSON describing an object located by distinguishedName, sid or guid
Expand Down
19 changes: 11 additions & 8 deletions modules/integrations/activedirectory/analyze/analyze-ad.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ func init() {
DomainJoinedSID, sid,
engine.IgnoreBlanks,
engine.Name, computeraccount.Attr(engine.Name),
activedirectory.Type, "Machine",
activedirectory.Type, ObjectTypeMachine.ValueString(),
DnsHostName, computeraccount.Attr(DnsHostName),
)
// ui.Debug().Msgf("Added machine for SID %v", sid.String())
Expand All @@ -980,7 +980,7 @@ func init() {
})
},
"creating Machine objects (representing the machine running the OS)",
engine.BeforeMerge)
engine.BeforeMergeLow)

LoaderID.AddProcessor(func(ao *engine.Objects) {
// Ensure everyone has a family
Expand Down Expand Up @@ -1238,12 +1238,6 @@ func init() {
)

LoaderID.AddProcessor(func(ao *engine.Objects) {
DCsyncObject, _ := ao.FindTwoOrAdd(
engine.Type, engine.ObjectTypeCallableServicePoint.ValueString(),
engine.Name, engine.NewAttributeValueString("DCsync"),
)
DCsyncObject.Tag("hvt")

// Generate member of chains
everyonesid, _ := windowssecurity.ParseStringSID("S-1-1-0")
everyone := FindWellKnown(ao, everyonesid)
Expand All @@ -1264,6 +1258,12 @@ func init() {
ui.Fatal().Msgf("Could not get needed domain information (%v), aborting", err)
}

DCsyncObject, _ := ao.FindTwoOrAdd(
engine.Type, engine.ObjectTypeCallableServicePoint.ValueString(),
engine.Name, engine.NewAttributeValueString("DCsync"),
)
DCsyncObject.Tag("hvt")

dnsroot = strings.ToLower(dnsroot)
TrustMap.Store(TrustPair{
SourceNCName: ncname,
Expand Down Expand Up @@ -1407,6 +1407,7 @@ func init() {
ui.Warn().Msgf("Can not find machine object for RODC %v", object.DN())
} else {
machine.Tag("role-readonly-domaincontroller")
machine.Tag("hvt")
}

// Figure out what hashes this machine has cached - FIXME!
Expand Down Expand Up @@ -1880,6 +1881,8 @@ func init() {
); found {
ca.Tag("role-certificate-authority")
ca.Tag("hvt")
} else {
ui.Warn().Msgf("Couldn't locate dnsHostName %v acting as enrollmentservice", cadns)
}
}

Expand Down
Loading

0 comments on commit dd938d5

Please sign in to comment.