@portll/cobolwork 0.0.1 → 0.2.76

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.
Files changed (79) hide show
  1. package/LICENSE +661 -0
  2. package/LICENSING.md +93 -0
  3. package/NOTICE +9 -0
  4. package/README.md +325 -3
  5. package/THIRD-PARTY-NOTICES.md +118 -0
  6. package/bin/cobolwork.mjs +354 -0
  7. package/lib/advisories.mjs +133 -0
  8. package/lib/baseline.mjs +154 -0
  9. package/lib/bms.mjs +453 -0
  10. package/lib/build.mjs +402 -0
  11. package/lib/capabilities.mjs +79 -0
  12. package/lib/cics-commands.mjs +281 -0
  13. package/lib/compliance.mjs +81 -0
  14. package/lib/consequence.mjs +139 -0
  15. package/lib/control.mjs +1515 -0
  16. package/lib/csd.mjs +77 -0
  17. package/lib/dataflow.mjs +1506 -0
  18. package/lib/diff.mjs +344 -0
  19. package/lib/explain.mjs +145 -0
  20. package/lib/gate.mjs +383 -0
  21. package/lib/index.mjs +6 -0
  22. package/lib/inventory.mjs +79 -0
  23. package/lib/jcl.mjs +478 -0
  24. package/lib/kernel/findings.mjs +94 -0
  25. package/lib/kernel/identity.mjs +216 -0
  26. package/lib/kernel/memory.mjs +217 -0
  27. package/lib/kernel/printable.mjs +6 -0
  28. package/lib/kernel/registry.mjs +79 -0
  29. package/lib/kernel/ruleset.mjs +72 -0
  30. package/lib/kernel/source-tree.mjs +159 -0
  31. package/lib/kev.mjs +27 -0
  32. package/lib/options.mjs +512 -0
  33. package/lib/packs.mjs +148 -0
  34. package/lib/parser.mjs +2055 -0
  35. package/lib/policy.mjs +163 -0
  36. package/lib/precompile-cics.mjs +169 -0
  37. package/lib/precompile.mjs +544 -0
  38. package/lib/reach.mjs +122 -0
  39. package/lib/revision.json +1 -0
  40. package/lib/revision.mjs +89 -0
  41. package/lib/sarif.mjs +222 -0
  42. package/lib/scan.mjs +272 -0
  43. package/lib/sets/build.mjs +234 -0
  44. package/lib/sets/cics.mjs +306 -0
  45. package/lib/sets/compile.mjs +187 -0
  46. package/lib/sets/copybook.mjs +174 -0
  47. package/lib/sets/flow.mjs +487 -0
  48. package/lib/sets/hidden.mjs +216 -0
  49. package/lib/sets/jcl.mjs +440 -0
  50. package/lib/sets/log.mjs +406 -0
  51. package/lib/sets/opaque.mjs +102 -0
  52. package/lib/sets/priv.mjs +322 -0
  53. package/lib/sets/recon.mjs +267 -0
  54. package/lib/sets/vendor.mjs +117 -0
  55. package/lib/sets/web.mjs +327 -0
  56. package/lib/site.mjs +164 -0
  57. package/lib/sources.mjs +156 -0
  58. package/lib/tui/app.mjs +325 -0
  59. package/lib/tui/keys.mjs +39 -0
  60. package/lib/tui/model.mjs +96 -0
  61. package/lib/tui/run.mjs +38 -0
  62. package/lib/tui/screen.mjs +59 -0
  63. package/lib/tui/terminal.mjs +46 -0
  64. package/lib/utilities.mjs +296 -0
  65. package/lib/version.mjs +15 -0
  66. package/lib/words.mjs +318 -0
  67. package/package.json +45 -6
  68. package/rules/advisories.json +264 -0
  69. package/rules/compliance-dora.json +2151 -0
  70. package/rules/compliance-ffiec.json +2134 -0
  71. package/rules/compliance-nist80053.json +2134 -0
  72. package/rules/gitleaks-mainframe.toml +57 -0
  73. package/rules/kev-ids.json +1729 -0
  74. package/rules/packs/broadcom.json +124 -0
  75. package/rules/packs/connectdirect.json +116 -0
  76. package/rules/packs/controlm.json +114 -0
  77. package/rules/system-layouts.json +28 -0
  78. package/schema/cobolwork-coverage.schema.json +65 -0
  79. package/schema/cobolwork.policy.schema.json +54 -0
package/lib/csd.mjs ADDED
@@ -0,0 +1,77 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // The CICS system definition, as DFHCSDUP reads it: DEFINE commands, each naming a resource and
3
+ // giving its attributes as KEYWORD(value), running on until the next command.
4
+ //
5
+ // DEFINE TDQUEUE(JOBS) GROUP(CARDDEMO)
6
+ // TYPE(EXTRA) DDNAME(INREADER) ...
7
+ //
8
+ // It is how a transient-data queue a program writes to becomes a DD the region opens, which is the
9
+ // link between EXEC CICS WRITEQ TD and the internal reader. This reads text and opens nothing; the
10
+ // caller reads the file through the source tree, so containment stays where it is enforced.
11
+
12
+ const COMMAND = /^\s*(DEFINE|ADD|ALTER|APPEND|COPY|DELETE|INITIALIZE|LIST|REMOVE|SCAN|SERVICE|UPGRADE|USERDEFINE|VERIFY)\b/i;
13
+
14
+ // { tdqueues: Map(name -> { type, ddname, indirect, line }),
15
+ // transactions: Map(name -> { program, cmdsec, ressec, line }),
16
+ // tcpipservices: Map(name -> { port, protocol, ssl, transaction, line }) }
17
+ export function parseCsd(text) {
18
+ const tdqueues = new Map();
19
+ const transactions = new Map();
20
+ const tcpipservices = new Map();
21
+ const blocks = [];
22
+ let cur = null;
23
+ const lines = String(text).split(/\r?\n/);
24
+ for (let i = 0; i < lines.length; i++) {
25
+ const line = lines[i];
26
+ if (/^\s*\*/.test(line)) continue;
27
+ if (COMMAND.test(line)) {
28
+ cur = { line: i + 1, text: line };
29
+ blocks.push(cur);
30
+ } else if (cur) cur.text += ` ${line}`;
31
+ }
32
+ for (const b of blocks) {
33
+ const head = /^\s*DEFINE\s+([A-Z]+)\s*\(\s*([^)\s]+)\s*\)/i.exec(b.text);
34
+ if (!head) continue;
35
+ const kind = head[1].toUpperCase();
36
+ const name = head[2].toUpperCase();
37
+ const attrs = new Map();
38
+ // The value is bounded. Unbounded, an unbalanced `(` makes the engine scan to the end of the
39
+ // block and backtrack once per following attribute, which is quadratic: 5.6s at 100KB and 130s
40
+ // at 400KB of `a(`. This is the one parser here that runs over arbitrary unfiltered bytes - any
41
+ // file holding a single DEFINE line is handed to it whole - so that cost is reachable by a file
42
+ // nobody chose to scan. No CSD attribute value comes near 256 bytes.
43
+ for (const m of b.text.slice(head[0].length).matchAll(/\b([A-Z0-9]+)\s*\(([^)]{0,256})\)/gi)) attrs.set(m[1].toUpperCase(), m[2].trim().toUpperCase());
44
+ if (kind === 'TCPIPSERVICE') {
45
+ // SSL is kept as written, including absent: CICS defaults it to NO, so a definition that says
46
+ // nothing accepts cleartext exactly as one that says NO does. GenApp's listener says nothing.
47
+ tcpipservices.set(name, {
48
+ port: attrs.get('PORTNUMBER') || null,
49
+ protocol: attrs.get('PROTOCOL') || null,
50
+ ssl: attrs.get('SSL') || null,
51
+ transaction: attrs.get('TRANSACTION') || null,
52
+ line: b.line,
53
+ });
54
+ } else if (kind === 'TDQUEUE') {
55
+ tdqueues.set(name, { type: attrs.get('TYPE') || null, ddname: attrs.get('DDNAME') || null, indirect: attrs.get('INDIRECTNAME') || null, transid: attrs.get('TRANSID') || null, line: b.line });
56
+ } else if (kind === 'TRANSACTION') {
57
+ // The security attributes are kept because their absence means the same as NO: a caller that
58
+ // re-read the file to find them would search on past the end of this definition into the
59
+ // next one, which is how a CMDSEC(YES) on one transaction came to clear another.
60
+ transactions.set(name, {
61
+ program: attrs.get('PROGRAM') || null,
62
+ cmdsec: attrs.get('CMDSEC') || null,
63
+ ressec: attrs.get('RESSEC') || null,
64
+ line: b.line,
65
+ });
66
+ }
67
+ }
68
+ return { tdqueues, transactions, tcpipservices };
69
+ }
70
+
71
+ // The DD a queue is written to, following one INDIRECT hop. Null when the definition does not say:
72
+ // an intrapartition queue has no DD, and neither does a queue nobody defined.
73
+ export function ddOfQueue(csd, queue) {
74
+ let q = csd.tdqueues.get(queue);
75
+ if (q && q.type === 'INDIRECT' && q.indirect) q = csd.tdqueues.get(q.indirect);
76
+ return q && q.type === 'EXTRA' ? q.ddname : null;
77
+ }