Browse Source

Implement encryption for MobileOrg

Carsten Dominik 15 years ago
parent
commit
f84a8a8651
4 changed files with 121 additions and 17 deletions
  1. 2 0
      doc/ChangeLog
  2. 8 5
      doc/org.texi
  3. 11 0
      lisp/ChangeLog
  4. 100 12
      lisp/org-mobile.el

+ 2 - 0
doc/ChangeLog

@@ -1,6 +1,8 @@
 2010-04-01  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org.texi (The export dispatcher): Renamed from ASCII export.
+	(Setting up the staging area): Document the availability of
+	encryption for MobileOrg.
 
 2010-03-29  Carsten Dominik  <carsten.dominik@gmail.com>
 

+ 8 - 5
doc/org.texi

@@ -12335,11 +12335,14 @@ in-buffer settings, but it will understand the logistics of todo state
 
 Org-mode has commands to prepare a directory with files for @i{MobileOrg},
 and to read captured notes from there.  If Emacs can directly write to the
-WebDAV directory accessed by @i{MobileOrg}, just point to this directory
-using the variable @code{org-mobile-directory}.  Using the @file{tramp}
-method, @code{org-mobile-directory} may point to a remote directory
-accessible through, for example, 
-@file{ssh/scp}:
+WebDAV directory@footnote{If you are using a public server, you might prefer
+to encrypt the files on the server.  This can be done with Org-mode 6.35 and
+MobileOrg 1.2.  On the Emacs side, configure the variables
+@code{org-mobile-use-encryption} and @code{org-mobile-encryption-password}.}
+accessed by @i{MobileOrg}, just point to this directory using the variable
+@code{org-mobile-directory}.  Using the @file{tramp} method,
+@code{org-mobile-directory} may point to a remote directory accessible
+through, for example, @file{ssh/scp}:
 
 @smallexample
 (setq org-mobile-directory "/scpc:user@@remote.host:org/webdav/")

+ 11 - 0
lisp/ChangeLog

@@ -1,5 +1,16 @@
 2010-04-01  Carsten Dominik  <carsten.dominik@gmail.com>
 
+	* org-mobile.el (org-mobile-use-encryption)
+	(org-mobile-encryption-tempfile, org-mobile-encryption-password):
+	New options.
+	(org-mobile-check-setup): CHeck the encryption setup.
+	(org-mobile-copy-agenda-files, org-mobile-sumo-agenda-command)
+	(org-mobile-create-sumo-agenda): Use encryption code.
+	(org-mobile-encrypt-and-move): New function.
+	(org-mobile-encrypt-file, org-mobile-decrypt-file): New
+	functions.
+	(org-mobile-move-capture): Decrypt the capture file.
+
 	* org.el (org-entities): Require the new file.
 	(org-export-latex-default-packages-alist): New variable.
 	(org-complete): Use new entity code for completion.

+ 100 - 12
lisp/org-mobile.el

@@ -65,6 +65,34 @@ org-agenda-text-search-extra-files
   :group 'org-mobile
   :type 'directory)
 
+(defcustom org-mobile-use-encryption nil
+  "Non-nil means keep only encrypted files on the webdav server.
+Encryption uses AES-256, with a password given in
+`org-mobile-encryption-password'.
+When nil, plain files are kept on the server.
+Turning on encryption requires to set the same password in the MobileOrg
+application."
+  :group 'org-mobile
+  :type 'boolean)
+
+(defcustom org-mobile-encryption-tempfile "~/orgtmpcrypt"
+  "File that is being used as a temporary file for encryption.
+This must be local file on your local machine (not on the webdav server).
+You might want to put this file into a directory where only you have access."
+  :group 'org-mobile
+  :type 'directory)
+
+(defcustom org-mobile-encryption-password ""
+  "Password for encrypting files uploaded to the server.
+This is a single password which is used for AES-256 encryption.  The same
+password must also be set in the MobileOrg application.  All Org files,
+including mobileorg.org will be encrypted using this password.
+Note that, whe Org runs the encryption commands, the password could
+be visible on your system with the `ps' command.  So this method is only
+intended to keep the files secure on the server, not on your own machine."
+  :group 'org-mobile
+  :type '(string :tag "Password"))
+
 (defcustom org-mobile-inbox-for-pull "~/org/from-mobile.org"
   "The file where captured notes and flags will be appended to.
 During the execution of `org-mobile-pull', the file
@@ -320,7 +348,16 @@ agenda view showing the flagged items."
 	       (file-exists-p
 		(file-name-directory org-mobile-inbox-for-pull)))
     (error
-     "Variable `org-mobile-inbox-for-pull' must point to a file in an existing directory")))
+     "Variable `org-mobile-inbox-for-pull' must point to a file in an existing directory"))
+  (when org-mobile-use-encryption
+    (unless (string-match "\\S-" org-mobile-encryption-password)
+      (error
+       "To use encryption, you must set `org-mobile-encryption-password'"))
+    (unless (file-writable-p org-mobile-encryption-tempfile)
+      (error "Cannot write to entryption tempfile %s"
+	     org-mobile-encryption-tempfile))
+    (unless (executable-find "openssl")
+      (error "openssl is needed to encrypt files."))))
 
 (defun org-mobile-create-index-file ()
   "Write the index file in the WebDAV directory."
@@ -400,7 +437,9 @@ agenda view showing the flagged items."
 	      target-dir (file-name-directory target-path))
 	(unless (file-directory-p target-dir)
 	  (make-directory target-dir 'parents))
-	(copy-file file target-path 'ok-if-exists)
+	(if org-mobile-use-encryption
+	    (org-mobile-encrypt-and-move file target-path)
+	  (copy-file file target-path 'ok-if-exists))
 	(setq check (shell-command-to-string
 		     (concat org-mobile-checksum-binary " "
 			     (shell-quote-argument (expand-file-name file)))))
@@ -467,6 +506,11 @@ The table of checksums is written to the file mobile-checksums."
        ((memq (nth 2 e) '(todo-tree tags-tree occur-tree))
 	;; These are trees, not really agenda commands
 	)
+       ((and (memq (nth 2 e) '(todo tags tags-todo))
+	     (or (null (nth 3 e))
+		 (not (string-match "\\S-" (nth 3 e)))))
+	;; These would be interactive because the match string is empty
+	)
        ((memq (nth 2 e) '(agenda alltodo todo tags tags-todo))
 	;; a normal command
 	(setq key (car e) desc (nth 1 e) type (nth 2 e) match (nth 3 e)
@@ -570,26 +614,66 @@ The table of checksums is written to the file mobile-checksums."
   (interactive)
   (let* ((file (expand-file-name "agendas.org"
 				 org-mobile-directory))
+	 (file1 (if org-mobile-use-encryption
+		    org-mobile-encryption-tempfile
+		  file))
 	 (sumo (org-mobile-sumo-agenda-command))
 	 (org-agenda-custom-commands
-	  (list (append sumo (list (list file)))))
+	  (list (append sumo (list (list file1)))))
 	 (org-mobile-creating-agendas t))
-    (unless (file-writable-p file)
-      (error "Cannot write to file %s" file))
+    (unless (file-writable-p file1)
+      (error "Cannot write to file %s" file1))
     (when sumo
-      (org-store-agenda-views))))
+      (org-store-agenda-views))
+    (when org-mobile-use-encryption
+      (org-mobile-encrypt-file file1 file)
+      (delete-file file1))))
+
+(defun org-mobile-encrypt-and-move (infile outfile)
+  "Encrypt INFILE locally to INFILE_enc, then move it to OUTFILE.
+We do this in two steps so that remote paths will work, even if the
+encryption program does not understand them."
+  (let ((encfile (concat infile "_enc")))
+    (org-mobile-encrypt-file infile encfile)
+    (when outfile
+      (copy-file encfile outfile 'ok-if-exists)
+      (delete-file encfile))))
+
+(defun org-mobile-encrypt-file (infile outfile)
+  "Encrypt INFILE to OUTFILE, using `org-mobile-encryption-password'."
+  (shell-command
+   (format "openssl enc -aes-256-cbc -salt -pass %s -in %s -out %s"
+	   (shell-quote-argument (concat "pass:" org-mobile-encryption-password))
+	   (shell-quote-argument (expand-file-name infile))
+	   (shell-quote-argument (expand-file-name outfile)))))
+
+(defun org-mobile-decrypt-file (infile outfile)
+  "Decrypt INFILE to OUTFILE, using `org-mobile-encryption-password'."
+  (shell-command
+   (format "openssl enc -d -aes-256-cbc -salt -pass %s -in %s -out %s"
+	   (shell-quote-argument (concat "pass:" org-mobile-encryption-password))
+	   (shell-quote-argument (expand-file-name infile))
+	   (shell-quote-argument (expand-file-name outfile)))))
 
 (defun org-mobile-move-capture ()
   "Move the contents of the capture file to the inbox file.
 Return a marker to the location where the new content has been added.
 If nothing new has been added, return nil."
   (interactive)
-  (let ((inbox-buffer (find-file-noselect org-mobile-inbox-for-pull))
-	(capture-buffer (find-file-noselect
-			 (expand-file-name org-mobile-capture-file
-					   org-mobile-directory)))
-	(insertion-point (make-marker))
-	not-empty content)
+  (let* ((encfile nil)
+	 (capture-file (expand-file-name org-mobile-capture-file
+					 org-mobile-directory))
+	 (inbox-buffer (find-file-noselect org-mobile-inbox-for-pull))
+	 (capture-buffer
+	  (if (not org-mobile-use-encryption)
+	      (find-file-noselect capture-file)
+	    (delete-file org-mobile-encryption-tempfile)
+	    (setq encfile (concat org-mobile-encryption-tempfile "_enc"))
+	    (copy-file capture-file encfile)
+	    (org-mobile-decrypt-file encfile org-mobile-encryption-tempfile)
+	    (find-file-noselect org-mobile-encryption-tempfile)))
+	 (insertion-point (make-marker))
+	 not-empty content)
     (with-current-buffer capture-buffer
       (setq content (buffer-string))
       (setq not-empty (string-match "\\S-" content))
@@ -606,9 +690,13 @@ If nothing new has been added, return nil."
 	(save-buffer)
 	(org-mobile-update-checksum-for-capture-file (buffer-string))))
     (kill-buffer capture-buffer)
+    (when org-mobile-use-encryption
+      (org-mobile-encrypt-and-move org-mobile-encryption-tempfile
+				   capture-file))
     (if not-empty insertion-point)))
 
 (defun org-mobile-update-checksum-for-capture-file (buffer-string)
+  "Find the checksum line and modify it to match BUFFER-STRING."
   (let* ((file (expand-file-name "checksums.dat" org-mobile-directory))
 	 (buffer (find-file-noselect file)))
     (when buffer