her.esy.fun/src/posts/project-el/index.org

105 lines
3.3 KiB
Org Mode
Raw Normal View History

2019-07-28 16:44:25 +00:00
#+TITLE: Autoload Script by project
#+SUBTITLE: fast, secure, easy autoload
#+AUTHOR: Yann Esposito
2019-07-29 22:10:54 +00:00
#+EMAIL: yann@esposito.host
2019-08-17 17:22:22 +00:00
#+DATE: [2019-08-17 Sat]
2019-07-28 16:44:25 +00:00
#+KEYWORDS: programming, blog, org-mode
#+OPTIONS: auto-id:t
#+begin_quote
/tl;dr/: A script that use projectile and GPG to securely load
an emacs lisp script when opening a new project.
Check the [[#solution]] section to get the code.
#+end_quote
* Problem
:PROPERTIES:
:CUSTOM_ID: problem
:END:
When providing a repository containing only org files of my blog.
I also wanted to provide everything necessary for users to be able to publish my
website.
Emacs, org-publish mostly assume you should put all those details in a
centralised place in your =~/.emacs.d/.init.el= file.
The main principle is quite simple.
2019-08-20 13:35:54 +00:00
1. When opening a new file in a project, check for the presence of a
=project.el= and =project.el.sig= file at the root directory of the
project.
2. Check the file was signed with by a trusted fingerprint.
3. Load the file.
Other solutions I found on the internet asked you each time you enter in a
project if you trust the file or not.
2019-07-28 16:44:25 +00:00
This was both quite annoying and insecure as it is kind of easy to type 'y'
2019-08-20 13:35:54 +00:00
instead of 'n' and to load 3rd party script.
2019-07-28 16:44:25 +00:00
2019-08-20 13:35:54 +00:00
Note that checking who signed a file with an external signature is not as
straightforward as it should be:
2019-07-28 16:44:25 +00:00
#+begin_src elisp
2019-08-20 13:35:54 +00:00
(defun auto-load-project/get-sign-key (file)
"Return the fingerprint of they key that signed FILE.
To sign a file you should used
`gpg --local-user my@email --output project.el.sig --detach-sign project.el`"
2019-07-28 16:44:25 +00:00
(string-trim-right
(shell-command-to-string
(concat
2019-08-20 13:35:54 +00:00
(format "gpg --status-fd 1 --verify %s.sig %s 2>/dev/null " file file)
"|grep VALIDSIG"
"|awk '{print $3}'"))))
2019-07-28 16:44:25 +00:00
#+end_src
- The `--status-fd` should provide more script friendly output.
GPG provide localized output by default which are therefore hard to use in
script (for grep for example).
We use =projectile= to detect the project-root and when we are in a new project.
Unfortunately the =projectile-after-switch-project-hooks= doesn't work as I
expected.
So I use the hooks =find-file-hook= and =dired-mode-hook= to try to load the
file.
In order not to load the code each time, I need to keep a local state of project
already loaded.
2019-08-20 13:35:54 +00:00
So now, each time I modify the =project.el= I sign it with the following
command line:
#+begin_src bash
gpg --local-user my@email --output project.el.sig --detach-sign project.el
#+end_src
2019-07-28 16:44:25 +00:00
* Solution
:PROPERTIES:
:CUSTOM_ID: solution
:END:
2019-08-20 13:35:54 +00:00
The project is hosted here: https://gitlab.esy.fun/yogsototh/auto-load-project-el
You can setup the emacs package in spacemacs with:
2019-07-30 09:49:03 +00:00
2019-07-28 16:44:25 +00:00
#+begin_src elisp
2019-08-20 13:35:54 +00:00
;; ...
dotspacemacs-additional-packages
'((auto-load-project :location
(recipe
:fetcher git
:url "https://gitlab.esy.fun/yogsototh/auto-load-project-el"
:files ("auto-load-project.el"))))
;; ...
(defun dotspacemacs/user-config ()
;; ...
(require 'auto-load-project)
(setq auto-load-project/trusted-gpg-key-fingerprints
'("0000000000000000000000000000000000000000" ;; figerprint of trusted key 1
"1111111111111111111111111111111111111111"
"2222222222222222222222222222222222222222"
)))
;; ...
2019-07-28 16:44:25 +00:00
#+end_src