From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id YHk9NNP8pWKyKAAAbAwnHQ (envelope-from ) for ; Sun, 12 Jun 2022 16:48:51 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id 6AUVNNP8pWLRZQEAauVa8A (envelope-from ) for ; Sun, 12 Jun 2022 16:48:51 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 009F521FFE for ; Sun, 12 Jun 2022 16:48:50 +0200 (CEST) Received: from localhost ([::1]:38916 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o0OtV-0003wV-Jn for larch@yhetil.org; Sun, 12 Jun 2022 10:48:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51888) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o0Osv-0003wI-HP for emacs-orgmode@gnu.org; Sun, 12 Jun 2022 10:48:13 -0400 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]:38873) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o0Ost-0004sR-3M for emacs-orgmode@gnu.org; Sun, 12 Jun 2022 10:48:13 -0400 Received: by mail-pl1-x632.google.com with SMTP id n18so3085493plg.5 for ; Sun, 12 Jun 2022 07:48:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:user-agent:message-id:mime-version; bh=UfsOTGpH2sMVNSG7V6ZCUTedpwCBGOi8gRzA5c04MGo=; b=GrN9EdrRk6KTvCqWbV0KLZI8364Y+lJuurmH42GB20YDbwsIn/9u6aaEVDnMwHpsrN Uo7V/7pR+4QBlRx6B5nC4NxXj6E/vtmfJAokRGzCrTPyp5H75g15yuLQP+B3Ix7N95S5 ysKsriVwUxy+VHFDZ4hpEqo5M0pTQUJl+qZmjHK7PfmeGjUk9Lpud7p+2mHyzHLTsTUw ugfS04a8FN3tGgmX9dRKBq+wF3clGvmupq5sx12M2D0z3QZAzy/5HIk/llmb97OhO4QH NtUj58EuD00dC/MhvUEEUInhTJ3rgmtR8SK0IPPRwMOa/1lBP9+aWdijBf2z7a2aUiQC aYfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:user-agent:message-id :mime-version; bh=UfsOTGpH2sMVNSG7V6ZCUTedpwCBGOi8gRzA5c04MGo=; b=7fu2mJzztWl32gNAsvpfb/Uqs0sBSmhYy13VGS+XqUJ6gmP/2OhedQblI9YYfYWUKH lKBueeimRv9nC5dpJoFAUvg3QTVHhw9lKuESjW5pf8FKJDNYxIJC8rViY2gvFFUymBnD vD7SaE+qwRBqiVNG+bsh/X/THdq/XVcxGfdBzubN0XYmVV0HK48dYDArVS0uIbpYZ5Sb ysItjrQepexC+6+A4XusFMMlZ3+mgdx/x558AYMl3HJRRDFZ854Q4+V5eQ5UDFDqL5Oy FG7W1Ri9m/XgdOfmh4SLNfm9tsH1sfYPqc4OkHg4otEwB1pm2stuOlAU16YLPSwlkLN2 mv0Q== X-Gm-Message-State: AOAM531+/sZnkTwsGuIS22hF50COqdxh/CSjzfRsc/mwS9M/75uOMtnk 28ZY+JzLy065ewD2kqRTLc5227X3RMg= X-Google-Smtp-Source: ABdhPJzhoF6jqrRLwQ7qFEkeWaduXgtCMqNWeISfAio7vOEqGNuWYB4BrLpKjNns8iixr1oN098Isw== X-Received: by 2002:a17:90b:33cd:b0:1e6:8a38:f0b9 with SMTP id lk13-20020a17090b33cd00b001e68a38f0b9mr10772035pjb.64.1655045286459; Sun, 12 Jun 2022 07:48:06 -0700 (PDT) Received: from localhost (2403-580e-91f7--124.ip6.aussiebb.net. [2403:580e:91f7::124]) by smtp.gmail.com with ESMTPSA id t17-20020a170902b21100b0015e8d4eb1d5sm3175045plr.31.2022.06.12.07.48.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Jun 2022 07:48:06 -0700 (PDT) From: Timothy To: emacs-orgmode@gnu.org Subject: [PATCH] New remote resource download policy Date: Sun, 12 Jun 2022 22:43:07 +0800 User-agent: mu4e 1.6.11; emacs 28.0.92 Message-ID: <87mteiq6ou.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2607:f8b0:4864:20::632; envelope-from=tecosaur@gmail.com; helo=mail-pl1-x632.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1655045331; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=UfsOTGpH2sMVNSG7V6ZCUTedpwCBGOi8gRzA5c04MGo=; b=eIMx+PtBDcNab2pSMvXyXcwzK8b2J1HnufNvloJ/d/b362u2ypSQpQS/lORC1W3VB9qB2T mTTk1VXLzayHFJwVn+HhkXniiCT13PhVk8pgOfs059jwlHc/VkmUUrUyKHS+YIj5CjdMzP /euYGhFG/6vH4trl171k32wL7PFeNT3MFTxj+RUjPtCHQraks9JcH1plm5PfVIMxKZPnaF MHYPwoNcyQDYQ8k37ZPYtUMMtSksvoO19Gys0CTKIWdMV9P7ENjf9R1zWcq7dHBctLSFQ5 7RnEQW/S2Z+hN82B7RaKzef/G9jj22SuSYT9lhkCZqvAzqW9+jWS3y+TkQzNGQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1655045331; a=rsa-sha256; cv=none; b=dPmOEhjVdCz1toH8rgKQMNg2IrApkyiipdWg80FJVW3fPuYO/97DVcT7xpyGY4UkXBGgtp 80QrSjrLxcFTkSt2qTTyyVCvwdS/2buvn/LRWdWDuPz9Ef/98FMmMikuvZQGGxP+qrJvCY wkErUuzbVoCvw3PjSF4lVYZ4fQ7LBDEGYG16Kc/85cIMzmLedxLOvNT6PwE1CxcOVCaj7c FkwbqJQtVeSY7x2ALU58Ow2LO+Oj5/m+nCGjoLhchvnVE94I3Lm320fMoeO9klEhOTeyhM E1NYHdI2QMlAYgX0AbBZn4z6CYlcy9Dw+ofZ78oepYqQc2ELcj/z7BCJPm5jZw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=GrN9EdrR; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -8.99 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=GrN9EdrR; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 009F521FFE X-Spam-Score: -8.99 X-Migadu-Scanner: scn0.migadu.com X-TUID: dThhZ5HkLieS --=-=-= Content-Type: multipart/alternative; boundary="==-=-=" --==-=-= Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi All, As was raised in the `#+include: URL' thread (), currently Org will automatically download files without confirmation in various circumstances. This patch introduces two variables to control Org=E2=80=99s attitude towar= ds downloading files, and hooks them into the relevant parts of the codebase. When prompting for downloading, this uses an approach borrowed from file lo= cal variable confirmation. All the best, Timothy --==-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable =

Hi All,

As was raised in the #+include: URL thread (https://list.orgmode.org/877d5sd7yu.fsf@gmail.com), curren= tly Org will automatically download files without confirmation in various circumstances.

This patch introduces two variables to control Org=E2=80=99s attitude towar= ds downloading files, and hooks them into the relevant parts of the codebase.

When prompting for downloading, this uses an approach borrowed from file lo= cal variable confirmation.

All the best,
Timothy

--==-=-=-- --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-org-Add-setting-for-remote-file-download-policy.patch >From 4f3437a2386e2ffdf37c99d476fa5ea3481b8d3c Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 12 Jun 2022 22:37:42 +0800 Subject: [PATCH] org: Add setting for remote file download policy * lisp/org.el (org-download-remote-resources, org-safe-remote-resources): Two new customisations to configure the policy for downloading remote resources. (org--should-fetch-remote-resource-p, org--safe-remote-resource-p, org--confirm-resource-safe, org-download-remote-resources): Introduce the new function `org--should-fetch-remote-resource-p' for internal use determining whether a remote resource should be downloaded according to the download policy. This function makes use of two helper functions, `org--safe-remote-resource-p' and `org--confirm-resource-safe'. (org-file-contents): Apply `org--safe-remote-resource-p' to file downloading. * lisp/org-persist.el (org-persist-write): Apply `org--safe-remote-resource-p' to url downloading. * lisp/org-attach.el (org-attach-attach): Apply `org--safe-remote-resource-p' to url downloading. --- lisp/org-attach.el | 6 ++- lisp/org-persist.el | 5 +- lisp/org.el | 115 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/lisp/org-attach.el b/lisp/org-attach.el index 5ee2b84b2..6f21ad716 100644 --- a/lisp/org-attach.el +++ b/lisp/org-attach.el @@ -525,7 +525,11 @@ (defun org-attach-attach (file &optional visit-dir method) ((eq method 'cp) (copy-file file attach-file)) ((eq method 'ln) (add-name-to-file file attach-file)) ((eq method 'lns) (make-symbolic-link file attach-file)) - ((eq method 'url) (url-copy-file file attach-file))) + ((eq method 'url) + (if (or (not noninteractive) (org--should-fetch-remote-resource-p file)) + (url-copy-file file attach-file) + (error "The remote resource %S is considered unsafe, and will not be downloaded." + file)))) (run-hook-with-args 'org-attach-after-change-hook attach-dir) (org-attach-tag) (cond ((eq org-attach-store-link-p 'attached) diff --git a/lisp/org-persist.el b/lisp/org-persist.el index 068f58cec..f49abe8cd 100644 --- a/lisp/org-persist.el +++ b/lisp/org-persist.el @@ -655,7 +655,10 @@ (defun org-persist-write:url (c collection) (format "%s-%s.%s" persist-file (md5 path) ext)))) (unless (file-exists-p (file-name-directory file-copy)) (make-directory (file-name-directory file-copy) t)) - (url-copy-file path file-copy 'overwrite) + (if (org--should-fetch-remote-resource-p path) + (url-copy-file path file-copy 'overwrite) + (error "The remote resource %S is considered unsafe, and will not be downloaded." + path)) (format "%s-%s.%s" persist-file (md5 path) ext))))) (defun org-persist-write:index (container _) diff --git a/lisp/org.el b/lisp/org.el index 8e7aadde5..3a8acaa8f 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1352,6 +1352,32 @@ (defcustom org-file-apps (string :tag "Command") (function :tag "Function"))))) +(defcustom org-download-remote-resources 'prompt + "The policy applied to requests to obtain remote resources. + +This affects keywords like #+setupfile and #+incude on export, +`org-persist-write:url',and `org-attach-attach' in +non-interactive Emacs sessions. + +This recognises four possible values: +- t, remote resources should always be downloaded. +- prompt, you will be prompted to download resources nt considered safe. +- safe, only resources considered safe will be downloaded. +- nil, never download remote resources. + +A resource is considered safe if it matches one of the patterns +in `org-safe-remote-resources'." + :group 'org + :type '(choice (const :tag "Always download remote resources" t) + (const :tag "Prompt before downloading an unsafe resource" prompt) + (const :tag "Only download resources considered safe" safe) + (const :tag "Never download any resources" nil))) + +(defcustom org-safe-remote-resources nil + "A list of regexp patterns matching safe URIs." + :group 'org + :type '(list regexp)) + (defcustom org-open-non-existing-files nil "Non-nil means `org-open-file' opens non-existing files. @@ -4466,21 +4492,25 @@ (defun org-file-contents (file &optional noerror nocache) (cond (cache) (is-url - (with-current-buffer (url-retrieve-synchronously file) - (goto-char (point-min)) - ;; Move point to after the url-retrieve header. - (search-forward "\n\n" nil :move) - ;; Search for the success code only in the url-retrieve header. - (if (save-excursion - (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) - ;; Update the cache `org--file-cache' and return contents. - (puthash file - (buffer-substring-no-properties (point) (point-max)) - org--file-cache) - (funcall (if noerror #'message #'user-error) - "Unable to fetch file from %S" - file) - nil))) + (if (org--should-fetch-remote-resource-p file) + (with-current-buffer (url-retrieve-synchronously file) + (goto-char (point-min)) + ;; Move point to after the url-retrieve header. + (search-forward "\n\n" nil :move) + ;; Search for the success code only in the url-retrieve header. + (if (save-excursion + (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) + ;; Update the cache `org--file-cache' and return contents. + (puthash file + (buffer-substring-no-properties (point) (point-max)) + org--file-cache) + (funcall (if noerror #'message #'user-error) + "Unable to fetch file from %S" + file) + nil)) + (funcall (if noerror #'message #'user-error) + "The remote resource %S is considered unsafe, and will not be downloaded." + file))) (t (with-temp-buffer (condition-case nil @@ -4493,6 +4523,61 @@ (defun org-file-contents (file &optional noerror nocache) file) nil))))))) +(defun org--should-fetch-remote-resource-p (uri) + "Return non-nil if the URI should be fetched." + (or (eq org-download-remote-resources t) + (org--safe-remote-resource-p uri) + (and (eq org-download-remote-resources 'prompt) + (org--confirm-resource-safe uri)))) + +(defun org--safe-remote-resource-p (uri) + "Return non-nil if URI is considered safe. +This checks every pattern in `org-safe-remote-resources', and +returns non-nil if any of them match." + (let (match-p (uri-patterns org-safe-remote-resources)) + (while (and (not match-p) uri-patterns) + (setq match-p (string-match-p (car uri-patterns) uri) + uri-patterns (cdr uri-patterns))) + match-p)) + +(defun org--confirm-resource-safe (uri) + "Ask the user if URI should be considered safe, returning non-nil if so." + (unless noninteractive + (let ((buf (get-buffer-create "*Org Remote Resource*"))) + ;; Set up the contents of the *Local Variables* buffer. + (with-current-buffer buf + (erase-buffer) + (insert "An org-mode document would like to download " + (propertize uri 'face '(:inherit org-link :weight normal)) + ", which is not considered safe.\n\n" + "Do you want to download this? You can type\n " + (propertize "!" 'face 'success) + " to download this resource, and permanantly mark it as safe.\n " + (propertize "y" 'face 'warning) + " to download this resource, just this once.\n " + (propertize "n" 'face 'error) + " to skip this resource.\n") + (setq-local cursor-type nil) + (set-buffer-modified-p nil) + (goto-char (point-min))) + ;; Display the buffer and read a choice. + (save-window-excursion + (pop-to-buffer buf) + (let* ((exit-chars '(?y ?n ?! ?\s)) + (prompt (format "Please type y, n, or !%s: " + (if (< (line-number-at-pos (point-max)) + (window-body-height)) + "" + ", or C-v/M-v to scroll"))) + char) + (setq char (read-char-choice prompt exit-chars)) + (when (= char ?!) + (customize-push-and-save + 'org-safe-remote-resources + (regexp-quote uri))) + (prog1 (memq char '(?! ?\s ?y)) + (quit-window t))))))) + (defun org-extract-log-state-settings (x) "Extract the log state setting from a TODO keyword string. This will extract info from a string like \"WAIT(w@/!)\"." -- 2.36.1 --=-=-=--