◇ OpenCyber Academy
Engineering · Chapter 9 · English

Chapter 9 — Programming II

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 9 — Programming II

Lesson map

Lesson 09 published. Map, example, EX025.

flowchart TD
  N0["Learning outcomes"]
  N1["9.1 Larger programs"]
  N2["9.2 Parsing configurations"]
  N3["9.3 Error handling"]
  N4["9.4 Reproducibility"]
  N5["Working with structured exports"]
  N6["Command-line interfaces"]
  N7["Code review"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX025"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["9.1 Larger programs"]
  N2["9.2 Parsing configurations"]
  N3["9.3 Error handling"]
  N4["9.4 Reproducibility"]
  N5["Working with structured exports"]
  N6["Command-line interfaces"]
  N7["Code review"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX025"]
[Learning outcomes]
    |
    v
[9.1 Larger programs]
    |
    v
[9.2 Parsing configurations]
    |
    v
[9.3 Error handling]
    |
    v
[9.4 Reproducibility]
    |
    v
[Working with structured exports]
    |
    v
[Command-line interfaces]
    |
    v
[Code review]
    |
    v
[Worked example] --> [Exercise EX025]

Learning outcomes

You will (1) structure larger analysis programs; (2) read configuration files safely; (3) handle errors.

9.1 Larger programs

As analysis grows, Kofi splits scripts into modules: parsing, policy evaluation and reporting. Each module has tests.

As scripts grow beyond a page, structure becomes essential. Splitting code into modules by purpose, such as parsing, analysis and reporting, keeps each part small enough to understand. Clear function names, short docstrings, and avoiding global variables make it possible for a colleague to review the code and for Kofi to change one part without breaking another.

A short README explaining how to run the program completes the structure.

9.2 Parsing configurations

Exported firewall configurations are text. Kofi parses them into structured records, rejecting lines he cannot interpret rather than silently skipping them.

Device configurations are text with structure: sections, indentation and keywords. A parser reads that text into data structures such as lists of rules, each with source, destination, service and action fields. Once parsed, rules can be checked automatically for problems such as overly broad sources, duplicates or unused objects. Parsers should be written for synthetic samples first and should report lines they cannot understand rather than silently skipping them.

9.3 Error handling

Programs report clear errors on malformed input, naming the line. Silent failures could hide missing rules.

Real input is messy: files are missing, lines are malformed, values are out of range. A robust script detects these cases, reports them clearly with the line number, and either continues safely or stops. Silent failure is the worst outcome, because a script that ignores a malformed rule may report a clean policy that is actually wrong. Explicit error messages make problems visible to the person running the check.

9.4 Reproducibility

Scripts and synthetic inputs are versioned together, so any result can be regenerated.

A result is reproducible when someone else can run the same script on the same input and get the same output. That requires recording the script version, the input file, and any settings, and avoiding hidden dependencies such as the current date or random values without a fixed seed. Reproducibility turns analysis into evidence that reviewers can trust.

Saving the output alongside these details completes the record.

Working with structured exports

Some council tools export configurations as JSON rather than text. Python's json module loads these into nested dictionaries and lists, which are easier to process reliably than free text. Kofi writes small functions that convert each vendor's export into a common internal format: a list of rules with source, destination, service and action. Converting early means the rest of his analysis code works the same way regardless of where the data came from, and adding support for a new device only requires a new converter.

Command-line interfaces

To make scripts usable by council engineers, Kofi gives them simple command-line options using the argparse module: the input file, an optional output file and a verbose flag. Help text explains each option. This avoids engineers editing code to change file names, which is where mistakes creep in. Each script exits with a non-zero status when it finds a problem, such as a rule that violates policy, so it can be used later in automated checks before a configuration is deployed.

Code review

Before council engineers rely on a script, a second person reads it. Review catches mistakes that tests miss, such as a comparison that treats port 0 as false, and spreads understanding so the council is not dependent on one author. Kofi keeps scripts short enough to review in one sitting and writes comments explaining why, not what. Review comments and their resolutions are kept with the code history, which also shows examiners how quality was checked. Reviewers use a short checklist covering input handling, edge cases and output format.

Worked example

A parser reads "allow staff servers 443" lines into tuples and raises an error on "allow staff" missing fields.

Synthetic case. Data are synthetic.

Errors and limits

Skipping unparseable lines can silently omit rules from analysis.

Exercises

Synthesis

Structured, tested, versioned code makes analysis trustworthy.

Continue studying — chapter 09 of 50

← Chapter 08 (draft) · Course chapter index · Chapter 10 (draft) →