emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GnuTLS per-connection variables


From: Michael Albinus
Subject: Re: GnuTLS per-connection variables
Date: Mon, 28 Nov 2016 19:54:20 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux)

Ted Zlatanov <address@hidden> writes:

Hi Ted,

> I looked at migrating gnutls.el to use this new facility. I have some
> questions (and maybe Lars and others can add more).
>
> * how will users see and configure the settings per class?
>
> * how will users select the class per server? The NSM may be useful
>   here, since it already does some per-connection checks and storage.

Over the weekend, I've played a little bit with this. As a result there
are two new functions (see attached patch), which could give some support.

The following scenario shall give you an idea. I assume, you have some
connection-local variables you want to offer. Declare them as alist,
where the `cdr' of every element might be the default value to use:

(defvar gnutls-boot-parameters-default
  '((gnutls-priority . "priority-string")
    (gnutls-hostname . "localhost")
    (gnutls-loglevel . 123)
    (gnutls-min-prime-bits . 1024)
    (gnutls-trustfiles . "/etc/trustfiles")
    (gnutls-crlfiles . "/etc/crlfiles")
    (gnutls-keylist)
    (gnutls-verify-flags a b c)
    (gnutls-verify-error . t)
    (gnutls-callbacks))
  "Connection-local variables and their initial values.")

Please don't discuss the values with me, I've used them ramdomly :-)

After that, you call

(connection-local-custom-create-custom
 'gnutls-boot-parameters 'gnutls-boot-parameters-default)

This creates a new custom option `gnutls-boot-parameters', which you
could edit now in the appearing customization buffer. You should add
regular expressions, which identify the remote servers you want to
provide with connection-local variables. Let's assume you add the two
regular expressions "^/ssh:" "and remote-host". If you set these values
in the custom buffer, the custom option `gnutls-boot-parameters' is
created with the following values:

gnutls-boot-parameters
=> ("^/ssh:" "remote-host")

Furthermore, two additional custom options are created, which represent
intermediate classes
`connection-local--class-^/ssh:-gnutls-boot-parameters-default' and
`connection-local--class-remote-host-gnutls-boot-parameters-default'. The
names sound strange, but this could be changed. You don't need them
explicitely.

Now follow the link at the bottom of the customization buffer to the
custom group connection-local. Beside the new custom option
`gnutls-boot-parameters', you see also the two new options representing
the classes. Customize them. For example, in the custom option
`connection-local--class-^/ssh:-gnutls-boot-parameters-default' you
might select the keys `gnutls-priority' and `gnutls-hostname', and in
the custom option
`connection-local--class-remote-host-gnutls-boot-parameters-default' you
might select the keys `gnutls-min-prime-bits' and `gnutls-crlfiles'. In
all cases, you could also change the values of the selected keys.

Apply the changes, and now you have as desired

connection-local-criteria-alist
=> (("remote-host" 
connection-local--class-remote-host-gnutls-boot-parameters-default)
    ("^/ssh:" connection-local--class-^/ssh:-gnutls-boot-parameters-default))

connection-local-class-alist
=> ((connection-local--class-remote-host-gnutls-boot-parameters-default
    (gnutls-min-prime-bits . 2048)
    (gnutls-trustfiles . "/etc/trustfiles")
    (gnutls-crlfiles . "/opt/crlfiles"))
   (connection-local--class-^/ssh:-gnutls-boot-parameters-default
    (gnutls-priority . "priority-string")
    (gnutls-hostname . "localhost")))

All of this is far from being perfect, but you see the idea.

> * how to migrate users from the current defcustoms in
>   (customize-group 'gnutls) to this new system? Do we support both for
>   some time?

For this I still have no idea.

> Thanks
> Ted

Best regards, Michael.

--8<---------------cut here---------------start------------->8---
*** 
/home/albinus/src/emacs/lisp/files-x.el.~1228055b320dbed92ab400c4a95813a2b8023909~
  2016-11-28 19:26:52.537538722 +0100
--- /home/albinus/src/emacs/lisp/files-x.el     2016-11-28 18:02:11.790554444 
+0100
***************
*** 559,564 ****
--- 559,570 ----
  (setq ignored-local-variables
        (cons 'connection-local-variables-alist ignored-local-variables))
  
+ (defgroup connection-local nil
+   "Declare connection-local files."
+   :group 'files
+ ;  :link '(custom-manual "(tramp)Top")
+   :version "26.1")
+ 
  (defvar connection-local-class-alist '()
    "Alist mapping connection-local variable classes (symbols) to variable 
lists.
  Each element in this list has the form (CLASS VARIABLES).
***************
*** 636,641 ****
--- 642,734 ----
  class.  The list is processed in order."
    (setf (alist-get class connection-local-class-alist) variables))
  
+ (defun connection-local-custom-set-variables (criteria template)
+   "Add connection-local variables for remote servers.
+ CRITERIA is either a regular expression identifying a remote
+ server, or a function with one argument IDENTIFICATION, which
+ returns non-nil when a remote server shall apply variables.  If
+ CRITERIA is nil, it always applies.
+ 
+ TEMPLATE, a symbol, contains a list of connection-local variables
+ and their initial values.  Every element of this list is a cons
+ cell of type (VARIABLE . VALUE).
+ 
+ A new customizable variable is created on-the-fly, which is used
+ as connection-local class in order to create a link between
+ CRITERIA and the variables.  A customization buffer opens in
+ order to provide an interface for setting the connection-local
+ variables derived from TEMPLATE."
+   (unless (symbolp template) (error "Invalid template %s" template))
+   (let ((class
+          (intern (format "connection-local--class-%s-%s" criteria template)))
+         (type
+          `(alist
+            :key-type variable :value-type sexp
+            :options
+            ,(mapcar
+              (lambda (x)
+                "Compute alist options, depending on TEMPLATE."
+                (unless (consp x) (error "Invalid argument %s in template" x))
+                (list
+                 (car x)
+                 ;; We support only some few types.  All other types
+                 ;; are handled as sexp.
+                 (if (null (cdr x))
+                     'sexp
+                   (list
+                    (cond
+                     ((numberp (cdr x)) 'number)
+                     ((stringp (cdr x)) 'string)
+                     ((functionp (cdr x)) 'function)
+ ;;                    ((booleanp (cdr x)) 'boolean)
+                     ((symbolp (cdr x)) 'symbol)
+ ;;                    ((consp (cdr x)) 'cons)
+ ;;                    ((vectorp (cdr x)) 'vector)
+ ;;                    ((listp (cdr x)) 'list)
+                     (t 'sexp))
+                    :value (cdr x)))))
+              (symbol-value template))))
+         (setfunction
+          `(lambda (symbol value)
+             (set symbol value)
+             (connection-local-set-class-variables symbol value)
+             (connection-local-set-classes ,criteria symbol))))
+     (eval
+      `(progn
+         (defcustom ,class nil
+           ,(format
+             "Connection-local class for criteria %S and template %S."
+             criteria template)
+           :group 'connection-local
+           :type type
+           :set setfunction)))))
+ 
+ (defun connection-local-custom-create-custom (option template)
+   "Create custom variable OPTION, and initialize it with TEMPLATE.
+ TEMPLATE, a symbol, contains a list of connection-local variables
+ and their initial values.  Every element of this list is a cons
+ cell of type (VARIABLE . VALUE).
+ OPTION can be used then to customize the connection-local
+ variables according to different remote connections."
+   (unless (symbolp option) (error "Invalid custom variable %s" option))
+   (unless (symbolp template) (error "Invalid template %s" template))
+   (let ((type '(repeat regexp))
+         (setfunction
+          `(lambda (symbol value)
+             (set symbol value)
+             (dolist (val value)
+               (connection-local-custom-set-variables val ',template)))))
+     (eval
+      `(progn
+         (defcustom ,option nil
+           ,(format
+             "Connection-local class for custom option %S and template %S."
+             option template)
+           :group 'connection-local
+           :type type
+           :set setfunction)
+         (customize-variable ',option)))))
+ 
  (defun hack-connection-local-variables ()
    "Read per-connection local variables for the current buffer.
  Store the connection-local variables in `connection-local-variables-alist'.
--8<---------------cut here---------------end--------------->8---



reply via email to

[Prev in Thread] Current Thread [Next in Thread]