commit: | eae47829f0ac4149405035a7252ae4c32e0f9bb2 |
author: | Trevor Bentley |
committer: | Trevor Bentley |
date: | Thu Dec 10 01:22:36 2020 +0100 |
parents: | e96d3f55710e6b4af84cc6caae05fffb69687a8c |
diff --git a/README.md b/README.md line changes: +21/-21 index 373b7f3..13373f3 --- a/README.md +++ b/README.md
@@ -1,5 +1,5 @@ ``` -snitch.el (pronounced like schnitzel) is a firewall for emacs. +snitch.el (pronounced like schnitzel) is a firewall for Emacs. snitch intercepts calls to create network connections or launch subprocesses. Through user-configured default policies, filter
@@ -12,7 +12,7 @@ with their own separate default policies, blacklist and whitelist, and logging policies. The main purpose of snitch is network monitoring. Subprocesses are -included because it is extremely common for emacs packages to +included because it is extremely common for Emacs packages to "shell out" to an external program for network access, commonly to ‘curl’. As a side effect, snitch can also effectively audit and prevent undesired access to other programs.
@@ -31,22 +31,22 @@ network connections, and communicate through pipes. In modern times, most users manage large collections of third-party packages through intelligent package managers that automatically pull in any number of dependencies, updated periodically. Any and all of these -could be a bit naughty, and the sheer quantity of lisp code in a -modern emacs install makes it un-auditable. +could be a bit naughty, and the sheer quantity of Lisp code in a +modern Emacs install makes it un-auditable. -An emacs firewall, thus, makes sense. Does *snitch* make sense? +An Emacs firewall, thus, makes sense. Does *snitch* make sense? Not really... see the SECURITY section below. But we currently have nothing, and snitch is better than nothing. -Also, to answer the question: "I wonder if I can make an emacs +Also, to answer the question: "I wonder if I can make an Emacs firewall?" Yes! ...well, sort of. === MECHANISM === The underlying ’firewall’ mechanism is built on function advice -surrounding emacs’s lowest-level core functions for spawning -connections or subprocesses. When an emacs package or script makes +surrounding Emacs’s lowest-level core functions for spawning +connections or subprocesses. When an Emacs package or script makes such a request, snitch receives it first, and either passes it through or rejects it based on the current rules. Once a connection or process is accepted, snitch is no longer involved for
@@ -136,12 +136,12 @@ manual: Enabling snitch is as simple as calling ‘(snitch-init)’. Initialization does very little, so this is safe to call in your -emacs init without worrying about deferral or negative consequences +Emacs init without worrying about deferral or negative consequences on startup time. The minimum required initialization is simply: -> (require ’snitch) +> (require 'snitch) > (snitch-init) An example initialization using ‘use-package’ might look like so:
@@ -168,7 +168,7 @@ To disable snitch, call ‘(snitch-deinit)’. === CONFIGURATION === Customize snitch with ‘M-x customize-group <RET> snitch’, or -manually in your emacs initialization file. +manually in your Emacs initialization file. Most users will have five variables that need to be configured before use:
@@ -318,7 +318,7 @@ Memory usage should not be particularly high, as events are ephemeral and only contain a small amount of metadata. The largest use of memory is the audit log, which does keep copies of all events in the log. This can be controlled via -‘snitch--log-buffer-max-lines’. +‘snitch-log-buffer-max-lines’. Firewall rules are traversed linearly, and short-circuit (if an early rule terminates processing, the subsequent rules will not be
@@ -330,14 +330,14 @@ should be added earlier in the lists. === TIMER TRACING === Since snitch’s usefulness is highly dependent on the ability to -trace back to the original source that triggered an event, emacs +trace back to the original source that triggered an event, Emacs timers pose a bit of a challenge. Timers are used to trigger network requests asynchronously, but have the side effect of losing the stack trace back to the function or package that initiated it. To deal with this, snitch optionally supports timer tracing. When tracing is enabled, by customizing ‘snitch-trace-timers’ to t, -snitch hooks into emacs’s timer functions, and records backtraces +snitch hooks into Emacs’s timer functions, and records backtraces whenever a timer is registered. If a timer later generates a snitch-relevant event, snitch concatenates the regular backtrace with the cached timer backtrace to get a full call stack for the
@@ -358,7 +358,7 @@ With ‘snitch-trace-timers’ set to nil (tracing disabled): Notice how the source is the function ‘timer-event-handler’ in ‘timer.el’, part of the special ‘site-lisp’ package? *All* timer-originated network calls appear to originate from that -function, since it is the lowest level emacs timer dispatch +function, since it is the lowest level Emacs timer dispatch function. It is impossible to filter on the true source. Now with ‘snitch-trace-timers’ set to t (tracing enabled):
@@ -374,7 +374,7 @@ For this event, snitch has successfully traced through the timer to find the true source, ‘elfeed-insert-html’ in the ‘elfeed’ package! Timer tracing comes with a cost: snitch has to generate metadata -for every single timer event. If your emacs usage involves a very +for every single timer event. If your Emacs usage involves a very large number of timers, or very high-frequency timers, snitch’s tracing could lead to delays and inflated memory usage. Consider carefully whether this is a feature you need, and leave it disabled
@@ -402,12 +402,12 @@ might say that an effective security boundary must be "tamper-proof" and provide "complete mediation." snitch does neither. -Tamper-proof: none at all. Any other emacs package can simply +Tamper-proof: none at all. Any other Emacs package can simply disable snitch, or modify it to pass malicious traffic undetected. Complete mediation: no attempt has been made to verify that *all* network and subprocess accesses must go through the functions that -snitch hooks. Given the complexity of emacs, it is extremely +snitch hooks. Given the complexity of Emacs, it is extremely unlikely that they do. However, your Principal Security Engineer friends also like to
@@ -423,14 +423,14 @@ snitch effectiveness: great! snitch is useful for auditing and blocking unwanted features in an otherwise well-behaving ecosystem. It is handy for getting a -record of exactly what your emacs is doing, and for fine-tuning -accesses beyond emacs’s boundaries a little bit better. It will +record of exactly what your Emacs is doing, and for fine-tuning +accesses beyond Emacs’s boundaries a little bit better. It will not, however, save you from the bad guys. === KNOWN LIMITATIONS === -When snitch blocks events, some emacs functions that seldom throw +When snitch blocks events, some Emacs functions that seldom throw errors in normal use will throw errors because of snitch. It is very likely that blocked connections will cause errors to bubble up in strange and unexpected ways, as many package authors have not
diff --git a/snitch-backtrace.el b/snitch-backtrace.el line changes: +8/-7 index 53f77ca..3059222 --- a/snitch-backtrace.el +++ b/snitch-backtrace.el
@@ -36,7 +36,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: -(require 'cl-macs) ; cl loops +(require 'cl-lib) ; cl loops (require 'package) ; backtrace package sources (require 'backtrace)
@@ -52,10 +52,10 @@ ;; snitch--package-dirs-cache might grow unbounded. (defvar snitch--site-lisp-dir-cache nil - "Cache a list of the emacs site-lisp directories.") + "Cache a list of the Emacs site-lisp directories.") (defvar snitch--site-lisp-root-cache nil - "Cache a list of the emacs site-lisp root directories.") + "Cache a list of the Emacs site-lisp root directories.") (defvar snitch--function-to-file-cache nil "Hash table cache of function names to the file the functions
@@ -124,7 +124,9 @@ system-wide/non-user base directories containing elisp files." snitch--site-lisp-root-cache)) (defun snitch--dir-in-site-lisp (dir) - "Check if a directory is a subdirectory of one of the system-wide elisp directories found by `snitch--site-lisp-roots'." + "Check if directory DIR is a subdirectory of one of the +system-wide elisp directories found by +`snitch--site-lisp-roots'." (not (null (cl-loop for site-dir in (snitch--site-lisp-roots) if (string-prefix-p site-dir dir) collect site-dir))))
@@ -149,7 +151,7 @@ in that directory." (gethash (file-name-as-directory dir) snitch--package-dirs-cache)) (defun snitch--package-from-path (path) - "Try to guess a package name for a full path to a file. + "Try to guess a package name for PATH, a full path to a file. Returns a symbol, which is either an installed package name, or one of the following special values:
@@ -274,8 +276,7 @@ started the chain. On the other hand, for packages, we really want to focus on the very last function that was responsible for triggering the rest -of the emacs internal activity. -" +of the emacs internal activity." (cond ;; nil only greater than nil ((null a) (member b (list nil)))
diff --git a/snitch-custom.el b/snitch-custom.el line changes: +30/-19 index b2255c0..a93a245 --- a/snitch-custom.el +++ b/snitch-custom.el
@@ -74,7 +74,7 @@ multi-line event logs)." :group 'snitch-log) ;;;###autoload -(defcustom snitch--log-buffer-max-lines 1000 +(defcustom snitch-log-buffer-max-lines 1000 "Maximum number of lines to keep in the snitch event log buffer. When it grows larger than this, the least recent lines are periodically truncated by a timer.
@@ -138,7 +138,11 @@ snitch-network-whitelist." ;;;###autoload (defcustom snitch-network-blacklist '() - "" + "A list of rules defining which network connections are +forbidden when snitch.el is configured to allow connections by +default. + +See documentation of ‘snitch-process-whitelist’ for details." :group 'snitch-rules :type '(alist :key-type function :value-type (repeat sexp)))
@@ -146,7 +150,11 @@ snitch-network-whitelist." ;;;###autoload (defcustom snitch-network-whitelist '() - "" + "A list of rules defining which network connections are +permitted when snitch.el is configured to deny connections by +default. + +See documentation of ‘snitch-process-whitelist’ for details." :group 'snitch-rules :type '(alist :key-type function :value-type (repeat sexp)))
@@ -166,7 +174,10 @@ snitch-network-whitelist." ;; Example: block processes from an unknown user package ;;(snitch-filter/src-pkg . (user)) ) - "" + "A list of rules defining which subprocess calls are forbidden +when snitch.el is configured to allow subprocesses by default. + +See documentation of ‘snitch-process-whitelist’ for details." :group 'snitch-rules :type '(alist :key-type function :value-type (repeat sexp)))
@@ -227,10 +238,10 @@ of the other hooks with snitch's final decision. Callback functions must take two arguments: - 1) a snitch-actions symbol describing the event type ('event) + 1) a ‘snitch-actions’ symbol describing the event type (‘event’) - 2) an event object, either a snitch-process-entry or - snitch-network-entry. + 2) an event object, either a ‘snitch-process-entry’ or + ‘snitch-network-entry’. Returning nil blocks the event, terminating processing." :group 'snitch-hooks
@@ -242,10 +253,10 @@ Returning nil blocks the event, terminating processing." Callback functions must take two arguments: - 1) a snitch-actions symbol describing the event type ('block) + 1) a ‘snitch-actions’ symbol describing the event type (‘block’) - 2) an event object, either a snitch-process-entry or - snitch-network-entry. + 2) an event object, either a ‘snitch-process-entry’ or + ‘snitch-network-entry’. Returning nil interrupts the block, allowing the event to pass." :group 'snitch-hooks
@@ -257,10 +268,10 @@ Returning nil interrupts the block, allowing the event to pass." Callback functions must take two arguments: - 1) a snitch-actions symbol describing the event type ('allow) + 1) a ‘snitch-actions’ symbol describing the event type (‘allow’) - 2) an event object, either a snitch-process-entry or - snitch-network-entry. + 2) an event object, either a ‘snitch-process-entry’ or + ‘snitch-network-entry’. Returning nil blocks the event, terminating processing." :group 'snitch-hooks
@@ -272,10 +283,10 @@ Returning nil blocks the event, terminating processing." Callback functions must take two arguments: - 1) a snitch-actions symbol describing the event type ('whitelist) + 1) a ‘snitch-actions’ symbol describing the event type (‘whitelist’) - 2) an event object, either a snitch-process-entry or - snitch-network-entry. + 2) an event object, either a ‘snitch-process-entry’ or + ‘snitch-network-entry’. Returning nil blocks the event, terminating processing." :group 'snitch-hooks
@@ -287,10 +298,10 @@ Returning nil blocks the event, terminating processing." Callback functions must take two arguments: - 1) a snitch-actions symbol describing the event type ('blacklist) + 1) a ‘snitch-actions’ symbol describing the event type (‘blacklist’) - 2) an event object, either a snitch-process-entry or - snitch-network-entry. + 2) an event object, either a ‘snitch-process-entry’ or + ‘snitch-network-entry’. Returning nil interrupts the block, allowing the event to pass." :group 'snitch-hooks
diff --git a/snitch-filter.el b/snitch-filter.el line changes: +10/-9 index c7c4418..853265d --- a/snitch-filter.el +++ b/snitch-filter.el
@@ -42,25 +42,26 @@ ;; ;; -(defun snitch-filter/name (event name) +(defun snitch-filter-name (event name) "Filter function for snitch rules. -Takes the process name as a string. Applies to both network and -subprocess events." +Takes the event object EVENT and process name as a string in +NAME. Applies to both network and subprocess events." (string-equal (oref event proc-name) name)) -(defun snitch-filter/src-pkg (event pkg) +(defun snitch-filter-src-pkg (event pkg) "Filter function for snitch rules. -Takes the emacs package that originated the event as a symbol. -Applies to both network and subprocess events." +Takes the event object EVENT, and Emacs package that originated +the event, PKG, as a symbol. Applies to both network and +subprocess events." (eq (oref event src-pkg) pkg)) -(defun snitch-filter/log-filter (event &rest alist) +(defun snitch-filter-log (event &rest alist) "Filter function for snitch rules. -Takes an alist generated by the snitch log filter wizard, -filtering on all specified fields." +Takes the event object EVENT, and ALIST, an alist generated by +the snitch log filter wizard, filtering on all specified fields." (cl-loop for (aslot . avalue) in alist with accept = t do
diff --git a/snitch-log.el b/snitch-log.el line changes: +12/-10 index 7de0820..69f96ce --- a/snitch-log.el +++ b/snitch-log.el
@@ -109,7 +109,7 @@ can be used to deserialize back into an object with eval." (defun snitch--propertize (logmsg event) "Add text properties to LOGMSG with elements from EVENT. This allows the log filter commands to re-assemble an event from its -log message. " +log message." (cond ;; process events ((snitch-process-entry-p event)
@@ -217,6 +217,8 @@ type from ‘snitch-log-policies’." :data event))))) (defun snitch--prune-log-buffer () + "Prune the size of log buffer to at most +‘snitch-log-buffer-max-lines’ lines long." ;; ensure timer is stopped. it will be started again by the next ;; log event. it’s wasteful to have a timer running when we know ;; the buffer isn’t growing.
@@ -224,13 +226,13 @@ type from ‘snitch-log-policies’." (let ((buf (get-buffer-create snitch--log-buffer-name))) (with-current-buffer buf (let ((line-count (count-lines (point-min) (point-max)))) - (when (and (> snitch--log-buffer-max-lines 0) - (> line-count snitch--log-buffer-max-lines)) + (when (and (> snitch-log-buffer-max-lines 0) + (> line-count snitch-log-buffer-max-lines)) (setq buffer-read-only nil) (buffer-disable-undo) (save-excursion (goto-char (point-min)) - (forward-line (+ (- line-count snitch--log-buffer-max-lines) 1)) + (forward-line (+ (- line-count snitch-log-buffer-max-lines) 1)) (delete-region (point-min) (point)) (goto-char (point-min)) (insert "[log trimmed]\n")
@@ -306,8 +308,7 @@ persistently as a customized variable." :src-pkg pkg :proc-name name :executable exec - :args args)))) - ))) + :args args))))))) (defun snitch--run-log-filter-wizard (event) "Runs the snitch log filter 'wizard', an interactive popup
@@ -371,7 +372,7 @@ the filter to the customization variable if appropriate." ((string-equal key "w") (setq black-white "whitelist"))))) ;; append the new entry to the correct defcustom list, and ;; save as default customization. - (let* ((filter (cons #'snitch-filter/log-filter slot-value-alist)) + (let* ((filter (cons #'snitch-filter-log slot-value-alist)) (orig-list (cond ((snitch-network-entry-p event) (intern-soft (format "snitch-network-%s" black-white)))
@@ -474,15 +475,16 @@ filter from an existing log line." (setq-local show-trailing-whitespace nil)))) (defun snitch--hide-log-filter-window (buffer) - "Hide snitch log filter window." + "Hide snitch log filter window, which is the window currently +displaying BUFFER." ;; based on which-key (when (buffer-live-p buffer) (quit-windows-on buffer) (run-hooks 'snitch-log-filter-window-close-hook))) (defun snitch--log-filter-window-size-to-fit (window) - "Resize log filter window to a reasonable height and maximum -width." + "Resize log filter window, WINDOW, to a reasonable height and +maximum width." ;; based on which-key ;; cap at 30% of the vertical height (let ((fit-window-to-buffer-horizontally t)
diff --git a/snitch-test.el b/snitch-test.el line changes: +8/-8 index 85e9678..51a7d13 --- a/snitch-test.el +++ b/snitch-test.el
@@ -73,7 +73,7 @@ snitch-process-whitelist snitch-log-policy snitch-log-verbose - snitch--log-buffer-max-lines + snitch-log-buffer-max-lines snitch-on-event-functions snitch-on-allow-functions snitch-on-block-functions
@@ -91,7 +91,7 @@ (setq snitch-process-whitelist (nth 5 vars)) (setq snitch-log-policy (nth 6 vars)) (setq snitch-log-verbose (nth 7 vars)) - (setq snitch--log-buffer-max-lines (nth 8 vars)) + (setq snitch-log-buffer-max-lines (nth 8 vars)) (setq snitch-on-event-functions (nth 9 vars)) (setq snitch-on-allow-functions (nth 10 vars)) (setq snitch-on-block-functions (nth 11 vars))
@@ -109,7 +109,7 @@ (setq snitch-process-whitelist '()) (setq snitch-log-policy '()) (setq snitch-log-verbose nil) - (setq snitch--log-buffer-max-lines 1000) + (setq snitch-log-buffer-max-lines 1000) (setq snitch-on-event-functions '()) (setq snitch-on-allow-functions '()) (setq snitch-on-block-functions '())
@@ -1282,15 +1282,15 @@ blacklisted events." (dotimes (i 20) (snitch-test--process "ls" t)) (should (eq 40 (snitch-test--log-lines))) - (setq snitch--log-buffer-max-lines 30) + (setq snitch-log-buffer-max-lines 30) (snitch--prune-log-buffer) (should (eq 30 (snitch-test--log-lines))) - (setq snitch--log-buffer-max-lines 10) + (setq snitch-log-buffer-max-lines 10) (snitch--prune-log-buffer) (should (eq 10 (snitch-test--log-lines))) - (setq snitch--log-buffer-max-lines 1) + (setq snitch-log-buffer-max-lines 1) (snitch--prune-log-buffer) (should (eq 1 (snitch-test--log-lines)))
@@ -1310,7 +1310,7 @@ blacklisted events." (dotimes (i 5) (snitch-test--process "ls" t)) (should (eq 10 (snitch-test--log-lines))) - (setq snitch--log-buffer-max-lines 5) + (setq snitch-log-buffer-max-lines 5) (snitch--start-log-prune-timer) (timer-set-idle-time snitch--log-prune-timer 0) (timer-activate snitch--log-prune-timer)
@@ -1416,7 +1416,7 @@ is shown or hidden." (snitch-init) (make-network-process :name "netpoop" :host "blommorna.com" :service 443 :family 'ipv4) (url-retrieve "http://google.com" #'identity) - (setq snitch--log-buffer-max-lines 5) + (setq snitch-log-buffer-max-lines 5) )
diff --git a/snitch-timer.el b/snitch-timer.el line changes: +1/-1 index 4c07cf7..6a1e43e --- a/snitch-timer.el +++ b/snitch-timer.el
@@ -13,7 +13,7 @@ ;; ;;; Commentary: ;; -;; This file hooks emacs timers to save backtrace information. It is +;; This file hooks Emacs timers to save backtrace information. It is ;; used by the snitch-backtrace functions to reproduce full backtraces ;; for functions initiated by timers. This is required to provide a ;; more accurate guess as to which function/package originated a call
diff --git a/snitch.el b/snitch.el line changes: +26/-27 index f1d3eb2..fb465a5 --- a/snitch.el +++ b/snitch.el
@@ -1,10 +1,11 @@ -;;; snitch.el --- an emacs firewall -*- lexical-binding: t; -*- +;;; snitch.el --- An emacs firewall -*- lexical-binding: t; -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Copyright (C) 2020 Trevor Bentley ;; Author: Trevor Bentley <snitch.el@x.mrmekon.com> ;; Created: 01 Dec 2020 ;; Version: 0.2.0 +;; Package-Requires: ((emacs "27.1")) ;; ;; Keywords: processes, comm ;; URL: https://github.com/mrmekon/snitch-el
@@ -15,7 +16,7 @@ ;; ;;; Commentary: ;; -;; snitch.el (pronounced like schnitzel) is a firewall for emacs. +;; snitch.el (pronounced like schnitzel) is a firewall for Emacs. ;; ;; snitch intercepts calls to create network connections or launch ;; subprocesses. Through user-configured default policies, filter
@@ -28,7 +29,7 @@ ;; and logging policies. ;; ;; The main purpose of snitch is network monitoring. Subprocesses are -;; included because it is extremely common for emacs packages to +;; included because it is extremely common for Emacs packages to ;; "shell out" to an external program for network access, commonly to ;; ‘curl’. As a side effect, snitch can also effectively audit and ;; prevent undesired access to other programs.
@@ -47,22 +48,22 @@ ;; times, most users manage large collections of third-party packages ;; through intelligent package managers that automatically pull in any ;; number of dependencies, updated periodically. Any and all of these -;; could be a bit naughty, and the sheer quantity of lisp code in a -;; modern emacs install makes it un-auditable. +;; could be a bit naughty, and the sheer quantity of Lisp code in a +;; modern Emacs install makes it un-auditable. ;; -;; An emacs firewall, thus, makes sense. Does *snitch* make sense? +;; An Emacs firewall, thus, makes sense. Does *snitch* make sense? ;; Not really... see the SECURITY section below. But we currently ;; have nothing, and snitch is better than nothing. ;; -;; Also, to answer the question: "I wonder if I can make an emacs +;; Also, to answer the question: "I wonder if I can make an Emacs ;; firewall?" Yes! ...well, sort of. ;; ;; ;; === MECHANISM === ;; ;; The underlying ’firewall’ mechanism is built on function advice -;; surrounding emacs’s lowest-level core functions for spawning -;; connections or subprocesses. When an emacs package or script makes +;; surrounding Emacs’s lowest-level core functions for spawning +;; connections or subprocesses. When an Emacs package or script makes ;; such a request, snitch receives it first, and either passes it ;; through or rejects it based on the current rules. Once a ;; connection or process is accepted, snitch is no longer involved for
@@ -152,7 +153,7 @@ ;; ;; Enabling snitch is as simple as calling ‘(snitch-init)’. ;; Initialization does very little, so this is safe to call in your -;; emacs init without worrying about deferral or negative consequences +;; Emacs init without worrying about deferral or negative consequences ;; on startup time. ;; ;; The minimum required initialization is simply:
@@ -184,7 +185,7 @@ ;; === CONFIGURATION === ;; ;; Customize snitch with ‘M-x customize-group <RET> snitch’, or -;; manually in your emacs initialization file. +;; manually in your Emacs initialization file. ;; ;; Most users will have five variables that need to be configured ;; before use:
@@ -227,7 +228,7 @@ ;; > (setq snitch-process-policy 'deny) ;; > (setq snitch-log-policy '(blocked whitelisted allowed)) ;; > (add-to-list 'snitch-network-whitelist -;; > (cons #'snitch-filter/src-pkg '(elfeed))) +;; > (cons #'snitch-filter-src-pkg '(elfeed))) ;; > (snitch-init)) ;; ;;
@@ -334,7 +335,7 @@ ;; ephemeral and only contain a small amount of metadata. The largest ;; use of memory is the audit log, which does keep copies of all ;; events in the log. This can be controlled via -;; ‘snitch--log-buffer-max-lines’. +;; ‘snitch-log-buffer-max-lines’. ;; ;; Firewall rules are traversed linearly, and short-circuit (if an ;; early rule terminates processing, the subsequent rules will not be
@@ -346,14 +347,14 @@ ;; === TIMER TRACING === ;; ;; Since snitch’s usefulness is highly dependent on the ability to -;; trace back to the original source that triggered an event, emacs +;; trace back to the original source that triggered an event, Emacs ;; timers pose a bit of a challenge. Timers are used to trigger ;; network requests asynchronously, but have the side effect of losing ;; the stack trace back to the function or package that initiated it. ;; ;; To deal with this, snitch optionally supports timer tracing. When ;; tracing is enabled, by customizing ‘snitch-trace-timers’ to t, -;; snitch hooks into emacs’s timer functions, and records backtraces +;; snitch hooks into Emacs’s timer functions, and records backtraces ;; whenever a timer is registered. If a timer later generates a ;; snitch-relevant event, snitch concatenates the regular backtrace ;; with the cached timer backtrace to get a full call stack for the
@@ -374,7 +375,7 @@ ;; Notice how the source is the function ‘timer-event-handler’ in ;; ‘timer.el’, part of the special ‘site-lisp’ package? *All* ;; timer-originated network calls appear to originate from that -;; function, since it is the lowest level emacs timer dispatch +;; function, since it is the lowest level Emacs timer dispatch ;; function. It is impossible to filter on the true source. ;; ;; Now with ‘snitch-trace-timers’ set to t (tracing enabled):
@@ -390,7 +391,7 @@ ;; find the true source, ‘elfeed-insert-html’ in the ‘elfeed’ package! ;; ;; Timer tracing comes with a cost: snitch has to generate metadata -;; for every single timer event. If your emacs usage involves a very +;; for every single timer event. If your Emacs usage involves a very ;; large number of timers, or very high-frequency timers, snitch’s ;; tracing could lead to delays and inflated memory usage. Consider ;; carefully whether this is a feature you need, and leave it disabled
@@ -418,12 +419,12 @@ ;; "tamper-proof" and provide "complete mediation." snitch does ;; neither. ;; -;; Tamper-proof: none at all. Any other emacs package can simply +;; Tamper-proof: none at all. Any other Emacs package can simply ;; disable snitch, or modify it to pass malicious traffic undetected. ;; ;; Complete mediation: no attempt has been made to verify that *all* ;; network and subprocess accesses must go through the functions that -;; snitch hooks. Given the complexity of emacs, it is extremely +;; snitch hooks. Given the complexity of Emacs, it is extremely ;; unlikely that they do. ;; ;; However, your Principal Security Engineer friends also like to
@@ -439,14 +440,14 @@ ;; ;; snitch is useful for auditing and blocking unwanted features in an ;; otherwise well-behaving ecosystem. It is handy for getting a -;; record of exactly what your emacs is doing, and for fine-tuning -;; accesses beyond emacs’s boundaries a little bit better. It will +;; record of exactly what your Emacs is doing, and for fine-tuning +;; accesses beyond Emacs’s boundaries a little bit better. It will ;; not, however, save you from the bad guys. ;; ;; ;; === KNOWN LIMITATIONS === ;; -;; When snitch blocks events, some emacs functions that seldom throw +;; When snitch blocks events, some Emacs functions that seldom throw ;; errors in normal use will throw errors because of snitch. It is ;; very likely that blocked connections will cause errors to bubble up ;; in strange and unexpected ways, as many package authors have not
@@ -521,7 +522,7 @@ ;;; Code: (require 'eieio) ; class objects -(require 'cl-macs) ; cl loops +(require 'cl-lib) ; cl loops (require 'package) ; backtrace package sources (require 'backtrace)
@@ -643,8 +644,7 @@ were blocked by a blacklist rule") network-blocked network-allowed network-whitelisted - network-blacklisted - ) + network-blacklisted) "All of the logging policies for snitch. Provide a list of these symbols to ‘snitch-log-policy’ to enable logging of events of the corresponding type.
@@ -794,8 +794,7 @@ permit it." :src-pkg (nth 2 caller) :proc-name (plist-get args :name) :executable (car (plist-get args :command)) - :args (cdr (plist-get args :command))) - )) + :args (cdr (plist-get args :command))))) (snitch--wrap-internal event "process" orig-fun args))) (defun snitch--wrap-make-network-process (orig-fun &rest args)
diff --git a/test_snitch.sh b/test_snitch.sh line changes: +16/-0 index 780fa32..5a61091 --- a/test_snitch.sh +++ b/test_snitch.sh
@@ -1,4 +1,20 @@ #!/bin/bash +set -e + +emacs -batch \ + --eval "(package-initialize)" \ + --eval "(setq load-path (seq-filter \ + (lambda (x) (not (string-match \"/snitch\" x))) load-path))" \ + --eval "(add-to-list 'load-path \"~/.emacs.d/snitch/\")" \ + --eval "(require 'snitch)" \ + --eval "(message \"Testing snitch version: %s\" (snitch-version))" \ + --eval "(setq package-lint-batch-fail-on-warnings nil)" \ + --eval "(setq package-lint-main-file \"snitch.el\")" \ + -L . \ + -f package-lint-batch-and-exit \ + snitch.el snitch-backtrace.el snitch-custom.el \ + snitch-filter.el snitch-log.el snitch-timer.el + emacs -batch \ --eval "(package-initialize)" \ --eval "(setq load-path (seq-filter \