From 2ddc62bac6933cfa32f3f344719df8b4c54b7631 Mon Sep 17 00:00:00 2001
From: Dante Catalfamo
Date: Fri, 2 Jul 2021 16:33:06 -0400
Subject: bsd-auth: Work on script to generate .dot graph

---
 .../WIP-how-bsd-authentication-works/gen_dot.rb    | 82 ++++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 content/posts/WIP-how-bsd-authentication-works/gen_dot.rb

(limited to 'content/posts/WIP-how-bsd-authentication-works')

diff --git a/content/posts/WIP-how-bsd-authentication-works/gen_dot.rb b/content/posts/WIP-how-bsd-authentication-works/gen_dot.rb
new file mode 100644
index 0000000..9925d8c
--- /dev/null
+++ b/content/posts/WIP-how-bsd-authentication-works/gen_dot.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+SOURCE_DIR = File.join Dir.home, 'src', 'github.com', 'openbsd', 'src', 'lib', 'libc', 'gen'
+FILENAMES = %w[authenticate.c auth_subr.c login_cap.c].freeze
+
+FUNCTION_REGEX = /^\w.*?$\n(\w*)\(.*?\)\n\{(.*?)^\}/m.freeze
+ONELINE_FUNCTION_REFGEX = /^\w.*?(\w*)\(.*?\).*?\{(.*?)\}/.freeze
+CALL_REGEX = /[^\n](\w+)\(.*?\)/.freeze
+
+class FunctionDigraph
+  attr_accessor :pairs, :subgraphs
+
+  class Subgraph
+    attr_accessor :name, :label, :functions
+
+    def initialize(name, label)
+      @name = name
+      @label = label
+      @functions = []
+    end
+
+    def emit
+      puts "subgraph cluster_#{name} {"
+      puts "label = \"#{label}\""
+      functions.each { |f| puts f unless f == 'DEF_WEAK' }
+      puts '}'
+    end
+  end
+
+  class Pair
+    attr_accessor :to, :from
+
+    def initialize(from, to)
+      @from = from
+      @to = to
+    end
+
+    def emit
+      puts "#{from} -> #{to}" if to =~ /auth|login|^_/
+    end
+  end
+
+  def initialize
+    @pairs = []
+    @subgraphs = []
+  end
+
+  def emit
+    puts 'digraph G {'
+    @subgraphs.each(&:emit)
+    @pairs.uniq { |p| [p.to, p.from] }.each(&:emit)
+    puts '}'
+  end
+
+  def parse_files(filenames)
+    filenames.each do |filename|
+      contents = File.read(filename)
+      basename = File.basename filename
+      subgraph = Subgraph.new(basename.gsub(/\..*/, ''), basename)
+      functions = contents.scan(FUNCTION_REGEX)
+      oneliners = contents.scan(ONELINE_FUNCTION_REFGEX)
+      functions.concat(oneliners) unless oneliners.empty?
+      functions.each do |function|
+        function_name = function[0]
+        function_body = function[1]
+        puts 'auth_open!' if function_name == 'auth_open'
+        subgraph.functions << function_name
+        function_body.scan(CALL_REGEX) do |call|
+          @pairs << Pair.new(function_name, call[0])
+        end
+      end
+      @subgraphs << subgraph
+    end
+  end
+end
+
+fg = FunctionDigraph.new
+
+files = FILENAMES.map { |f| File.join(SOURCE_DIR, f) }
+fg.parse_files files
+
+fg.emit
-- 
cgit v1.2.3