synapse 2.165.0__py311-none-any.whl → 2.167.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +4 -10
- synapse/cmds/cortex.py +1 -6
- synapse/common.py +6 -0
- synapse/cortex.py +104 -57
- synapse/datamodel.py +32 -0
- synapse/exc.py +1 -0
- synapse/lib/agenda.py +81 -51
- synapse/lib/aha.py +2 -0
- synapse/lib/ast.py +21 -23
- synapse/lib/base.py +11 -10
- synapse/lib/cell.py +24 -24
- synapse/lib/hive.py +11 -0
- synapse/lib/httpapi.py +1 -0
- synapse/lib/nexus.py +3 -2
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +3 -1
- synapse/lib/snap.py +50 -0
- synapse/lib/storm.py +19 -17
- synapse/lib/stormlib/aha.py +370 -17
- synapse/lib/stormlib/auth.py +11 -4
- synapse/lib/stormlib/cache.py +202 -0
- synapse/lib/stormlib/cortex.py +69 -7
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/spooled.py +109 -0
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +61 -17
- synapse/lib/trigger.py +10 -12
- synapse/lib/types.py +3 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +16 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/models/inet.py +74 -2
- synapse/models/orgs.py +52 -8
- synapse/models/person.py +30 -11
- synapse/models/risk.py +44 -3
- synapse/telepath.py +115 -32
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +79 -8
- synapse/tests/test_datamodel.py +22 -0
- synapse/tests/test_lib_agenda.py +8 -1
- synapse/tests/test_lib_aha.py +19 -6
- synapse/tests/test_lib_cell.py +6 -2
- synapse/tests/test_lib_grammar.py +62 -64
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_rstorm.py +4 -4
- synapse/tests/test_lib_storm.py +98 -7
- synapse/tests/test_lib_stormlib_aha.py +196 -0
- synapse/tests/test_lib_stormlib_cache.py +272 -0
- synapse/tests/test_lib_stormlib_compression.py +12 -12
- synapse/tests/test_lib_stormlib_cortex.py +71 -0
- synapse/tests/test_lib_stormlib_macro.py +94 -0
- synapse/tests/test_lib_stormlib_spooled.py +190 -0
- synapse/tests/test_lib_stormtypes.py +71 -37
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- synapse/tests/test_model_inet.py +67 -0
- synapse/tests/test_model_risk.py +6 -0
- synapse/tests/test_telepath.py +30 -7
- synapse/tests/test_tools_genpkg.py +26 -0
- synapse/tests/test_tools_hiveload.py +1 -0
- synapse/tests/test_tools_hivesave.py +1 -0
- synapse/tests/test_tools_modrole.py +81 -0
- synapse/tests/test_tools_moduser.py +105 -0
- synapse/tests/utils.py +22 -3
- synapse/tools/autodoc.py +1 -1
- synapse/tools/hive/load.py +3 -0
- synapse/tools/hive/save.py +3 -0
- synapse/tools/modrole.py +59 -7
- synapse/tools/moduser.py +78 -10
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/METADATA +3 -3
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/RECORD +75 -72
- synapse/lib/provenance.py +0 -111
- synapse/tests/test_lib_provenance.py +0 -37
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/LICENSE +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/WHEEL +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormtypes.py
CHANGED
|
@@ -36,7 +36,6 @@ import synapse.lib.trigger as s_trigger
|
|
|
36
36
|
import synapse.lib.urlhelp as s_urlhelp
|
|
37
37
|
import synapse.lib.version as s_version
|
|
38
38
|
import synapse.lib.stormctrl as s_stormctrl
|
|
39
|
-
import synapse.lib.provenance as s_provenance
|
|
40
39
|
|
|
41
40
|
logger = logging.getLogger(__name__)
|
|
42
41
|
|
|
@@ -907,6 +906,18 @@ class LibService(Lib):
|
|
|
907
906
|
'returns': {'type': 'boolean', 'desc': 'Returns true if the service is available, false on a '
|
|
908
907
|
'timeout waiting for the service to be ready.', }}},
|
|
909
908
|
)
|
|
909
|
+
_storm_lib_perms = (
|
|
910
|
+
{'perm': ('service', 'add'), 'gate': 'cortex',
|
|
911
|
+
'desc': 'Controls the ability to add a Storm Service to the Cortex.'},
|
|
912
|
+
{'perm': ('service', 'del'), 'gate': 'cortex',
|
|
913
|
+
'desc': 'Controls the ability to delete a Storm Service from the Cortex'},
|
|
914
|
+
{'perm': ('service', 'get'), 'gate': 'cortex',
|
|
915
|
+
'desc': 'Controls the ability to get the Service object for any Storm Service.'},
|
|
916
|
+
{'perm': ('service', 'get', '<iden>'), 'gate': 'cortex',
|
|
917
|
+
'desc': 'Controls the ability to get the Service object for a Storm Service by iden.'},
|
|
918
|
+
{'perm': ('service', 'list'), 'gate': 'cortex',
|
|
919
|
+
'desc': 'Controls the ability to list all available Storm Services and their service definitions.'},
|
|
920
|
+
)
|
|
910
921
|
_storm_lib_path = ('service',)
|
|
911
922
|
|
|
912
923
|
def getObjLocals(self):
|
|
@@ -931,6 +942,7 @@ class LibService(Lib):
|
|
|
931
942
|
except s_exc.AuthDeny:
|
|
932
943
|
raise e from None
|
|
933
944
|
else:
|
|
945
|
+
# TODO: Remove support for this permission in 3.0.0
|
|
934
946
|
mesg = 'Use of service.get.<servicename> permissions are deprecated.'
|
|
935
947
|
await self.runt.warnonce(mesg, svcname=ssvc.name, svciden=ssvc.iden)
|
|
936
948
|
|
|
@@ -3425,13 +3437,14 @@ class LibFeed(Lib):
|
|
|
3425
3437
|
data = await toprim(data)
|
|
3426
3438
|
|
|
3427
3439
|
self.runt.layerConfirm(('feed:data', *name.split('.')))
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3440
|
+
|
|
3441
|
+
# small work around for the feed API consistency
|
|
3442
|
+
if name == 'syn.nodes':
|
|
3443
|
+
async for node in self.runt.snap.addNodes(data):
|
|
3444
|
+
yield node
|
|
3445
|
+
return
|
|
3446
|
+
|
|
3447
|
+
await self.runt.snap.addFeedData(name, data)
|
|
3435
3448
|
|
|
3436
3449
|
@stormfunc(readonly=True)
|
|
3437
3450
|
async def _libList(self):
|
|
@@ -3443,11 +3456,12 @@ class LibFeed(Lib):
|
|
|
3443
3456
|
data = await toprim(data)
|
|
3444
3457
|
|
|
3445
3458
|
self.runt.layerConfirm(('feed:data', *name.split('.')))
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3459
|
+
|
|
3460
|
+
# TODO this should be a reentrent safe with block
|
|
3461
|
+
strict = self.runt.snap.strict
|
|
3462
|
+
self.runt.snap.strict = False
|
|
3463
|
+
await self.runt.snap.addFeedData(name, data)
|
|
3464
|
+
self.runt.snap.strict = strict
|
|
3451
3465
|
|
|
3452
3466
|
@registry.registerLib
|
|
3453
3467
|
class LibPipe(Lib):
|
|
@@ -3922,7 +3936,13 @@ class LibTelepath(Lib):
|
|
|
3922
3936
|
scheme = url.split('://')[0]
|
|
3923
3937
|
if not self.runt.allowed(('lib', 'telepath', 'open', scheme)):
|
|
3924
3938
|
self.runt.confirm(('storm', 'lib', 'telepath', 'open', scheme))
|
|
3925
|
-
|
|
3939
|
+
try:
|
|
3940
|
+
return Proxy(self.runt, await self.runt.getTeleProxy(url))
|
|
3941
|
+
except s_exc.SynErr:
|
|
3942
|
+
raise
|
|
3943
|
+
except Exception as e:
|
|
3944
|
+
mesg = f'Failed to connect to Telepath service: "{s_urlhelp.sanitizeUrl(url)}" error: {str(e)}'
|
|
3945
|
+
raise s_exc.StormRuntimeError(mesg=mesg) from e
|
|
3926
3946
|
|
|
3927
3947
|
@registry.registerType
|
|
3928
3948
|
class Proxy(StormType):
|
|
@@ -7368,7 +7388,11 @@ class View(Prim):
|
|
|
7368
7388
|
The parent View iden.
|
|
7369
7389
|
|
|
7370
7390
|
nomerge (bool)
|
|
7371
|
-
|
|
7391
|
+
Deprecated - use protected. Updates to this option will be redirected to
|
|
7392
|
+
the protected option (below) until this option is removed.
|
|
7393
|
+
|
|
7394
|
+
protected (bool)
|
|
7395
|
+
Setting to $lib.true will prevent the layer from being merged or deleted.
|
|
7372
7396
|
|
|
7373
7397
|
layers (list(str))
|
|
7374
7398
|
Set the list of layer idens for a non-forked view. Layers are specified
|
|
@@ -7486,7 +7510,7 @@ class View(Prim):
|
|
|
7486
7510
|
|
|
7487
7511
|
{'name': 'getPropArrayCount',
|
|
7488
7512
|
'desc': '''
|
|
7489
|
-
Get the number of
|
|
7513
|
+
Get the number of individual array property values in the View for the given array property name.
|
|
7490
7514
|
|
|
7491
7515
|
Notes:
|
|
7492
7516
|
This is a fast approximate count calculated by summing the number of
|
|
@@ -7580,6 +7604,10 @@ class View(Prim):
|
|
|
7580
7604
|
'args': (),
|
|
7581
7605
|
'returns': {'name': 'Yields', 'type': 'dict',
|
|
7582
7606
|
'desc': 'Yields previously successful merges into the view.'}}},
|
|
7607
|
+
{'name': 'getMergingViews', 'desc': 'Get a list of idens of Views that have open merge requests to this View.',
|
|
7608
|
+
'type': {'type': 'function', '_funcname': 'getMergingViews',
|
|
7609
|
+
'args': (),
|
|
7610
|
+
'returns': {'name': 'idens', 'type': 'list', 'desc': 'The list of View idens that have an open merge request into this View.'}}},
|
|
7583
7611
|
{'name': 'setMergeVoteComment', 'desc': 'Set the comment associated with your vote on a merge request.',
|
|
7584
7612
|
'type': {'type': 'function', '_funcname': 'setMergeVoteComment',
|
|
7585
7613
|
'args': ({'name': 'comment', 'type': 'str', 'desc': 'The text comment to set for the merge vote'},),
|
|
@@ -7634,6 +7662,7 @@ class View(Prim):
|
|
|
7634
7662
|
'delMergeRequest': self.delMergeRequest,
|
|
7635
7663
|
'setMergeRequest': self.setMergeRequest,
|
|
7636
7664
|
'setMergeComment': self.setMergeComment,
|
|
7665
|
+
'getMergingViews': self.getMergingViews,
|
|
7637
7666
|
}
|
|
7638
7667
|
|
|
7639
7668
|
async def addNode(self, form, valu, props=None):
|
|
@@ -7762,6 +7791,8 @@ class View(Prim):
|
|
|
7762
7791
|
|
|
7763
7792
|
@stormfunc(readonly=True)
|
|
7764
7793
|
async def _methViewGet(self, name, defv=None):
|
|
7794
|
+
if name == 'nomerge':
|
|
7795
|
+
name = 'protected'
|
|
7765
7796
|
return self.valu.get(name, defv)
|
|
7766
7797
|
|
|
7767
7798
|
def _reqView(self):
|
|
@@ -7788,6 +7819,10 @@ class View(Prim):
|
|
|
7788
7819
|
valu = await toprim(valu)
|
|
7789
7820
|
|
|
7790
7821
|
elif name == 'nomerge':
|
|
7822
|
+
name = 'protected'
|
|
7823
|
+
valu = await tobool(valu)
|
|
7824
|
+
|
|
7825
|
+
elif name == 'protected':
|
|
7791
7826
|
valu = await tobool(valu)
|
|
7792
7827
|
|
|
7793
7828
|
elif name == 'layers':
|
|
@@ -7951,6 +7986,12 @@ class View(Prim):
|
|
|
7951
7986
|
|
|
7952
7987
|
return await view.setMergeComment((await tostr(comment)))
|
|
7953
7988
|
|
|
7989
|
+
async def getMergingViews(self):
|
|
7990
|
+
view = self._reqView()
|
|
7991
|
+
self.runt.confirm(('view', 'read'), gateiden=view.iden)
|
|
7992
|
+
|
|
7993
|
+
return await view.getMergingViews()
|
|
7994
|
+
|
|
7954
7995
|
async def setMergeVote(self, approved=True, comment=None):
|
|
7955
7996
|
view = self._reqView()
|
|
7956
7997
|
quorum = view.reqParentQuorum()
|
|
@@ -8664,7 +8705,7 @@ class LibCron(Lib):
|
|
|
8664
8705
|
'returns': {'type': 'str', 'desc': 'The iden of the CronJob which was moved.'}}},
|
|
8665
8706
|
{'name': 'list', 'desc': 'List CronJobs in the Cortex.',
|
|
8666
8707
|
'type': {'type': 'function', '_funcname': '_methCronList',
|
|
8667
|
-
'returns': {'type': 'list', 'desc': 'A list of ``cronjob`` objects
|
|
8708
|
+
'returns': {'type': 'list', 'desc': 'A list of ``cronjob`` objects.', }}},
|
|
8668
8709
|
{'name': 'enable', 'desc': 'Enable a CronJob in the Cortex.',
|
|
8669
8710
|
'type': {'type': 'function', '_funcname': '_methCronEnable',
|
|
8670
8711
|
'args': (
|
|
@@ -8855,6 +8896,7 @@ class LibCron(Lib):
|
|
|
8855
8896
|
incunit = None
|
|
8856
8897
|
incval = None
|
|
8857
8898
|
reqdict = {}
|
|
8899
|
+
pool = await tobool(kwargs.get('pool', False))
|
|
8858
8900
|
valinfo = { # unit: (minval, next largest unit)
|
|
8859
8901
|
'month': (1, 'year'),
|
|
8860
8902
|
'dayofmonth': (1, 'month'),
|
|
@@ -8960,6 +9002,7 @@ class LibCron(Lib):
|
|
|
8960
9002
|
|
|
8961
9003
|
cdef = {'storm': query,
|
|
8962
9004
|
'reqs': reqdict,
|
|
9005
|
+
'pool': pool,
|
|
8963
9006
|
'incunit': incunit,
|
|
8964
9007
|
'incvals': incval,
|
|
8965
9008
|
'creator': self.runt.user.iden
|
|
@@ -9208,6 +9251,7 @@ class CronJob(Prim):
|
|
|
9208
9251
|
'view': view,
|
|
9209
9252
|
'viewshort': view[:8] + '..',
|
|
9210
9253
|
'query': self.valu.get('query') or '<missing>',
|
|
9254
|
+
'pool': self.valu.get('pool', False),
|
|
9211
9255
|
'isrecur': 'Y' if self.valu.get('recur') else 'N',
|
|
9212
9256
|
'isrunning': 'Y' if self.valu.get('isrunning') else 'N',
|
|
9213
9257
|
'enabled': 'Y' if self.valu.get('enabled', True) else 'N',
|
synapse/lib/trigger.py
CHANGED
|
@@ -11,7 +11,6 @@ import synapse.lib.chop as s_chop
|
|
|
11
11
|
import synapse.lib.cache as s_cache
|
|
12
12
|
import synapse.lib.config as s_config
|
|
13
13
|
import synapse.lib.grammar as s_grammar
|
|
14
|
-
import synapse.lib.provenance as s_provenance
|
|
15
14
|
|
|
16
15
|
logger = logging.getLogger(__name__)
|
|
17
16
|
|
|
@@ -546,20 +545,19 @@ class Trigger:
|
|
|
546
545
|
|
|
547
546
|
self.startcount += 1
|
|
548
547
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
async with self.view.core.getStormRuntime(query, opts=opts) as runt:
|
|
548
|
+
try:
|
|
549
|
+
async with self.view.core.getStormRuntime(query, opts=opts) as runt:
|
|
552
550
|
|
|
553
|
-
|
|
554
|
-
|
|
551
|
+
runt.addInput(node)
|
|
552
|
+
await s_common.aspin(runt.execute())
|
|
555
553
|
|
|
556
|
-
|
|
557
|
-
|
|
554
|
+
except (asyncio.CancelledError, s_exc.RecursionLimitHit):
|
|
555
|
+
raise
|
|
558
556
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
557
|
+
except Exception as e:
|
|
558
|
+
self.errcount += 1
|
|
559
|
+
self.lasterrs.append(str(e))
|
|
560
|
+
logger.exception('Trigger encountered exception running storm query %s', storm)
|
|
563
561
|
|
|
564
562
|
def pack(self):
|
|
565
563
|
tdef = self.tdef.copy()
|
synapse/lib/types.py
CHANGED
|
@@ -1447,6 +1447,8 @@ class Edge(Type):
|
|
|
1447
1447
|
|
|
1448
1448
|
def postTypeInit(self):
|
|
1449
1449
|
|
|
1450
|
+
self.deprecated = True
|
|
1451
|
+
|
|
1450
1452
|
self.fieldoffs = {'n1': 0, 'n2': 1}
|
|
1451
1453
|
|
|
1452
1454
|
self.ndeftype = self.modl.types.get('ndef') # type: Ndef
|
|
@@ -1850,7 +1852,7 @@ class Tag(Str):
|
|
|
1850
1852
|
mesg = f'Tag does not match tagre: [{s_grammar.tagre.pattern}]'
|
|
1851
1853
|
raise s_exc.BadTypeValu(valu=norm, name=self.name, mesg=mesg)
|
|
1852
1854
|
|
|
1853
|
-
return norm, {'subs': subs}
|
|
1855
|
+
return norm, {'subs': subs, 'toks': toks}
|
|
1854
1856
|
|
|
1855
1857
|
def _normPyStr(self, text):
|
|
1856
1858
|
toks = text.strip('#').split('.')
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 167, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '7b2983533ea27d69e547ac54d9aab953630137c2'
|
synapse/lib/view.py
CHANGED
|
@@ -167,6 +167,18 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
167
167
|
if byts is not None:
|
|
168
168
|
return s_msgpack.un(byts)
|
|
169
169
|
|
|
170
|
+
async def getMergingViews(self):
|
|
171
|
+
if self.info.get('quorum') is None:
|
|
172
|
+
mesg = f'View ({self.iden}) does not require quorum voting.'
|
|
173
|
+
raise s_exc.BadState(mesg=mesg)
|
|
174
|
+
|
|
175
|
+
idens = []
|
|
176
|
+
for view in list(self.core.views.values()):
|
|
177
|
+
await asyncio.sleep(0)
|
|
178
|
+
if view.parent == self and view.getMergeRequest() is not None:
|
|
179
|
+
idens.append(view.iden)
|
|
180
|
+
return idens
|
|
181
|
+
|
|
170
182
|
async def setMergeRequest(self, mergeinfo):
|
|
171
183
|
self.reqParentQuorum()
|
|
172
184
|
mergeinfo['iden'] = s_common.guid()
|
|
@@ -1086,7 +1098,8 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1086
1098
|
'''
|
|
1087
1099
|
Set a mutable view property.
|
|
1088
1100
|
'''
|
|
1089
|
-
if name not in ('name', 'desc', 'parent', 'nomerge', 'quorum'):
|
|
1101
|
+
if name not in ('name', 'desc', 'parent', 'nomerge', 'protected', 'quorum'):
|
|
1102
|
+
# TODO: Remove nomerge after Synapse 3.x.x
|
|
1090
1103
|
mesg = f'{name} is not a valid view info key'
|
|
1091
1104
|
raise s_exc.BadOptValu(mesg=mesg)
|
|
1092
1105
|
|
|
@@ -1334,8 +1347,8 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1334
1347
|
if self.parent is None:
|
|
1335
1348
|
raise s_exc.CantMergeView(mesg=f'Cannot merge view ({self.iden}) that has not been forked.')
|
|
1336
1349
|
|
|
1337
|
-
if self.info.get('
|
|
1338
|
-
raise s_exc.CantMergeView(mesg=f'Cannot merge view ({self.iden}) that has
|
|
1350
|
+
if self.info.get('protected'):
|
|
1351
|
+
raise s_exc.CantMergeView(mesg=f'Cannot merge view ({self.iden}) that has protected set.')
|
|
1339
1352
|
|
|
1340
1353
|
if self.parent.info.get('quorum') is not None:
|
|
1341
1354
|
raise s_exc.CantMergeView(mesg=f'Cannot merge view({self.iden}). Parent view requires quorum voting.')
|
synapse/models/base.py
CHANGED
|
@@ -63,28 +63,36 @@ class BaseModule(s_module.CoreModule):
|
|
|
63
63
|
'doc': 'A generic rule linked to matches with -(matches)> edges.'}),
|
|
64
64
|
|
|
65
65
|
('graph:cluster', ('guid', {}), {
|
|
66
|
+
'deprecated': True,
|
|
66
67
|
'doc': 'A generic node, used in conjunction with Edge types, to cluster arbitrary nodes to a '
|
|
67
68
|
'single node in the model.'}),
|
|
68
69
|
|
|
69
70
|
('graph:node', ('guid', {}), {
|
|
71
|
+
'deprecated': True,
|
|
70
72
|
'doc': 'A generic node used to represent objects outside the model.'}),
|
|
71
73
|
|
|
72
74
|
('graph:event', ('guid', {}), {
|
|
75
|
+
'deprecated': True,
|
|
73
76
|
'doc': 'A generic event node to represent events outside the model.'}),
|
|
74
77
|
|
|
75
78
|
('edge:refs', ('edge', {}), {
|
|
79
|
+
'deprecated': True,
|
|
76
80
|
'doc': 'A digraph edge which records that N1 refers to or contains N2.'}),
|
|
77
81
|
|
|
78
82
|
('edge:has', ('edge', {}), {
|
|
83
|
+
'deprecated': True,
|
|
79
84
|
'doc': 'A digraph edge which records that N1 has N2.'}),
|
|
80
85
|
|
|
81
86
|
('edge:wentto', ('timeedge', {}), {
|
|
87
|
+
'deprecated': True,
|
|
82
88
|
'doc': 'A digraph edge which records that N1 went to N2 at a specific time.'}),
|
|
83
89
|
|
|
84
90
|
('graph:edge', ('edge', {}), {
|
|
91
|
+
'deprecated': True,
|
|
85
92
|
'doc': 'A generic digraph edge to show relationships outside the model.'}),
|
|
86
93
|
|
|
87
94
|
('graph:timeedge', ('timeedge', {}), {
|
|
95
|
+
'deprecated': True,
|
|
88
96
|
'doc': 'A generic digraph time edge to show relationships outside the model.'}),
|
|
89
97
|
|
|
90
98
|
('meta:priority', ('int', {'enums': prioenums, 'enums:strict': False}), {
|
synapse/models/files.py
CHANGED
synapse/models/inet.py
CHANGED
|
@@ -1304,8 +1304,8 @@ class InetModule(s_module.CoreModule):
|
|
|
1304
1304
|
}),
|
|
1305
1305
|
|
|
1306
1306
|
('inet:ssl:cert', ('comp', {'fields': (('server', 'inet:server'), ('file', 'file:bytes'))}), {
|
|
1307
|
-
'
|
|
1308
|
-
'
|
|
1307
|
+
'deprecated': True,
|
|
1308
|
+
'doc': 'Deprecated. Please use inet:tls:servercert or inet:tls:clientcert',
|
|
1309
1309
|
}),
|
|
1310
1310
|
|
|
1311
1311
|
('inet:port', ('int', {'min': 0, 'max': 0xffff}), {
|
|
@@ -1489,6 +1489,24 @@ class InetModule(s_module.CoreModule):
|
|
|
1489
1489
|
('inet:ssl:jarmsample', ('comp', {'fields': (('server', 'inet:server'), ('jarmhash', 'inet:ssl:jarmhash'))}), {
|
|
1490
1490
|
'doc': 'A JARM hash sample taken from a server.'}),
|
|
1491
1491
|
|
|
1492
|
+
('inet:tls:handshake', ('guid', {}), {
|
|
1493
|
+
'doc': 'An instance of a TLS handshake between a server and client.'}),
|
|
1494
|
+
|
|
1495
|
+
('inet:tls:ja3s:sample', ('comp', {'fields': (('server', 'inet:server'), ('ja3s', 'hash:md5'))}), {
|
|
1496
|
+
'doc': 'A JA3 sample taken from a server.'}),
|
|
1497
|
+
|
|
1498
|
+
('inet:tls:ja3:sample', ('comp', {'fields': (('client', 'inet:client'), ('ja3', 'hash:md5'))}), {
|
|
1499
|
+
'doc': 'A JA3 sample taken from a client.'}),
|
|
1500
|
+
|
|
1501
|
+
('inet:tls:servercert', ('comp', {'fields': (('server', 'inet:server'), ('cert', 'crypto:x509:cert'))}), {
|
|
1502
|
+
'doc': 'An x509 certificate sent by a server for TLS.',
|
|
1503
|
+
'ex': '(1.2.3.4:443, c7437790af01ae1bb2f8f3b684c70bf8)',
|
|
1504
|
+
}),
|
|
1505
|
+
|
|
1506
|
+
('inet:tls:clientcert', ('comp', {'fields': (('client', 'inet:client'), ('cert', 'crypto:x509:cert'))}), {
|
|
1507
|
+
'doc': 'An x509 certificate sent by a client for TLS.',
|
|
1508
|
+
'ex': '(1.2.3.4:443, 3fdf364e081c14997b291852d1f23868)',
|
|
1509
|
+
}),
|
|
1492
1510
|
),
|
|
1493
1511
|
|
|
1494
1512
|
'interfaces': (
|
|
@@ -3234,6 +3252,60 @@ class InetModule(s_module.CoreModule):
|
|
|
3234
3252
|
'doc': 'The server that was sampled to compute the JARM hash.'}),
|
|
3235
3253
|
)),
|
|
3236
3254
|
|
|
3255
|
+
('inet:tls:handshake', {}, (
|
|
3256
|
+
('time', ('time', {}), {
|
|
3257
|
+
'doc': 'The time the handshake was initiated.'}),
|
|
3258
|
+
('flow', ('inet:flow', {}), {
|
|
3259
|
+
'doc': 'The raw inet:flow associated with the handshake.'}),
|
|
3260
|
+
('server', ('inet:server', {}), {
|
|
3261
|
+
'doc': 'The TLS server during the handshake.'}),
|
|
3262
|
+
('server:cert', ('crypto:x509:cert', {}), {
|
|
3263
|
+
'doc': 'The x509 certificate sent by the server during the handshake.'}),
|
|
3264
|
+
('server:fingerprint:ja3', ('hash:md5', {}), {
|
|
3265
|
+
'doc': 'The JA3S finger of the server.'}),
|
|
3266
|
+
('client', ('inet:client', {}), {
|
|
3267
|
+
'doc': 'The TLS client during the handshake.'}),
|
|
3268
|
+
('client:cert', ('crypto:x509:cert', {}), {
|
|
3269
|
+
'doc': 'The x509 certificate sent by the client during the handshake.'}),
|
|
3270
|
+
('client:fingerprint:ja3', ('hash:md5', {}), {
|
|
3271
|
+
'doc': 'The JA3 fingerprint of the client.'}),
|
|
3272
|
+
)),
|
|
3273
|
+
|
|
3274
|
+
('inet:tls:ja3s:sample', {}, (
|
|
3275
|
+
('server', ('inet:server', {}), {
|
|
3276
|
+
'ro': True,
|
|
3277
|
+
'doc': 'The server that was sampled to produce the JA3S hash.'}),
|
|
3278
|
+
('ja3s', ('hash:md5', {}), {
|
|
3279
|
+
'ro': True,
|
|
3280
|
+
'doc': "The JA3S hash computed from the server's TLS hello packet."})
|
|
3281
|
+
)),
|
|
3282
|
+
|
|
3283
|
+
('inet:tls:ja3:sample', {}, (
|
|
3284
|
+
('client', ('inet:client', {}), {
|
|
3285
|
+
'ro': True,
|
|
3286
|
+
'doc': 'The client that was sampled to produce the JA3 hash.'}),
|
|
3287
|
+
('ja3', ('hash:md5', {}), {
|
|
3288
|
+
'ro': True,
|
|
3289
|
+
'doc': "The JA3 hash computed from the client's TLS hello packet."})
|
|
3290
|
+
)),
|
|
3291
|
+
|
|
3292
|
+
('inet:tls:servercert', {}, (
|
|
3293
|
+
('server', ('inet:server', {}), {
|
|
3294
|
+
'ro': True,
|
|
3295
|
+
'doc': 'The server associated with the x509 certificate.'}),
|
|
3296
|
+
('cert', ('crypto:x509:cert', {}), {
|
|
3297
|
+
'ro': True,
|
|
3298
|
+
'doc': 'The x509 certificate sent by the server.'})
|
|
3299
|
+
)),
|
|
3300
|
+
|
|
3301
|
+
('inet:tls:clientcert', {}, (
|
|
3302
|
+
('client', ('inet:client', {}), {
|
|
3303
|
+
'ro': True,
|
|
3304
|
+
'doc': 'The client associated with the x509 certificate.'}),
|
|
3305
|
+
('cert', ('crypto:x509:cert', {}), {
|
|
3306
|
+
'ro': True,
|
|
3307
|
+
'doc': 'The x509 certificate sent by the client.'})
|
|
3308
|
+
)),
|
|
3237
3309
|
),
|
|
3238
3310
|
}),
|
|
3239
3311
|
)
|
synapse/models/orgs.py
CHANGED
|
@@ -24,14 +24,27 @@ class OuModule(s_module.CoreModule):
|
|
|
24
24
|
}),
|
|
25
25
|
('ou:isic', ('str', {'regex': r'^[A-Z]([0-9]{2}[0-9]{0,2})?$'}), {
|
|
26
26
|
'doc': 'An International Standard Industrial Classification of All Economic Activities (ISIC) code.',
|
|
27
|
-
'ex': 'C1393',
|
|
28
|
-
|
|
27
|
+
'ex': 'C1393'}),
|
|
28
|
+
|
|
29
29
|
('ou:org', ('guid', {}), {
|
|
30
30
|
'doc': 'A GUID for a human organization such as a company or military unit.',
|
|
31
|
-
|
|
31
|
+
'display': {
|
|
32
|
+
'columns': (
|
|
33
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
34
|
+
{'type': 'prop', 'opts': {'name': 'names'}},
|
|
35
|
+
{'type': 'prop', 'opts': {'name': 'country:code'}},
|
|
36
|
+
),
|
|
37
|
+
}}),
|
|
38
|
+
|
|
32
39
|
('ou:team', ('guid', {}), {
|
|
33
40
|
'doc': 'A GUID for a team within an organization.',
|
|
34
|
-
|
|
41
|
+
'display': {
|
|
42
|
+
'columns': (
|
|
43
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
44
|
+
{'type': 'prop', 'opts': {'name': 'org::name'}},
|
|
45
|
+
),
|
|
46
|
+
}}),
|
|
47
|
+
|
|
35
48
|
('ou:orgtype', ('taxonomy', {}), {
|
|
36
49
|
'doc': 'An org type taxonomy.',
|
|
37
50
|
'interfaces': ('meta:taxonomy',),
|
|
@@ -49,6 +62,11 @@ class OuModule(s_module.CoreModule):
|
|
|
49
62
|
}),
|
|
50
63
|
('ou:industry', ('guid', {}), {
|
|
51
64
|
'doc': 'An industry classification type.',
|
|
65
|
+
'display': {
|
|
66
|
+
'columns': (
|
|
67
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
68
|
+
),
|
|
69
|
+
},
|
|
52
70
|
}),
|
|
53
71
|
('ou:industry:type:taxonomy', ('taxonomy', {}), {
|
|
54
72
|
'interfaces': ('meta:taxonomy',),
|
|
@@ -113,6 +131,12 @@ class OuModule(s_module.CoreModule):
|
|
|
113
131
|
}),
|
|
114
132
|
('ou:conference', ('guid', {}), {
|
|
115
133
|
'doc': 'A conference with a name and sponsoring org.',
|
|
134
|
+
'display': {
|
|
135
|
+
'columns': (
|
|
136
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
137
|
+
{'type': 'prop', 'opts': {'name': 'start'}},
|
|
138
|
+
),
|
|
139
|
+
},
|
|
116
140
|
}),
|
|
117
141
|
('ou:conference:attendee', ('comp', {'fields': (('conference', 'ou:conference'), ('person', 'ps:person'))}), {
|
|
118
142
|
'deprecated': True,
|
|
@@ -133,6 +157,11 @@ class OuModule(s_module.CoreModule):
|
|
|
133
157
|
}),
|
|
134
158
|
('ou:goal', ('guid', {}), {
|
|
135
159
|
'doc': 'An assessed or stated goal which may be abstract or org specific.',
|
|
160
|
+
'display': {
|
|
161
|
+
'columns': (
|
|
162
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
163
|
+
),
|
|
164
|
+
},
|
|
136
165
|
}),
|
|
137
166
|
('ou:goalname', ('str', {'lower': True, 'onespace': True}), {
|
|
138
167
|
'doc': 'A goal name.',
|
|
@@ -154,16 +183,31 @@ class OuModule(s_module.CoreModule):
|
|
|
154
183
|
|
|
155
184
|
('ou:campaign', ('guid', {}), {
|
|
156
185
|
'doc': "Represents an org's activity in pursuit of a goal.",
|
|
157
|
-
|
|
186
|
+
'display': {
|
|
187
|
+
'columns': (
|
|
188
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
189
|
+
{'type': 'prop', 'opts': {'name': 'names'}},
|
|
190
|
+
{'type': 'prop', 'opts': {'name': 'reporter:name'}},
|
|
191
|
+
{'type': 'prop', 'opts': {'name': 'tag'}},
|
|
192
|
+
),
|
|
193
|
+
}}),
|
|
194
|
+
|
|
158
195
|
('ou:conflict', ('guid', {}), {
|
|
159
196
|
'doc': 'Represents a conflict where two or more campaigns have mutually exclusive goals.',
|
|
160
197
|
}),
|
|
161
198
|
('ou:contribution', ('guid', {}), {
|
|
162
|
-
'doc': 'Represents a specific instance of contributing material support to a campaign.',
|
|
163
|
-
|
|
199
|
+
'doc': 'Represents a specific instance of contributing material support to a campaign.'}),
|
|
200
|
+
|
|
164
201
|
('ou:technique', ('guid', {}), {
|
|
165
202
|
'doc': 'A specific technique used to achieve a goal.',
|
|
166
|
-
|
|
203
|
+
'display': {
|
|
204
|
+
'columns': (
|
|
205
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
206
|
+
{'type': 'prop', 'opts': {'name': 'reporter:name'}},
|
|
207
|
+
{'type': 'prop', 'opts': {'name': 'tag'}},
|
|
208
|
+
),
|
|
209
|
+
}}),
|
|
210
|
+
|
|
167
211
|
('ou:technique:taxonomy', ('taxonomy', {}), {
|
|
168
212
|
'interfaces': ('meta:taxonomy',),
|
|
169
213
|
'doc': 'An analyst defined taxonomy to classify techniques in different disciplines.',
|
synapse/models/person.py
CHANGED
|
@@ -39,11 +39,19 @@ class PsModule(s_module.CoreModule):
|
|
|
39
39
|
('ps:persona:has', ('comp', {'fields': (('persona', 'ps:persona'), ('node', 'ndef'))}), {
|
|
40
40
|
'deprecated': True,
|
|
41
41
|
'doc': 'A persona owns, controls, or has exclusive use of an object or'
|
|
42
|
-
' resource, potentially during a specific period of time.'
|
|
43
|
-
|
|
42
|
+
' resource, potentially during a specific period of time.'}),
|
|
43
|
+
|
|
44
44
|
('ps:contact', ('guid', {}), {
|
|
45
45
|
'doc': 'A GUID for a contact info record.',
|
|
46
|
-
|
|
46
|
+
'display': {
|
|
47
|
+
'columns': (
|
|
48
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
49
|
+
{'type': 'prop', 'opts': {'name': 'type'}},
|
|
50
|
+
{'type': 'prop', 'opts': {'name': 'orgname'}},
|
|
51
|
+
{'type': 'prop', 'opts': {'name': 'email'}},
|
|
52
|
+
),
|
|
53
|
+
}}),
|
|
54
|
+
|
|
47
55
|
('ps:contact:type:taxonomy', ('taxonomy', {}), {
|
|
48
56
|
'interfaces': ('meta:taxonomy',),
|
|
49
57
|
'doc': 'A taxonomy of contact types.',
|
|
@@ -55,18 +63,29 @@ class PsModule(s_module.CoreModule):
|
|
|
55
63
|
'doc': "A GUID representing entry in a contact's work history.",
|
|
56
64
|
}),
|
|
57
65
|
('ps:vitals', ('guid', {}), {
|
|
58
|
-
'doc': 'Statistics and demographic data about a person or contact.',
|
|
59
|
-
|
|
66
|
+
'doc': 'Statistics and demographic data about a person or contact.'}),
|
|
67
|
+
|
|
60
68
|
('ps:skill', ('guid', {}), {
|
|
61
|
-
'doc': 'A specific skill which a person or organization may have.'
|
|
62
|
-
|
|
69
|
+
'doc': 'A specific skill which a person or organization may have.',
|
|
70
|
+
'display': {
|
|
71
|
+
'columns': (
|
|
72
|
+
{'type': 'prop', 'opts': {'name': 'name'}},
|
|
73
|
+
{'type': 'prop', 'opts': {'name': 'type'}},
|
|
74
|
+
),
|
|
75
|
+
}}),
|
|
76
|
+
|
|
63
77
|
('ps:skill:type:taxonomy', ('taxonomy', {}), {
|
|
64
78
|
'interfaces': ('meta:taxonomy',),
|
|
65
|
-
'doc': 'A taxonomy of skill types.',
|
|
66
|
-
|
|
79
|
+
'doc': 'A taxonomy of skill types.'}),
|
|
80
|
+
|
|
67
81
|
('ps:proficiency', ('guid', {}), {
|
|
68
|
-
'doc': 'The assessment that a given contact possesses a specific skill.'
|
|
69
|
-
|
|
82
|
+
'doc': 'The assessment that a given contact possesses a specific skill.',
|
|
83
|
+
'display': {
|
|
84
|
+
'columns': (
|
|
85
|
+
{'type': 'prop', 'opts': {'name': 'contact::name'}},
|
|
86
|
+
{'type': 'prop', 'opts': {'name': 'skill::name'}},
|
|
87
|
+
),
|
|
88
|
+
}}),
|
|
70
89
|
),
|
|
71
90
|
'edges': (
|
|
72
91
|
(('ps:contact', 'has', None), {
|