aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/server.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/server.el')
-rw-r--r--lisp/server.el144
1 files changed, 96 insertions, 48 deletions
diff --git a/lisp/server.el b/lisp/server.el
index 404bebc4747..1e2f458ac9c 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -139,6 +139,32 @@ directory residing in a NTFS partition instead."
139;;;###autoload 139;;;###autoload
140(put 'server-auth-dir 'risky-local-variable t) 140(put 'server-auth-dir 'risky-local-variable t)
141 141
142(defcustom server-auth-key nil
143 "Server authentication key.
144
145Normally, the authentication key is randomly generated when the
146server starts, which guarantees some level of security. It is
147recommended to leave it that way. Using a long-lived shared key
148will decrease security (especially since the key is transmitted as
149plain text).
150
151In some situations however, it can be difficult to share randomly
152generated passwords with remote hosts (eg. no shared directory),
153so you can set the key with this variable and then copy the
154server file to the remote host (with possible changes to IP
155address and/or port if that applies).
156
157The key must consist of 64 ASCII printable characters except for
158space (this means characters from ! to ~; or from code 33 to 126).
159
160You can use \\[server-generate-key] to get a random authentication
161key."
162 :group 'server
163 :type '(choice
164 (const :tag "Random" nil)
165 (string :tag "Password"))
166 :version "24.2")
167
142(defcustom server-raise-frame t 168(defcustom server-raise-frame t
143 "If non-nil, raise frame when switching to a buffer." 169 "If non-nil, raise frame when switching to a buffer."
144 :group 'server 170 :group 'server
@@ -494,41 +520,62 @@ Creates the directory if necessary and makes sure:
494 ;; Check that it's safe for use. 520 ;; Check that it's safe for use.
495 (let* ((uid (nth 2 attrs)) 521 (let* ((uid (nth 2 attrs))
496 (w32 (eq system-type 'windows-nt)) 522 (w32 (eq system-type 'windows-nt))
497 (safe (catch :safe 523 (safe (cond
498 (unless (eq t (car attrs)) ; is a dir? 524 ((not (eq t (car attrs))) nil) ; is a dir?
499 (throw :safe nil)) 525 ((and w32 (zerop uid)) ; on FAT32?
500 (when (and w32 (zerop uid)) ; on FAT32? 526 (display-warning
501 (display-warning 527 'server
502 'server 528 (format "Using `%s' to store Emacs-server authentication files.
503 (format "Using `%s' to store Emacs-server authentication files.
504Directories on FAT32 filesystems are NOT secure against tampering. 529Directories on FAT32 filesystems are NOT secure against tampering.
505See variable `server-auth-dir' for details." 530See variable `server-auth-dir' for details."
506 (file-name-as-directory dir)) 531 (file-name-as-directory dir))
507 :warning) 532 :warning)
508 (throw :safe t)) 533 t)
509 (unless (or (= uid (user-uid)) ; is the dir ours? 534 ((and (/= uid (user-uid)) ; is the dir ours?
510 (and w32 535 (or (not w32)
511 ;; Files created on Windows by 536 ;; Files created on Windows by Administrator
512 ;; Administrator (RID=500) have 537 ;; (RID=500) have the Administrators (RID=544)
513 ;; the Administrators (RID=544) 538 ;; group recorded as the owner.
514 ;; group recorded as the owner. 539 (/= uid 544) (/= (user-uid) 500)))
515 (= uid 544) (= (user-uid) 500))) 540 nil)
516 (throw :safe nil)) 541 (w32 t) ; on NTFS?
517 (when w32 ; on NTFS? 542 (t ; else, check permissions
518 (throw :safe t)) 543 (zerop (logand ?\077 (file-modes dir)))))))
519 (unless (zerop (logand ?\077 (file-modes dir)))
520 (throw :safe nil))
521 t)))
522 (unless safe 544 (unless safe
523 (error "The directory `%s' is unsafe" dir))))) 545 (error "The directory `%s' is unsafe" dir)))))
524 546
547(defun server-generate-key ()
548 "Generate and return a random authentication key.
549The key is a 64-byte string of random chars in the range `!'..`~'.
550If called interactively, also inserts it into current buffer."
551 (interactive)
552 (let ((auth-key
553 (loop repeat 64
554 collect (+ 33 (random 94)) into auth
555 finally return (concat auth))))
556 (if (called-interactively-p 'interactive)
557 (insert auth-key))
558 auth-key))
559
560(defun server-get-auth-key ()
561 "Return server's authentication key.
562
563If `server-auth-key' is nil, just call `server-generate-key'.
564Otherwise, if `server-auth-key' is a valid key, return it.
565If the key is not valid, signal an error."
566 (if server-auth-key
567 (if (string-match-p "^[!-~]\\{64\\}$" server-auth-key)
568 server-auth-key
569 (error "The key '%s' is invalid" server-auth-key))
570 (server-generate-key)))
571
525;;;###autoload 572;;;###autoload
526(defun server-start (&optional leave-dead inhibit-prompt) 573(defun server-start (&optional leave-dead inhibit-prompt)
527 "Allow this Emacs process to be a server for client processes. 574 "Allow this Emacs process to be a server for client processes.
528This starts a server communications subprocess through which 575This starts a server communications subprocess through which client
529client \"editors\" can send your editing commands to this Emacs 576\"editors\" can send your editing commands to this Emacs job.
530job. To use the server, set up the program `emacsclient' in the 577To use the server, set up the program `emacsclient' in the Emacs
531Emacs distribution as your standard \"editor\". 578distribution as your standard \"editor\".
532 579
533Optional argument LEAVE-DEAD (interactively, a prefix arg) means just 580Optional argument LEAVE-DEAD (interactively, a prefix arg) means just
534kill any existing server communications subprocess. 581kill any existing server communications subprocess.
@@ -615,13 +662,7 @@ server or call `M-x server-force-delete' to forcibly disconnect it.")
615 (unless server-process (error "Could not start server process")) 662 (unless server-process (error "Could not start server process"))
616 (process-put server-process :server-file server-file) 663 (process-put server-process :server-file server-file)
617 (when server-use-tcp 664 (when server-use-tcp
618 (let ((auth-key 665 (let ((auth-key (server-get-auth-key)))
619 (loop
620 ;; The auth key is a 64-byte string of random chars in the
621 ;; range `!'..`~'.
622 repeat 64
623 collect (+ 33 (random 94)) into auth
624 finally return (concat auth))))
625 (process-put server-process :auth-key auth-key) 666 (process-put server-process :auth-key auth-key)
626 (with-temp-file server-file 667 (with-temp-file server-file
627 (set-buffer-multibyte nil) 668 (set-buffer-multibyte nil)
@@ -780,10 +821,6 @@ This handles splitting the command if it would be bigger than
780 (select-frame frame) 821 (select-frame frame)
781 (process-put proc 'frame frame) 822 (process-put proc 'frame frame)
782 (process-put proc 'terminal (frame-terminal frame)) 823 (process-put proc 'terminal (frame-terminal frame))
783
784 ;; Display *scratch* by default.
785 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
786
787 frame)) 824 frame))
788 825
789(defun server-create-window-system-frame (display nowait proc parent-id 826(defun server-create-window-system-frame (display nowait proc parent-id
@@ -816,9 +853,6 @@ This handles splitting the command if it would be bigger than
816 (select-frame frame) 853 (select-frame frame)
817 (process-put proc 'frame frame) 854 (process-put proc 'frame frame)
818 (process-put proc 'terminal (frame-terminal frame)) 855 (process-put proc 'terminal (frame-terminal frame))
819
820 ;; Display *scratch* by default.
821 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
822 frame))) 856 frame)))
823 857
824(defun server-goto-toplevel (proc) 858(defun server-goto-toplevel (proc)
@@ -1042,8 +1076,9 @@ The following commands are accepted by the client:
1042 1076
1043 ;; -window-system: Open a new X frame. 1077 ;; -window-system: Open a new X frame.
1044 (`"-window-system" 1078 (`"-window-system"
1045 (setq dontkill t) 1079 (if (fboundp 'x-create-frame)
1046 (setq tty-name 'window-system)) 1080 (setq dontkill t
1081 tty-name 'window-system)))
1047 1082
1048 ;; -resume: Resume a suspended tty frame. 1083 ;; -resume: Resume a suspended tty frame.
1049 (`"-resume" 1084 (`"-resume"
@@ -1071,7 +1106,8 @@ The following commands are accepted by the client:
1071 (setq dontkill t) 1106 (setq dontkill t)
1072 (pop args-left)) 1107 (pop args-left))
1073 1108
1074 ;; -tty DEVICE-NAME TYPE: Open a new tty frame at the client. 1109 ;; -tty DEVICE-NAME TYPE: Open a new tty frame.
1110 ;; (But if we see -window-system later, use that.)
1075 (`"-tty" 1111 (`"-tty"
1076 (setq tty-name (pop args-left) 1112 (setq tty-name (pop args-left)
1077 tty-type (pop args-left) 1113 tty-type (pop args-left)
@@ -1133,6 +1169,13 @@ The following commands are accepted by the client:
1133 ;; Unknown command. 1169 ;; Unknown command.
1134 (arg (error "Unknown command: %s" arg)))) 1170 (arg (error "Unknown command: %s" arg))))
1135 1171
1172 ;; If both -no-wait and -tty are given with file or sexp
1173 ;; arguments, use an existing frame.
1174 (and nowait
1175 (not (eq tty-name 'window-system))
1176 (or files commands)
1177 (setq use-current-frame t))
1178
1136 (setq frame 1179 (setq frame
1137 (cond 1180 (cond
1138 ((and use-current-frame 1181 ((and use-current-frame
@@ -1182,12 +1225,17 @@ The following commands are accepted by the client:
1182 ;; including code that needs to wait. 1225 ;; including code that needs to wait.
1183 (with-local-quit 1226 (with-local-quit
1184 (condition-case err 1227 (condition-case err
1185 (let* ((buffers 1228 (let ((buffers (server-visit-files files proc nowait)))
1186 (when files
1187 (server-visit-files files proc nowait))))
1188
1189 (mapc 'funcall (nreverse commands)) 1229 (mapc 'funcall (nreverse commands))
1190 1230
1231 ;; If we were told only to open a new client, obey
1232 ;; `initial-buffer-choice' if it specifies a file.
1233 (unless (or files commands)
1234 (if (stringp initial-buffer-choice)
1235 (find-file initial-buffer-choice)
1236 (switch-to-buffer (get-buffer-create "*scratch*")
1237 'norecord)))
1238
1191 ;; Delete the client if necessary. 1239 ;; Delete the client if necessary.
1192 (cond 1240 (cond
1193 (nowait 1241 (nowait