My main problem right now is that in gnus.el i got several mail sources set in a manner like:
(setq mail-sources
'((pop :server "server.org"
:port 995
:user "user#server.org"
:password "pAssWorD")
I don't want to store passwords in a plain text file like that. What i want is:
Store passwords for Gnus mail sources in a separate file with strict permissions and encrypted using gpg.
When using Emacs enter passphrase once and have these passwords automatically used when fetching mail.
What is the most idiomatic/efficient way to do that?
I'm also interested in any general ideas about password management in Emacs, be it just storing them somewhere in an encrypted files or having them managed for particular Emacs packages.
Emacs version: 24.0.97
I couldn't make .authinfo file work with POP3, so i followed the Keeping your secrets secret blogpost (thanks to phils for the link). I created three files in my load-path. secrets.el:
(load-library "secrets.el.gpg")
(provide 'secrets)
secrets.el.gpg:
(setq password-alist
'((:mbox1 . "pAsSwOrD")
(:mbox2 . "correct horse battery staple")
(:mbox3 . "qwfpgj")))
mail.el:
(defun load-mail-passwords ()
"Load passwords for mail sources from secrets.el.gpg"
(require 'secrets)
(setq mail-sources
`((pop :server "pop.server.org"
:port 995
:user "user#server.org"
:password ,(rest (assoc :mbox1 password-alist)))
))
(setq smtpmail-auth-credentials `(("smtp.server.org" "465" "user#server.org"
,(rest (assoc :mbox1 password-alist))))))
(add-hook 'gnus-load-hook 'load-mail-passwords)
And i also put (load "~/.emacs.d/mail.el") to my init file, because for some reason my ~/.emacs.d/ folder in load-path wasn't being loaded automatically.
The backtick is like apostrophe (quote), but it allows some expressions to be unquoted using comma. The (rest (assoc :keyword alist)) combination is to get the second part of the dotted pair in association list.
Related
I have this in my emacs .init file:
(load "~/.emacs.d/.ercpass")
(global-set-key "\C-cef" (lambda () (interactive)
(erc :server "irc.freenode.net" :port "6667"
:nick "nick")))
What line do I need to add to "~/.emacs.d/.ercpass" so that my password is automatically identified?
Thanks,
Oliver
#lawlist already pointed years ago to the resource https://www.emacswiki.org/emacs/ErcNickserv#toc4 which contains the answer the OP needed. But I go about this in a different way, so I thought that I would list various options for future users.
In all cases, you want, in your init file:
(setq erc-prompt-for-nickserv-password nil)
OP's method:
Have in your init file:
(load "~/.ercpass")
(setq erc-nickserv-passwords
`(freenode (<nick> . ,freenode-password)))
and create a file ~/.ercpass with:
(setq freenode-password <password>)
A very similar method, keeping everything in the init file:
(setq erc-nickserv-passwords
'(freenode (<nick> . <password>)))
An alternative method with authinfo:
You can have the login info in your ~/.authinfo.gpg file.
Add a line with:
machine irc.freenode.net login <nick> password <password>
This is the method I use because it identifies the nickname faster and the password is protected.
Note that for any of these methods, you can have as many nicknames and passwords on as many networks as you want. Simply add more lines as appropriate (and of course, replace freenode by whatever network you are actually interested in).
I'm trying to connect to a PostgreSQL DB thru Emacs using the sql-mode.
I start Emacs, command M-x sql-postgres and it prompts for User,
Database and Server but not for the password. An empty buffer opens
and whatever I write, I get:
the Password for user james:
psql: FATAL: password authentication failed for user "james"
I can login using psql, though. I'm running GNU Emacs 24.4.1 in Linux Antergos, PostgreSQL is 9.3.5.
Thanks..
In case someone else comes looking I solved this by calling send-invisible and typing in my password, after the sql-postgres command completed. Emacs version 24.5.1.
Initiate postgres connection
At blank screen M-x send-invisible
Type password.
Profit.
Kevin's answer provides an interactive solution.
Otherwise you must use a non-interactive method of authenticating (such as a .pgpass file).
My original (and incorrect) suggestion was to enable the "password" option at M-x customize-option RET sql-postgres-login-params RET.
The sql-*-login-params variables (and associated customize widgets) are generalised across all database types; but not all of those options are applicable to all of the databases.
Where applicable, passwords are read by Emacs and then used in the command line. psql doesn't allow the password to be supplied as part of the command, however, so there's no way for Emacs to use this approach here. This is why the password option is disabled for the postgres login params.
Here is a simpler solution exploiting the fact that you can pass a password in the connection string. For example:
(setq sql-connection-alist
'((my-db (sql-product 'postgres)
(sql-database "postgresql://user:pass#host/database"))))
Then disable all postgres login params except for database.
As a bonus here is my config for using the unix password manager pass which I recommend:
(defun my-pass (key)
(string-trim-right
(shell-command-to-string (concat "pass " key))))
(setq sql-connection-alist
'((db (sql-product 'postgres)
(sql-database (concat "postgresql://user:"
(my-pass "db/user")
"#host/database")))))
I find it simplest to explicitly define the connections within the sql-connection-alist. Once the connections are defined, you can connect using sql-connect. A particular connection can be selected using up/down/previous/next. Avoid storing passwords by reading them in during connection with read-passwd.
;; Remove all default login parameters
(setq sql-postgres-login-params nil)
;; define your connections
(setq sql-connection-alist
'((primary-db (sql-product 'postgres)
(sql-database (concat "postgresql://"
"username" ;; replace with your username
":" (read-passwd "Enter password: ")
"#host" ;; replace with your host
":port" ;; replace with your port
"/database" ;; replace with your database
)))
(secondary-db (sql-product 'postgres)
(sql-database (concat "postgresql://"
"username:"
(read-passwd "Enter password: ")
"#host"
":port"
"/database")))))
First, clear out the sql-postgres-login-params variable. There's no sense creating defaults since they'll be defined in the connections list. If sql-postgres-login-params is non-nil, you'll be prompted when connecting. This is annoying and defeats the purpose of explicitly defining connections.
Second, use "Connection URIs" to define a connection.
These have the form:
postgresql://[user[:password]#][netloc][:port][,...][/dbname][?param1=value1&...]
In the example above, we are creating connections called primary-db and secondary-db for postgres. The connections use only the "database" parameter. The database is a connection URI made by concatenating strings into the appropriate form. See how read-passwd prevents us from storing the password? Replace each parameter with your own. Pay attention to the various syntax elements for host (#), port (:), and database (/). If you don't want to store a particular parameter, I suppose you could use read-string just as with read-passwd, but that's basically reinventing the tooling which uses sql-postgres-login-params.
See C-h i d g (elisp) Association Lists for more about alists.
I solved this temporarily by creating a .pgpass file where I stored my connection credentials. I am not comfortable with that and would like a solution that requires inputing the password at login.
I have this problem also. If you go to the empty buffer & hit enter, do you get a password prompt there? I do, and when typing in the password the mode works just fine.
works for me setting the PGPASSWORD environment variable, e.g. (setenv "PGPASSWORD" "whatever your password is")
One can monkey-patch sql-comint-postgres to use the PGPASSWORD environment variable with the standard connection list fields:
(defun sql-comint-postgres (product options &optional buf-name)
"Create comint buffer and connect to Postgres."
;; username and password are ignored. Mark Stosberg suggests to add
;; the database at the end. Jason Beegan suggests using --pset and
;; pager=off instead of \\o|cat. The later was the solution by
;; Gregor Zych. Jason's suggestion is the default value for
;; sql-postgres-options.
(let ((params
(append
(if (not (= 0 sql-port))
(list "-p" (number-to-string sql-port)))
(if (not (string= "" sql-user))
(list "-U" sql-user))
(if (not (string= "" sql-server))
(list "-h" sql-server))
options
(if (not (string= "" sql-database))
(list sql-database))))
(process-environment
(nconc
(list (format "PGPASSWORD=%s" sql-password))
process-environment)))
(message (prin1-to-string process-environment))
(sql-comint product params buf-name)))
I have two user accounts on my Mac.
I would like to open the same text file on both accounts with emacs.
I can put the file in a directory where both users have read and write access.
When I add text to one process I would like it to show up in the other buffer and vice verse automatically.
I have tried combinations of auto-save-mode and auto-revert-mode to try to auto save an auto revert, but that does not seem to work quite right.
Is there some normal way to do this with emacs?
I think you should learn about collaborative editing. There is a page on the emacs wiki about it link
Not a full answer. Just some thoughts. Nevertheless, this is formulated as answer since I want to supplement it with elisp code and maybe refine it later on. This is not possible with comments.
I assume that you are actually working with two emacsen at the two accounts. Furthermore, I assume that the problem with auto-revert-buffer is the timing, i.e. that auto-revert-buffer works with polling and not on demand.
If you want to update on demand you have to setup both emacsen as servers and give them the possibility to communicate bidirectionally.
You could do something like that via emacsclient with the option -e over ssh.
If you are in a private network you can also let the emacs servers directly communicate.
I had no luck with emacsclient and the default server-setup as sockets since emacsclient checks the ownership for the sockets. (Note: First, I used emacsclient for testing. Afterwards, I verified that the communication also works between two emacsen.)
But the code below shows a possibility with the emacs server communicating over tcp/ip.
Both emacsen should put their server files into the same directory. Naturally, you need to name the servers differently. Then you can communicate via the command server-eval-at.
Note, this stuff is security relevant and should only be used on a secure private network.
The below elisp code is not like a package but more like a collection of useful commands.
Nevertheless, on one server you can use the commands as they are. On the other one you need small modifications. E.g.: changing server-name.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Communication over tcp:
(setq server-use-tcp t)
(setq server-auth-dir "/tmp/eserv/")
(if (file-directory-p server-auth-dir)
(progn
(unless (file-accessible-directory-p server-auth-dir)
(error "Cannot access server-auth-dir"))
(unless (file-writable-p server-auth-dir)
(error "Cannot write to server-auth-dir"))
)
(mkdir server-auth-dir t)
(unless (shell-command (concat "chgrp users \"" server-auth-dir "\""))
(error "Cannot change group of server file directory to users."))
(chmod server-auth-dir (file-modes-symbolic-to-number "g+xr" (file-modes server-auth-dir))))
;;
(defadvice server-ensure-safe-dir (around unsafe activate)
"We are on a private network and do not fear intrusion.
Furthermore, the directory is already set up.
This is a SECURITY HOLE if you do not know what you are doing!"
(let ((dir (ad-get-arg 0)))
(unless (file-exists-p dir)
(error "File %s does not exist." dir))
(unless (file-directory-p dir)
(error "File %s is not a directory." dir))))
(server-force-delete)
(server-start)
(defvar server-file nil
"Full name of server file.")
(setq server-file (concat server-auth-dir server-name))
(unless (shell-command (concat "chgrp users \"" server-file "\""))
(error "Cannot change group of server file to users."))
(chmod server-file (file-modes-symbolic-to-number "g+r" (file-modes server-file)))
Afterwards, I discovered that communication of two emacsen is also possible via sockets. One only needs to get around the security and to soft-link the server sockets in the auth-directories.
So, you have the choice.
When entering IRC with M-erc, Emacs remembers the last used server name and port. You can accept, hitting enter, or change those parameters.
As for the user name, it defaults to system user name and not to the last used one.
How can I have Emacs to suggest the last user name or a predefined one?
For completeness I propose an answer allowing to store both your account ID and password.
Solution 1: Store account in the Emacs init file
Append/add to your Emacs init file:
(setq erc-nick "my-nice-id")
(setq erc-password "my-nice-pw")
Note: You will get an y/n query to accept default password (i.e. my-nice-pw).
Solution 2: Store account in an external storage file
To avoid sharing your sensitive data when/if you share your Emacs init file or to store your data in a more secure directory, you can store your account data in an external file. Append/add to your Emacs init file:
(let ((acc (read-lines "~/.my-erc-account")))
(setq erc-nick (car acc))
(setq erc-password (nth 1 acc)))
where ".my-erc-account" contains:
"my-nice-id"
"my-nice-pw"
Place and name this file as it is more convenient for you and adjust the read-lines argument accordingly.
You might want to look at:
M-x customize-group RET erc RET
(n.b. ERC has a lot of customisation options, so you'll probably find some interesting things in there...)
I created a very simple Elisp function to simply the process of ERC login: http://wenshanren.org/?p=314
/multi used to work for me, now it's gone and I'm frustrated.
What I want to do is, in my dream world:
/myuser#remotehost:sudo:anotheruser:/some/path/to/file
...and have ido-mode work.
The key thing here is that 'myuser', 'remotehost' and 'anotheruser' are all very ad-hoc, I use a huge array of remote hosts, often with different users and sudo-ing to a wide range of different users.
What do I need to add and how can I test it without reloading emacs over and over?
As of this commit, TRAMP supports ad-hoc multiple hops again.
Roughly speaking, you use it like this:
/ssh:transituser#remotehost|sudo:user#remotehost:/some/file
I haven't got it to work reliably with ido-mode yet, which is a shame, but it's a lot better than nothing! :-)
The following code may help:
(defun find-file-as-root ()
"Find a file as root."
(interactive)
(let* ((parsed (when (tramp-tramp-file-p default-directory)
(coerce (tramp-dissect-file-name default-directory)
'list)))
(default-directory
(if parsed
(apply 'tramp-make-tramp-file-name
(append '("sudo" "root") (cddr parsed)))
(tramp-make-tramp-file-name "sudo" "root" "localhost"
default-directory))))
(call-interactively 'find-file)))
I had it in my .emacs file, and it seems to come from here: http://atomized.org/2011/01/toggle-between-root-non-root-in-emacs-with-tramp/
I haven't used it extensively but it seems like that is a step in the right direction.