aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Schmidt2023-05-21 21:37:35 +0200
committerEli Zaretskii2023-05-31 15:53:10 +0300
commit372bc1278c2d7c2440bb3d528f4c4e03402d21b5 (patch)
tree49ed4941aa7d6aef24b250116eaba75b55fb7479
parent23a14e7b9026a8572fe8ae8759232e08cd37910a (diff)
downloademacs-372bc1278c2d7c2440bb3d528f4c4e03402d21b5.tar.gz
emacs-372bc1278c2d7c2440bb3d528f4c4e03402d21b5.zip
Add internal documentation on plstore.el
* lisp/plstore.el: Add internal documentation and some words of warning in the user documentation. (Bug#63627)
-rw-r--r--lisp/plstore.el133
1 files changed, 131 insertions, 2 deletions
diff --git a/lisp/plstore.el b/lisp/plstore.el
index 0276a752a0f..1a0dacffb01 100644
--- a/lisp/plstore.el
+++ b/lisp/plstore.el
@@ -24,6 +24,14 @@
24 24
25;; Plist based data store providing search and partial encryption. 25;; Plist based data store providing search and partial encryption.
26;; 26;;
27;; By default, this package uses symmetric encryption, which means
28;; that you have to enter the password protecting your store more
29;; often than you probably expect to. To use public key encryption
30;; with this package, create a GnuPG key and customize user option
31;; `plstore-encrypt-to' to use it. You can then configure the GnuPG
32;; agent to adjust caching and expiration of the passphrase for your
33;; store.
34;;
27;; Creating: 35;; Creating:
28;; 36;;
29;; ;; Open a new store associated with ~/.emacs.d/auth.plist. 37;; ;; Open a new store associated with ~/.emacs.d/auth.plist.
@@ -43,12 +51,16 @@
43;; ;; Kill the buffer visiting ~/.emacs.d/auth.plist. 51;; ;; Kill the buffer visiting ~/.emacs.d/auth.plist.
44;; (plstore-close store) 52;; (plstore-close store)
45;; 53;;
54;; Avoid marking one property both as public *and* secret, as the
55;; behavior of this package with respect to such duplicate properties
56;; is not (yet) defined.
57;;
46;; Searching: 58;; Searching:
47;; 59;;
48;; (setq store (plstore-open (expand-file-name "~/.emacs.d/auth.plist"))) 60;; (setq store (plstore-open (expand-file-name "~/.emacs.d/auth.plist")))
49;; 61;;
50;; ;; As the entry "foo" associated with "foo.example.org" has no 62;; ;; As the entry "foo" associated with "foo.example.org" has no
51;; ;; secret properties, no need to decryption. 63;; ;; secret properties, no need for decryption.
52;; (plstore-find store '(:host ("foo.example.org"))) 64;; (plstore-find store '(:host ("foo.example.org")))
53;; 65;;
54;; ;; As the entry "bar" associated with "bar.example.org" has a 66;; ;; As the entry "bar" associated with "bar.example.org" has a
@@ -73,10 +85,112 @@
73;; 85;;
74;; where the prefixing `:secret-' means the property (without 86;; where the prefixing `:secret-' means the property (without
75;; `:secret-' prefix) is marked as secret. Thus, when you save the 87;; `:secret-' prefix) is marked as secret. Thus, when you save the
76;; buffer, the `:secret-user' property is encrypted as `:user'. 88;; buffer, the `:secret-user' property is encrypted as `:user'. Do
89;; not use a property consisting solely of the prefix, as the behavior
90;; of this package with respect to such properties is not (yet)
91;; defined.
77;; 92;;
78;; You can toggle the view between encrypted form and the decrypted 93;; You can toggle the view between encrypted form and the decrypted
79;; form with C-c C-c. 94;; form with C-c C-c.
95;;
96;; If you have opened a plstore with `plstore-open' you should not
97;; edit its underlying buffer in `plstore-mode' or in any other way at
98;; the same time, since your manual changes will be overwritten when
99;; `plstore-save' is called on that plstore.
100;;
101;; Internals:
102;;
103;; This is information on the internal data structure and functions of
104;; this package. None of it should be necessary to actually use it.
105;; For easier reading, we usually do not distinguish in this internal
106;; documentation between a Lisp object and its printed representation.
107;;
108;; A plstore corresponds to an alist mapping strings to property
109;; lists. Internally, that alist is organized as two alists, one
110;; mapping to the non-secret properties and placeholders for the
111;; secret properties (called "template alist" with identifier ALIST)
112;; and one mapping to the secret properties ("secret alist",
113;; SECRET-ALIST). The secret alist is read from and written to file
114;; as pgp-encrypted printed representation of the alist ("encrypted
115;; data", ENCRYPTED-DATA).
116;;
117;; During the lifetime of a plstore, a third type of alist may pop up,
118;; which maps to the merged non-secret properties and plain-text
119;; secret properties ("merged alist", MERGED-ALIST).
120;;
121;; After executing the "foo", "bar", "baz" example from above the
122;; alists described above look like the following:
123;;
124;; Template Alist:
125;;
126;; (("foo" :host "foo.example.org" :port 80)
127;; ("bar" :secret-user t :host "bar.example.org")
128;; ("baz" :secret-password t :host "baz.example.org"))
129;;
130;; Secret Alist:
131;;
132;; (("bar" :user "test")
133;; ("baz" :password "test"))
134;;
135;; Merged Alist:
136;;
137;; (("foo" :host "foo.example.org" :port 80)
138;; ("bar" :user "test" :host "bar.example.org")
139;; ("baz" :password "test" :host "baz.example.org"))
140;;
141;; Finally, a plstore requires a buffer ("plstore buffer", BUFFER) for
142;; conversion between its Lisp objects and its file representation.
143;; It is important to note that this buffer is *not* continuously
144;; synchronized as the plstore changes. During the lifetime of a
145;; plstore, its buffer is read from in function `plstore-open' and
146;; (destructively) written to in `plstore-save', but not touched
147;; otherwise. We call the file visited by the plstore buffer the
148;; associated file of the plstore.
149;;
150;; With the identifiers defined above a plstore is a vector with the
151;; following elements and accessor functions:
152;;
153;; [
154;; BUFFER ; plstore--get/set-buffer
155;; ALIST ; plstore--get/set-alist
156;; ENCRYPTED-DATA ; plstore--get/set-encrypted-data
157;; SECRET-ALIST ; plstore--get/set-secret-alist
158;; MERGED-ALIST ; plstore--get/set-merged-alist
159;; ]
160;;
161;; When a plstore is created through `plstore-open', its ALIST and
162;; ENCRYPTED-DATA are initialized from the contents of BUFFER without
163;; any decryption taking place, and MERGED-ALIST is initialized as a
164;; copy of ALIST. (Which means that at that stage the merged alist
165;; still contains the secret property placeholders!)
166;;
167;; During on-demand decryption of a plstore through function
168;; `plstore--decrypt', SECRET-ALIST is populated from ENCRYPTED-DATA,
169;; which is in turn replaced by value nil. (Which further serves as
170;; an indicator that the plstore has been decrypted already.) In
171;; addition, MERGED-ALIST is recomputed by function
172;; `plstore--merge-secret' to replace the secret property placeholders
173;; by their plain-text secret property equivalents.
174;;
175;; The file representation of a plstore consists of two Lisp forms plus
176;; markers to introduce them:
177;;
178;; ;;; public entries
179;; ALIST
180;; ;;; secret entries
181;; ENCRYPTED-DATA
182;;
183;; Both of these are optional, but the first section must be present
184;; if the second one is. If both sections are missing, the plstore is
185;; empty. If the second section is missing, it contains only
186;; non-secret data. If present, the printed representation of the
187;; encrypted data includes the delimiting double quotes.
188;;
189;; The plstore API (`plstore-open', `plstore-put', etc.) and the
190;; plstore mode implemented by `plstore-mode' are orthogonal to each
191;; other and should not be mixed up. In particular, encoding and
192;; decoding a plstore mode buffer with `plstore-mode-toggle-display'
193;; is not related in any way to the state of the plstore buffer.
80 194
81;;; Code: 195;;; Code:
82 196
@@ -457,6 +571,21 @@ If no one is selected, symmetric encryption will be performed. "
457 (plstore--insert-buffer plstore) 571 (plstore--insert-buffer plstore)
458 (save-buffer))) 572 (save-buffer)))
459 573
574;; The functions related to plstore mode unfortunately introduce yet
575;; another alist format ("decoded alist"). After executing the "foo",
576;; "bar", "baz" example from above the decoded alist of the plstore
577;; would look like the following:
578;;
579;; (("foo" :host "foo.example.org" :port 80)
580;; ("bar" :secret-user "test" :host "bar.example.org")
581;; ("baz" :secret-password "test" :host "baz.example.org"))
582;;
583;; Even more unfortunately, variable and function names of the
584;; following are a bit mixed up IMHO: With the current names, the
585;; result of function `plstore--encode' is used to create what is
586;; presented as "decoded form of a plstore" to the user. And variable
587;; `plstore-encoded' is non-nil if a buffer shows the decoded form.
588
460(defun plstore--encode (plstore) 589(defun plstore--encode (plstore)
461 (plstore--decrypt plstore) 590 (plstore--decrypt plstore)
462 (let ((merged-alist (plstore--get-merged-alist plstore))) 591 (let ((merged-alist (plstore--get-merged-alist plstore)))