From 894afa96cd14a84cd1a1bcfb9523f10210aebb7c Mon Sep 17 00:00:00 2001
From: Dante Catalfamo
Date: Mon, 18 Oct 2021 17:36:47 -0400
Subject: bsd-auth: no longer WIP
---
.../WIP-how-bsd-authentication-works/gen_dot.rb | 99 -
.../WIP-how-bsd-authentication-works/graph.dot | 152 --
.../WIP-how-bsd-authentication-works/graph.svg | 856 ------
.../WIP-how-bsd-authentication-works/index.org | 2811 --------------------
.../WIP-how-bsd-authentication-works/notes.org | 83 -
.../openbsd_internals.gif | Bin 690203 -> 0 bytes
6 files changed, 4001 deletions(-)
delete mode 100755 content/posts/WIP-how-bsd-authentication-works/gen_dot.rb
delete mode 100644 content/posts/WIP-how-bsd-authentication-works/graph.dot
delete mode 100644 content/posts/WIP-how-bsd-authentication-works/graph.svg
delete mode 100644 content/posts/WIP-how-bsd-authentication-works/index.org
delete mode 100644 content/posts/WIP-how-bsd-authentication-works/notes.org
delete mode 100644 content/posts/WIP-how-bsd-authentication-works/openbsd_internals.gif
(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
deleted file mode 100755
index 9f71876..0000000
--- a/content/posts/WIP-how-bsd-authentication-works/gen_dot.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-# Copyright (C) 2021 Dante Catalfamo
-# SPDX-License-Identifier: MIT
-
-require 'digest'
-require 'set'
-
-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(?!DEF)(\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} [color = \"##{color}\"]"
- end
-
- def color
- Digest::MD5.hexdigest(from)[..5]
- end
- end
-
- def initialize
- @pairs = []
- @subgraphs = []
- end
-
- def emit
- puts 'digraph G {'
- puts 'rankdir=LR'
- puts 'splines=ortho'
- puts 'graph [pad="0.5", nodesep="0.5", ranksep="1.5"]'
- all_functions = Set.new
- @subgraphs.each { |s| all_functions.merge(s.functions) }
- @subgraphs.each(&:emit)
- @pairs.uniq { |p| [p.to, p.from] }.each do |p|
- p.emit if all_functions.include?(p.to)
- end
- 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]
- 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
diff --git a/content/posts/WIP-how-bsd-authentication-works/graph.dot b/content/posts/WIP-how-bsd-authentication-works/graph.dot
deleted file mode 100644
index 9a2be3c..0000000
--- a/content/posts/WIP-how-bsd-authentication-works/graph.dot
+++ /dev/null
@@ -1,152 +0,0 @@
-digraph G {
-rankdir=LR
-splines=ortho
-graph [pad="0.5", nodesep="0.5", ranksep="1.5"]
-subgraph cluster_authenticate {
-label = "authenticate.c"
-auth_mkvalue
-auth_checknologin
-_auth_checknologin
-auth_cat
-_auth_validuser
-auth_approval
-auth_usercheck
-auth_userokay
-auth_userchallenge
-auth_userresponse
-auth_verify
-}
-subgraph cluster_auth_subr {
-label = "auth_subr.c"
-auth_open
-auth_clean
-auth_close
-auth_challenge
-auth_setenv
-auth_clrenv
-auth_getitem
-auth_setitem
-auth_setoption
-auth_clroptions
-auth_clroption
-auth_setdata
-auth_setpwd
-auth_getvalue
-auth_check_expire
-auth_check_change
-auth_call
-_recv_fd
-_auth_spool
-_add_rmlist
-_auth_next_arg
-auth_setstate
-auth_set_va_list
-auth_getstate
-auth_getpwd
-}
-subgraph cluster_login_cap {
-label = "login_cap.c"
-login_getclass
-login_getstyle
-login_getcapstr
-login_getcaptime
-login_getcapnum
-login_getcapsize
-login_getcapbool
-login_close
-gsetrl
-setclasscontext
-setusercontext
-setuserpath
-setuserenv
-login_setenv
-strtosize
-strtolimit
-multiply
-secure_path
-expandstr
-}
-auth_checknologin -> _auth_checknologin [color = "#f0bfd8"]
-_auth_checknologin -> login_getcapbool [color = "#f51748"]
-_auth_checknologin -> login_getcapstr [color = "#f51748"]
-_auth_checknologin -> auth_cat [color = "#f51748"]
-auth_approval -> auth_getitem [color = "#8f94eb"]
-auth_approval -> auth_getpwd [color = "#8f94eb"]
-auth_approval -> _auth_validuser [color = "#8f94eb"]
-auth_approval -> login_getclass [color = "#8f94eb"]
-auth_approval -> login_close [color = "#8f94eb"]
-auth_approval -> login_getcapstr [color = "#8f94eb"]
-auth_approval -> auth_open [color = "#8f94eb"]
-auth_approval -> auth_setstate [color = "#8f94eb"]
-auth_approval -> auth_setitem [color = "#8f94eb"]
-auth_approval -> auth_check_expire [color = "#8f94eb"]
-auth_approval -> login_getcapbool [color = "#8f94eb"]
-auth_approval -> auth_call [color = "#8f94eb"]
-auth_approval -> auth_close [color = "#8f94eb"]
-auth_approval -> auth_getstate [color = "#8f94eb"]
-auth_usercheck -> _auth_validuser [color = "#96fc6d"]
-auth_usercheck -> login_getclass [color = "#96fc6d"]
-auth_usercheck -> login_getstyle [color = "#96fc6d"]
-auth_usercheck -> login_close [color = "#96fc6d"]
-auth_usercheck -> auth_open [color = "#96fc6d"]
-auth_usercheck -> auth_setitem [color = "#96fc6d"]
-auth_usercheck -> auth_setdata [color = "#96fc6d"]
-auth_usercheck -> auth_verify [color = "#96fc6d"]
-auth_userokay -> auth_usercheck [color = "#3eb09b"]
-auth_userokay -> auth_close [color = "#3eb09b"]
-auth_userchallenge -> _auth_validuser [color = "#0db8d4"]
-auth_userchallenge -> login_getclass [color = "#0db8d4"]
-auth_userchallenge -> login_getstyle [color = "#0db8d4"]
-auth_userchallenge -> auth_open [color = "#0db8d4"]
-auth_userchallenge -> login_close [color = "#0db8d4"]
-auth_userchallenge -> auth_setitem [color = "#0db8d4"]
-auth_userchallenge -> auth_close [color = "#0db8d4"]
-auth_userchallenge -> auth_challenge [color = "#0db8d4"]
-auth_userresponse -> auth_setstate [color = "#cc7ac2"]
-auth_userresponse -> auth_getitem [color = "#cc7ac2"]
-auth_userresponse -> _auth_validuser [color = "#cc7ac2"]
-auth_userresponse -> auth_close [color = "#cc7ac2"]
-auth_userresponse -> auth_setdata [color = "#cc7ac2"]
-auth_userresponse -> auth_getstate [color = "#cc7ac2"]
-auth_userresponse -> auth_check_expire [color = "#cc7ac2"]
-auth_verify -> auth_open [color = "#83192f"]
-auth_verify -> auth_setstate [color = "#83192f"]
-auth_verify -> auth_setitem [color = "#83192f"]
-auth_verify -> auth_getitem [color = "#83192f"]
-auth_verify -> _auth_validuser [color = "#83192f"]
-auth_verify -> auth_set_va_list [color = "#83192f"]
-auth_verify -> auth_call [color = "#83192f"]
-auth_clean -> auth_clrenv [color = "#759227"]
-auth_clean -> auth_setitem [color = "#759227"]
-auth_close -> auth_setenv [color = "#4a5505"]
-auth_challenge -> _auth_validuser [color = "#5e3ac3"]
-auth_challenge -> auth_getvalue [color = "#5e3ac3"]
-auth_setitem -> auth_setitem [color = "#e67693"]
-auth_setitem -> _auth_validuser [color = "#e67693"]
-auth_check_expire -> auth_setpwd [color = "#739550"]
-auth_check_change -> auth_setpwd [color = "#902d9d"]
-auth_call -> _auth_next_arg [color = "#a9e6c9"]
-auth_call -> _auth_spool [color = "#a9e6c9"]
-auth_call -> _add_rmlist [color = "#a9e6c9"]
-auth_call -> auth_clrenv [color = "#a9e6c9"]
-_auth_spool -> _recv_fd [color = "#977e1c"]
-login_getstyle -> login_getcapstr [color = "#51a344"]
-login_getcapsize -> strtolimit [color = "#97959e"]
-gsetrl -> login_getcaptime [color = "#35d53a"]
-gsetrl -> login_getcapsize [color = "#35d53a"]
-gsetrl -> login_getcapnum [color = "#35d53a"]
-setclasscontext -> login_getclass [color = "#5b8e44"]
-setclasscontext -> setusercontext [color = "#5b8e44"]
-setclasscontext -> login_close [color = "#5b8e44"]
-setusercontext -> login_getclass [color = "#7eb75f"]
-setusercontext -> login_close [color = "#7eb75f"]
-setusercontext -> login_getcapnum [color = "#7eb75f"]
-setusercontext -> setuserenv [color = "#7eb75f"]
-setusercontext -> setuserpath [color = "#7eb75f"]
-setuserpath -> login_setenv [color = "#35ed7d"]
-setuserenv -> login_setenv [color = "#a1aa6a"]
-login_setenv -> expandstr [color = "#502c54"]
-strtosize -> multiply [color = "#a61402"]
-strtosize -> strtosize [color = "#a61402"]
-strtolimit -> strtosize [color = "#c987ba"]
-}
diff --git a/content/posts/WIP-how-bsd-authentication-works/graph.svg b/content/posts/WIP-how-bsd-authentication-works/graph.svg
deleted file mode 100644
index 94f22d2..0000000
--- a/content/posts/WIP-how-bsd-authentication-works/graph.svg
+++ /dev/null
@@ -1,856 +0,0 @@
-
-
-
-
-
diff --git a/content/posts/WIP-how-bsd-authentication-works/index.org b/content/posts/WIP-how-bsd-authentication-works/index.org
deleted file mode 100644
index f0623c2..0000000
--- a/content/posts/WIP-how-bsd-authentication-works/index.org
+++ /dev/null
@@ -1,2811 +0,0 @@
-#+TITLE: How BSD Authentication Works
-#+DATE: 2021-10-18T17:27:13-04:00
-#+DRAFT: true
-#+SHOWTOC: true
-#+DESCRIPTION: A walkthrough of how OpenBSD's BSD Auth framework functions
-#+TAGS[]: openbsd security
-#+KEYWORDS[]: openbsd security
-#+SLUG:
-#+SUMMARY:
-
-#+ATTR_HTML: :title OpenBSD Internals
-#+ATTR_HTML: :alt OpenBSD mascot cutaway view with spinning gears inside
-[[file:openbsd_internals.gif]]
-
-* History
- :PROPERTIES:
- :CUSTOM_ID: history
- :END:
-
- The way OpenBSD authenticates users is quite different from other
- Unix-like operating systems. Most other systems like AIX, Solaris,
- Linux, the other BSDs, and MacOS, use a framework called [[https://en.wikipedia.org/wiki/Pluggable_authentication_module][Pluggable
- Authentication Module]] (PAM). The two main implementations are [[http://www.linux-pam.org/][Linux
- PAM]] and [[https://www.openpam.org/][OpenPAM]]. PAM modules are created as dynamically loaded
- shared objects, which communicate using a combination of common and
- implementation specific interfaces ([[https://linux.die.net/man/3/pam][Linux-PAM]] and [[https://www.freebsd.org/cgi/man.cgi?query=pam&apropos=0&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports&arch=default&format=html][OpenPAM]]). It's
- configured using the [[https://linux.die.net/man/5/pam.d][pam.d]] directory and [[https://www.freebsd.org/cgi/man.cgi?query=pam.conf&sektion=5&apropos=0&manpath=FreeBSD+12.1-RELEASE+and+Ports][pam.conf]] file. While it can
- be flexible, it's highly complex and very easy to mis-configure,
- leaving you open to strange and hard to track down authentication
- bugs. On top of that, the fact that it's a shared library means that
- any vulnerability in a poorly vetted authentication module gives
- attackers direct access to the internals of your application. Author
- Michael W. Lucas said it best when he described PAM as
- [[https://www.youtube.com/watch?v=-CXp3byvI1g][unstandardized black magic]].
-
- OpenBSD on the other hand uses a mechanism called BSD
- Authentication. It was originally developed for a now-defunct
- proprietary operating system called [[https://en.wikipedia.org/wiki/BSD/OS][BSD/OS]] by [[https://en.wikipedia.org/wiki/Berkeley_Software_Design][Berkeley Software
- Design Inc.]], who later donated the system. It was then adopted by
- OpenBSD in release 2.9. BSD Auth is comparatively much simpler than
- PAM. Modules or, authentication "styles", are instead stand alone
- applications or scripts that communicate over IPC. The module has no
- ability to interfere with the parent and can very easily revoke
- permissions using [[https://man.openbsd.org/pledge][=pledge(2)=]] or [[https://man.openbsd.org/unveil][=unveil(2)=]]. The BSD Authentication
- system of configured through [[https://man.openbsd.org/login.conf][=login.conf(5)=]].
-
-* Documentation
- :PROPERTIES:
- :CUSTOM_ID: documentation
- :END:
-
- All of the high level authentication functions are described in
- [[https://man.openbsd.org/authenticate][=authenticate(3)=]], with the lower level functions being described in
- [[https://man.openbsd.org/auth_subr][=auth_subr(3)=]].
-
- Click on any function prototype in this post to see its definition.
-
- I've also created a [[#graph][graph]] at the bottom of the post to help
- visualize the function calls.
-
- All code snippets from this blog post belong to the OpenBSD
- contributors. Please see the [[#copyright][Copyright]] section for details.
-
-* BSD Auth Modules
- :PROPERTIES:
- :CUSTOM_ID: modules
- :END:
-
- Modules are located in =/usr/libexec/auth/= with the naming
- convention =login_
-#+end_export
diff --git a/content/posts/WIP-how-bsd-authentication-works/notes.org b/content/posts/WIP-how-bsd-authentication-works/notes.org
deleted file mode 100644
index 9bd67d4..0000000
--- a/content/posts/WIP-how-bsd-authentication-works/notes.org
+++ /dev/null
@@ -1,83 +0,0 @@
-* Notes
- https://web.archive.org/web/20170327150148/http://www.penzin.net/bsdauth/
- - In the man page for [[https://man.openbsd.org/auth_subr.3#auth_call][=auth_call=]] it says
- #+begin_src text
- path The full path name of the login script to run. The call will
- fail if path does not pass the requirements of the secure_path(3)
- function.
- #+end_src
-
- However I don't see this enforced anywhere, I even wrote a small test
- script to prove it.
-
- #+CAPTION: =authfail.c=
- #+begin_src c
- #include
- #include
- #include
- #include
-
- int main(void) {
- auth_session_t *as;
-
- as = auth_open();
- auth_call(as, "/home/dante/auth_tests/authtest/test", "hello", NULL);
- auth_close(as);
- }
- #+end_src
-
- Changing ="/home/dante/auth_tests/authtest/test"= to the location
- of the =test= binary.
-
- #+CAPTION: =test.c=
- #+begin_src c
- #include
-
- int main(void) {
- printf("Hello! I don't have a secure path!\n");
- return 0;
- }
- #+end_src
-
- #+CAPTION: =Makefile=
- #+begin_src makefile
- CFLAGS = -Wall -Wextra
-
- run: authfail test
- ./authfail
-
- authfail: authfail.c
- $(CC) -o $@ $(CFLAGS) $<
-
- test: test.c
- $(CC) -o $@ $(CFLAGS) $<
- #+end_src
-
- Which results in the following:
-
- #+begin_src text
- $ pwd && ls -l && make
- /home/dante/auth_tests/authtest
- total 12
- -rw-r--r-- 1 dante dante 143 May 30 19:20 Makefile
- -rw-r--r-- 1 dante dante 248 May 29 19:30 authfail.c
- -rw-r--r-- 1 dante dante 115 May 29 19:22 test.c
- cc -o authfail -Wall -Wextra authfail.c
- cc -o test -Wall -Wextra test.c
- ./authfail
- Hello! I don't have a secure path!
- #+end_src
-
- - The manpage also says the path is limited to =/bin/= and =/usr/bin=,
- which is also not the case.
-
- - The man page describes the interface for =auth_getitem= is in the
- format of =AUTH_- =, but in reality it is =AUTHV_
- =.
-
- # Ask jcs about the file descriptor situation, I don't understand it
- # after reading both the man page and source.
-
- - The [[#auth_getchallenge][=auth_getchallenge=]] function in the [[https://man.openbsd.org/auth_subr.3#auth_getchallenge][=auth_subr(3)=]] man page
- doesn't seem to exist in the source code.
-
-** TODO How are these configured in login.conf?
diff --git a/content/posts/WIP-how-bsd-authentication-works/openbsd_internals.gif b/content/posts/WIP-how-bsd-authentication-works/openbsd_internals.gif
deleted file mode 100644
index 5088082..0000000
Binary files a/content/posts/WIP-how-bsd-authentication-works/openbsd_internals.gif and /dev/null differ
--
cgit v1.2.3