diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/filenotify.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 13 | ||||
| -rw-r--r-- | lisp/progmodes/perl-mode.el | 8 | ||||
| -rw-r--r-- | lisp/ses.el | 2 | ||||
| -rw-r--r-- | lisp/url/url-auth.el | 403 |
5 files changed, 315 insertions, 113 deletions
diff --git a/lisp/filenotify.el b/lisp/filenotify.el index dbf19cf2f20..8bbe348f332 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el | |||
| @@ -422,7 +422,7 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'." | |||
| 422 | ;; (This may be the desired behaviour.) | 422 | ;; (This may be the desired behaviour.) |
| 423 | ;; * Watching a file in a already watched directory | 423 | ;; * Watching a file in a already watched directory |
| 424 | ;; If the file is created and *then* a watch is added to that file, the | 424 | ;; If the file is created and *then* a watch is added to that file, the |
| 425 | ;; watch might receive events which occured prior to it being created, | 425 | ;; watch might receive events which occurred prior to it being created, |
| 426 | ;; due to the way events are propagated during idle time. Note: This | 426 | ;; due to the way events are propagated during idle time. Note: This |
| 427 | ;; may be perfectly acceptable. | 427 | ;; may be perfectly acceptable. |
| 428 | 428 | ||
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index aed42a85076..3c720c05610 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -1713,7 +1713,7 @@ This performs fontification according to `js--class-styles'." | |||
| 1713 | (not (any ?\] ?\\)) | 1713 | (not (any ?\] ?\\)) |
| 1714 | (and "\\" not-newline))) | 1714 | (and "\\" not-newline))) |
| 1715 | "]"))) | 1715 | "]"))) |
| 1716 | (group "/")) | 1716 | (group (zero-or-one "/"))) |
| 1717 | "Regular expression matching a JavaScript regexp literal.") | 1717 | "Regular expression matching a JavaScript regexp literal.") |
| 1718 | 1718 | ||
| 1719 | (defun js-syntax-propertize-regexp (end) | 1719 | (defun js-syntax-propertize-regexp (end) |
| @@ -1721,12 +1721,13 @@ This performs fontification according to `js--class-styles'." | |||
| 1721 | (when (eq (nth 3 ppss) ?/) | 1721 | (when (eq (nth 3 ppss) ?/) |
| 1722 | ;; A /.../ regexp. | 1722 | ;; A /.../ regexp. |
| 1723 | (goto-char (nth 8 ppss)) | 1723 | (goto-char (nth 8 ppss)) |
| 1724 | (when (and (looking-at js--syntax-propertize-regexp-regexp) | 1724 | (when (looking-at js--syntax-propertize-regexp-regexp) |
| 1725 | ;; Don't touch text after END. | 1725 | ;; Don't touch text after END. |
| 1726 | (<= (match-end 1) end)) | 1726 | (when (> end (match-end 1)) |
| 1727 | (put-text-property (match-beginning 1) (match-end 1) | 1727 | (setq end (match-end 1))) |
| 1728 | (put-text-property (match-beginning 1) end | ||
| 1728 | 'syntax-table (string-to-syntax "\"/")) | 1729 | 'syntax-table (string-to-syntax "\"/")) |
| 1729 | (goto-char (match-end 0)))))) | 1730 | (goto-char end))))) |
| 1730 | 1731 | ||
| 1731 | (defun js-syntax-propertize (start end) | 1732 | (defun js-syntax-propertize (start end) |
| 1732 | ;; JavaScript allows immediate regular expression objects, written /.../. | 1733 | ;; JavaScript allows immediate regular expression objects, written /.../. |
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index a516f07e72f..b75f32ee200 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el | |||
| @@ -255,9 +255,11 @@ | |||
| 255 | ;; format statements | 255 | ;; format statements |
| 256 | ("^[ \t]*format.*=[ \t]*\\(\n\\)" | 256 | ("^[ \t]*format.*=[ \t]*\\(\n\\)" |
| 257 | (1 (prog1 "\"" (perl-syntax-propertize-special-constructs end)))) | 257 | (1 (prog1 "\"" (perl-syntax-propertize-special-constructs end)))) |
| 258 | ;; Funny things in `sub' arg-specs like `sub myfun ($)' or `sub ($)'. | 258 | ;; Propertize perl prototype chars `$%&*;+@\[]' as punctuation |
| 259 | ;; Be careful not to match "sub { (...) ... }". | 259 | ;; in `sub' arg-specs like `sub myfun ($)' and `sub ($)'. But |
| 260 | ("\\<sub\\(?:[\s\t\n]+\\(?:\\sw\\|\\s_\\)+\\)?[\s\t\n]*(\\([^)]+\\))" | 260 | ;; don't match subroutine signatures like `sub add ($a, $b)', or |
| 261 | ;; anonymous subs like "sub { (...) ... }". | ||
| 262 | ("\\<sub\\(?:[\s\t\n]+\\(?:\\sw\\|\\s_\\)+\\)?[\s\t\n]*(\\([][$%&*;+@\\]+\\))" | ||
| 261 | (1 ".")) | 263 | (1 ".")) |
| 262 | ;; Turn __DATA__ trailer into a comment. | 264 | ;; Turn __DATA__ trailer into a comment. |
| 263 | ("^\\(_\\)_\\(?:DATA\\|END\\)__[ \t]*\\(?:\\(\n\\)#.-\\*-.*perl.*-\\*-\\|\n.*\\)" | 265 | ("^\\(_\\)_\\(?:DATA\\|END\\)__[ \t]*\\(?:\\(\n\\)#.-\\*-.*perl.*-\\*-\\|\n.*\\)" |
diff --git a/lisp/ses.el b/lisp/ses.el index 50507132346..66fc0c5ebdf 100644 --- a/lisp/ses.el +++ b/lisp/ses.el | |||
| @@ -2276,7 +2276,7 @@ print area if NONARROW is nil." | |||
| 2276 | "Recalculate and reprint the current cell or range. | 2276 | "Recalculate and reprint the current cell or range. |
| 2277 | 2277 | ||
| 2278 | If SES--CURCELL is non nil use it as current cell or range | 2278 | If SES--CURCELL is non nil use it as current cell or range |
| 2279 | without any check, otherwise fnuction (ses-check-curcell 'range) | 2279 | without any check, otherwise function (ses-check-curcell 'range) |
| 2280 | is called. | 2280 | is called. |
| 2281 | 2281 | ||
| 2282 | For an individual cell, shows the error if the formula or printer | 2282 | For an individual cell, shows the error if the formula or printer |
diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el index 7b6cdd53790..2885d4e12e2 100644 --- a/lisp/url/url-auth.el +++ b/lisp/url/url-auth.el | |||
| @@ -131,8 +131,8 @@ instead of the filename inheritance method." | |||
| 131 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 131 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 132 | ;;; Digest authorization code | 132 | ;;; Digest authorization code |
| 133 | ;;; ------------------------ | 133 | ;;; ------------------------ |
| 134 | ;;; This implements the DIGEST authorization type. See the internet draft | 134 | ;;; This implements the DIGEST authorization type. See RFC 2617 |
| 135 | ;;; ftp://ds.internic.net/internet-drafts/draft-ietf-http-digest-aa-01.txt | 135 | ;;; https://www.ietf.org/rfc/rfc2617.txt |
| 136 | ;;; for the complete documentation on this type. | 136 | ;;; for the complete documentation on this type. |
| 137 | ;;; | 137 | ;;; |
| 138 | ;;; This is very secure | 138 | ;;; This is very secure |
| @@ -143,107 +143,306 @@ Its value is an assoc list of assoc lists. The first assoc list is | |||
| 143 | keyed by the server name. The cdr of this is an assoc list based | 143 | keyed by the server name. The cdr of this is an assoc list based |
| 144 | on the \"directory\" specified by the url we are looking up.") | 144 | on the \"directory\" specified by the url we are looking up.") |
| 145 | 145 | ||
| 146 | (defsubst url-digest-auth-colonjoin (&rest args) | ||
| 147 | "Concatenate ARGS as strings with colon as a separator." | ||
| 148 | (mapconcat 'identity args ":")) | ||
| 149 | |||
| 150 | (defsubst url-digest-auth-kd (data secret) | ||
| 151 | "Apply digest algorithm to DATA using SECRET and return the result." | ||
| 152 | (md5 (url-digest-auth-colonjoin secret data))) | ||
| 153 | |||
| 154 | (defsubst url-digest-auth-make-ha1 (user realm password) | ||
| 155 | "Compute checksum out of strings USER, REALM, and PASSWORD." | ||
| 156 | (md5 (url-digest-auth-colonjoin user realm password))) | ||
| 157 | |||
| 158 | (defsubst url-digest-auth-make-ha2 (method digest-uri) | ||
| 159 | "Compute checksum out of strings METHOD and DIGEST-URI." | ||
| 160 | (md5 (url-digest-auth-colonjoin method digest-uri))) | ||
| 161 | |||
| 162 | (defsubst url-digest-auth-make-request-digest (ha1 ha2 nonce) | ||
| 163 | "Construct the request-digest from hash strings HA1, HA2, and NONCE. | ||
| 164 | This is the value that server receives as a proof that user knows | ||
| 165 | a password." | ||
| 166 | (url-digest-auth-kd (url-digest-auth-colonjoin nonce ha2) ha1)) | ||
| 167 | |||
| 168 | (defsubst url-digest-auth-make-request-digest-qop (qop ha1 ha2 nonce nc cnonce) | ||
| 169 | "Construct the request-digest with qop. | ||
| 170 | QOP describes the \"quality of protection\" and algorithm to use. | ||
| 171 | All of the strings QOP, HA1, HA2, NONCE, NC, and CNONCE are | ||
| 172 | combined into a single hash value that proves to a server the | ||
| 173 | user knows a password. It's worth noting that HA2 already | ||
| 174 | depends on value of QOP." | ||
| 175 | (url-digest-auth-kd (url-digest-auth-colonjoin | ||
| 176 | nonce nc cnonce qop ha2) ha1)) | ||
| 177 | |||
| 178 | (defsubst url-digest-auth-directory-id (url realm) | ||
| 179 | "Make an identifier for selecting a key in key cache. | ||
| 180 | The identifier is made either from URL or REALM. It represents a | ||
| 181 | protection space within a server so that one server can have | ||
| 182 | multiple authorizations." | ||
| 183 | (or realm (or (url-file-directory (url-filename url)) "/"))) | ||
| 184 | |||
| 185 | (defsubst url-digest-auth-server-id (url) | ||
| 186 | "Make an identifier for selecting a server in key cache. | ||
| 187 | The identifier is made from URL's host and port. Together with | ||
| 188 | `url-digest-auth-directory-id' these identify a single key in the | ||
| 189 | key cache `url-digest-auth-storage'." | ||
| 190 | (format "%s:%d" (url-host url) (url-port url))) | ||
| 191 | |||
| 192 | (defun url-digest-auth-make-cnonce () | ||
| 193 | "Compute a new unique client nonce value." | ||
| 194 | (base64-encode-string | ||
| 195 | (apply 'format "%016x%04x%04x%05x%05x" (random) (current-time)) t)) | ||
| 196 | |||
| 197 | (defun url-digest-auth-nonce-count (nonce) | ||
| 198 | "The number requests sent to server with the given NONCE. | ||
| 199 | This count includes the request we're preparing here. | ||
| 200 | |||
| 201 | Currently, this is not implemented and will always return 1. | ||
| 202 | |||
| 203 | Value returned is in string format with leading zeroes, such as | ||
| 204 | \"00000001\"." | ||
| 205 | (format "%08x" 1)) | ||
| 206 | |||
| 207 | (defun url-digest-auth-name-value-string (pairs) | ||
| 208 | "Concatenate name-value pairs in association list PAIRS. | ||
| 209 | |||
| 210 | Output is formatted as \"name1=\\\"value1\\\", name2=\\\"value2\\\", ...\"" | ||
| 211 | (mapconcat (lambda (pair) | ||
| 212 | (format "%s=\"%s\"" | ||
| 213 | (symbol-name (car pair)) | ||
| 214 | (cdr pair))) | ||
| 215 | pairs ", ")) | ||
| 216 | |||
| 217 | (defun url-digest-auth-source-creds (url) | ||
| 218 | "Find credentials for URL object from the Emacs auth-source. | ||
| 219 | Return value is a plist that has `:user' and `:secret' properties | ||
| 220 | if credentials were found. Otherwise nil." | ||
| 221 | (let ((server (url-digest-auth-server-id url)) | ||
| 222 | (type (url-type url))) | ||
| 223 | (list :user (url-do-auth-source-search server type :user) | ||
| 224 | :secret (url-do-auth-source-search server type :secret)))) | ||
| 225 | |||
| 226 | (defun url-digest-prompt-creds (url realm &optional creds) | ||
| 227 | "Prompt credentials for URL and REALM, defaulting to CREDS. | ||
| 228 | CREDS is a plist that may have properties `:user' and `:secret'." | ||
| 229 | ;; Set explicitly in case creds were nil. This makes the second | ||
| 230 | ;; plist-put modify the same plist. | ||
| 231 | (setq creds | ||
| 232 | (plist-put creds :user | ||
| 233 | (read-string (url-auth-user-prompt url realm) | ||
| 234 | (or (plist-get creds :user) | ||
| 235 | (user-real-login-name))))) | ||
| 236 | (plist-put creds :secret | ||
| 237 | (read-passwd "Password: " nil (plist-get creds :secret)))) | ||
| 238 | |||
| 239 | (defun url-digest-auth-directory-id-assoc (dirkey keylist) | ||
| 240 | "Find the best match for DIRKEY in key alist KEYLIST. | ||
| 241 | |||
| 242 | The string DIRKEY should be obtained using | ||
| 243 | `url-digest-auth-directory-id'. The key list to search through | ||
| 244 | is the alist KEYLIST where car of each element may match DIRKEY. | ||
| 245 | If DIRKEY represents a realm, the list is searched only for an | ||
| 246 | exact match. For directory names, an ancestor is sufficient for | ||
| 247 | a match." | ||
| 248 | (or | ||
| 249 | ;; Check exact match first. | ||
| 250 | (assoc dirkey keylist) | ||
| 251 | ;; No exact match found. Continue to look for partial match if | ||
| 252 | ;; dirkey is not a realm. | ||
| 253 | (and (string-match "/" dirkey) | ||
| 254 | (let (match) | ||
| 255 | (while (and (null match) keylist) | ||
| 256 | (if (or | ||
| 257 | ;; Any realm candidate matches. Why? | ||
| 258 | (not (string-match "/" (caar keylist))) | ||
| 259 | ;; Parent directory matches. | ||
| 260 | (string-prefix-p (caar keylist) dirkey)) | ||
| 261 | (setq match (car keylist)) | ||
| 262 | (setq keylist (cdr keylist)))) | ||
| 263 | match)))) | ||
| 264 | |||
| 265 | (defun url-digest-cached-key (url realm) | ||
| 266 | "Find best match for URL and REALM from `url-digest-auth-storage'. | ||
| 267 | The return value is a list consisting of a realm (or a directory) | ||
| 268 | a user name, and hashed authentication tokens HA1 and HA2. | ||
| 269 | Modifying the contents of the returned list will modify the cache | ||
| 270 | variable `url-digest-auth-storage' itself." | ||
| 271 | (url-digest-auth-directory-id-assoc | ||
| 272 | (url-digest-auth-directory-id url realm) | ||
| 273 | (cdr (assoc (url-digest-auth-server-id url) url-digest-auth-storage)))) | ||
| 274 | |||
| 275 | (defun url-digest-cache-key (key url) | ||
| 276 | "Add key to `url-digest-auth-storage'. | ||
| 277 | KEY has the same format as returned by `url-digest-cached-key'. | ||
| 278 | The key is added to cache hierarchy under server id, deduced from | ||
| 279 | URL." | ||
| 280 | (let ((serverid (url-digest-auth-server-id url))) | ||
| 281 | (push (list serverid key) url-digest-auth-storage))) | ||
| 282 | |||
| 146 | (defun url-digest-auth-create-key (username password realm method uri) | 283 | (defun url-digest-auth-create-key (username password realm method uri) |
| 147 | "Create a key for digest authentication method" | 284 | "Create a key for digest authentication method. |
| 148 | (let* ((info (if (stringp uri) | 285 | The USERNAME and PASSWORD are the credentials for REALM and are |
| 149 | (url-generic-parse-url uri) | 286 | used in making a hashed value named HA1. The HTTP METHOD and URI |
| 150 | uri)) | 287 | makes a second hashed value HA2. These hashes are used in making |
| 151 | (a1 (md5 (concat username ":" realm ":" password))) | 288 | the authentication key that can be stored without saving the |
| 152 | (a2 (md5 (concat method ":" (url-filename info))))) | 289 | password in plain text. The return value is a list (HA1 HA2). |
| 153 | (list a1 a2))) | 290 | |
| 154 | 291 | For backward compatibility, URI is allowed to be a URL cl-struct | |
| 155 | (defun url-digest-auth (url &optional prompt overwrite realm args) | 292 | object." |
| 156 | "Get the username/password for the specified URL. | 293 | (and username password realm |
| 157 | If optional argument PROMPT is non-nil, ask for the username/password | 294 | (list (url-digest-auth-make-ha1 username realm password) |
| 158 | to use for the URL and its descendants. If optional third argument | 295 | (url-digest-auth-make-ha2 method (cond ((stringp uri) uri) |
| 159 | OVERWRITE is non-nil, overwrite the old username/password pair if it | 296 | (t (url-filename uri))))))) |
| 160 | is found in the assoc list. If REALM is specified, use that as the realm | 297 | |
| 161 | instead of hostname:portnum." | 298 | (defun url-digest-auth-build-response (key url realm attrs) |
| 162 | (if args | 299 | "Compute authorization string for the given challenge using KEY. |
| 163 | (let* ((href (if (stringp url) | 300 | |
| 164 | (url-generic-parse-url url) | 301 | The string looks like 'Digest username=\"John\", realm=\"The |
| 165 | url)) | 302 | Realm\", ...' |
| 166 | (server (url-host href)) | 303 | |
| 167 | (type (url-type href)) | 304 | Part of the challenge is already solved in a pre-computed KEY |
| 168 | (port (url-port href)) | 305 | which is list of a realm (or a directory), user name, and hash |
| 169 | (file (url-filename href)) | 306 | tokens HA1 and HA2. |
| 170 | (enable-recursive-minibuffers t) | 307 | |
| 171 | user pass byserv retval data) | 308 | Some fields are filled as is from the given URL, REALM, and |
| 172 | (setq file (cond | 309 | using the contents of alist ATTRS. |
| 173 | (realm realm) | 310 | |
| 174 | ((string-match "/$" file) file) | 311 | ATTRS is expected to contain at least the server's \"nonce\" |
| 175 | (t (url-file-directory file))) | 312 | value. It also might contain the optional \"opaque\" value. |
| 176 | server (format "%s:%d" server port) | 313 | Newer implementations conforming to RFC 2617 should also contain |
| 177 | byserv (cdr-safe (assoc server url-digest-auth-storage))) | 314 | qop (Quality Of Protection) and related attributes. |
| 178 | (cond | 315 | |
| 179 | ((and prompt (not byserv)) | 316 | Restrictions on Quality of Protection scheme: The qop value |
| 180 | (setq user (or | 317 | \"auth-int\" or algorithm any other than \"MD5\" are not |
| 181 | (url-do-auth-source-search server type :user) | 318 | implemented." |
| 182 | (read-string (url-auth-user-prompt url realm) | 319 | |
| 183 | (user-real-login-name))) | 320 | (when key |
| 184 | pass (or | 321 | (let ((user (nth 1 key)) |
| 185 | (url-do-auth-source-search server type :secret) | 322 | (ha1 (nth 2 key)) |
| 186 | (read-passwd "Password: ")) | 323 | (ha2 (nth 3 key)) |
| 187 | url-digest-auth-storage | 324 | (digest-uri (url-filename url)) |
| 188 | (cons (list server | 325 | (qop (cdr-safe (assoc "qop" attrs))) |
| 189 | (cons file | 326 | (nonce (cdr-safe (assoc "nonce" attrs))) |
| 190 | (setq retval | 327 | (opaque (cdr-safe (assoc "opaque" attrs)))) |
| 191 | (cons user | 328 | |
| 192 | (url-digest-auth-create-key | 329 | (concat |
| 193 | user pass realm | 330 | "Digest " |
| 194 | (or url-request-method "GET") | 331 | (url-digest-auth-name-value-string |
| 195 | url))))) | 332 | (append (list (cons 'username user) |
| 196 | url-digest-auth-storage))) | 333 | (cons 'realm realm) |
| 197 | (byserv | 334 | (cons 'nonce nonce) |
| 198 | (setq retval (cdr-safe (assoc file byserv))) | 335 | (cons 'uri digest-uri)) |
| 199 | (if (and (not retval) ; no exact match, check directories | 336 | |
| 200 | (string-match "/" file)) ; not looking for a realm | 337 | (cond |
| 201 | (while (and byserv (not retval)) | 338 | ((null qop) |
| 202 | (setq data (car (car byserv))) | 339 | (list (cons 'response (url-digest-auth-make-request-digest |
| 203 | (if (or (not (string-match "/" data)) | 340 | ha1 ha2 nonce)))) |
| 204 | (and | 341 | ((string= qop "auth") |
| 205 | (>= (length file) (length data)) | 342 | (let ((nc (url-digest-auth-nonce-count nonce)) |
| 206 | (string= data (substring file 0 (length data))))) | 343 | (cnonce (url-digest-auth-make-cnonce))) |
| 207 | (setq retval (cdr (car byserv)))) | 344 | (list (cons 'qop qop) |
| 208 | (setq byserv (cdr byserv)))) | 345 | (cons 'nc nc) |
| 209 | (if overwrite | 346 | (cons 'cnonce cnonce) |
| 210 | (if (and (not retval) prompt) | 347 | (cons 'response |
| 211 | (setq user (or | 348 | (url-digest-auth-make-request-digest-qop |
| 212 | (url-do-auth-source-search server type :user) | 349 | qop ha1 ha2 nonce nc cnonce))))) |
| 213 | (read-string (url-auth-user-prompt url realm) | 350 | (t (message "Quality of protection \"%s\" is not implemented." qop) |
| 214 | (user-real-login-name))) | 351 | nil)) |
| 215 | pass (or | 352 | |
| 216 | (url-do-auth-source-search server type :secret) | 353 | |
| 217 | (read-passwd "Password: ")) | 354 | (if opaque (list (cons 'opaque opaque))))))))) |
| 218 | retval (setq retval | 355 | |
| 219 | (cons user | 356 | (defun url-digest-find-creds (url prompt &optional realm) |
| 220 | (url-digest-auth-create-key | 357 | "Find or ask credentials for URL. |
| 221 | user pass realm | 358 | |
| 222 | (or url-request-method "GET") | 359 | Primary method for finding credentials is from Emacs auth-source. |
| 223 | url))) | 360 | If password isn't found, and PROMPT is non-nil, query credentials |
| 224 | byserv (assoc server url-digest-auth-storage)) | 361 | via minibuffer. Optional REALM may be used when prompting as a |
| 225 | (setcdr byserv | 362 | hint to the user. |
| 226 | (cons (cons file retval) (cdr byserv)))))) | 363 | |
| 227 | (t (setq retval nil))) | 364 | Return value is nil in case either user name or password wasn't |
| 228 | (if retval | 365 | found. Otherwise, it's a plist containing `:user' and `:secret'. |
| 229 | (if (cdr-safe (assoc "opaque" args)) | 366 | Additional `:source' property denotes the origin of the |
| 230 | (let ((nonce (or (cdr-safe (assoc "nonce" args)) "nonegiven")) | 367 | credentials and its value can be either symbol `authsource' or |
| 231 | (opaque (cdr-safe (assoc "opaque" args)))) | 368 | `interactive'." |
| 232 | (format | 369 | (let ((creds (url-digest-auth-source-creds url))) |
| 233 | (concat "Digest username=\"%s\", realm=\"%s\"," | 370 | |
| 234 | "nonce=\"%s\", uri=\"%s\"," | 371 | ;; If credentials weren't found and prompting is allowed, prompt |
| 235 | "response=\"%s\", opaque=\"%s\"") | 372 | ;; the user. |
| 236 | (nth 0 retval) realm nonce (url-filename href) | 373 | (if (and prompt |
| 237 | (md5 (concat (nth 1 retval) ":" nonce ":" | 374 | (or (null creds) |
| 238 | (nth 2 retval))) opaque)) | 375 | (null (plist-get creds :secret)))) |
| 239 | (let ((nonce (or (cdr-safe (assoc "nonce" args)) "nonegiven"))) | 376 | (progn |
| 240 | (format | 377 | (setq creds (url-digest-prompt-creds url realm creds)) |
| 241 | (concat "Digest username=\"%s\", realm=\"%s\"," | 378 | (plist-put creds :source 'interactive)) |
| 242 | "nonce=\"%s\", uri=\"%s\"," | 379 | (plist-put creds :source 'authsource)) |
| 243 | "response=\"%s\"") | 380 | |
| 244 | (nth 0 retval) realm nonce (url-filename href) | 381 | (and (plist-get creds :user) |
| 245 | (md5 (concat (nth 1 retval) ":" nonce ":" | 382 | (plist-get creds :secret) |
| 246 | (nth 2 retval)))))))))) | 383 | creds))) |
| 384 | |||
| 385 | (defun url-digest-find-new-key (url realm prompt) | ||
| 386 | "Find credentials and create a new authorization key for given URL and REALM. | ||
| 387 | |||
| 388 | Return value is the new key, or nil if credentials weren't found. | ||
| 389 | \"New\" in this context means a key that's not yet found in cache | ||
| 390 | variable `url-digest-auth-storage'. You may use `url-digest-cache-key' | ||
| 391 | to put it there. | ||
| 392 | |||
| 393 | This function uses `url-digest-find-creds' to find the | ||
| 394 | credentials. It first looks in auth-source. If not found, and | ||
| 395 | PROMPT is non-nil, user is asked for credentials interactively | ||
| 396 | via minibuffer." | ||
| 397 | (let (creds) | ||
| 398 | (unwind-protect | ||
| 399 | (if (setq creds (url-digest-find-creds url prompt realm)) | ||
| 400 | (cons (url-digest-auth-directory-id url realm) | ||
| 401 | (cons (plist-get creds :user) | ||
| 402 | (url-digest-auth-create-key | ||
| 403 | (plist-get creds :user) | ||
| 404 | (plist-get creds :secret) | ||
| 405 | realm | ||
| 406 | (or url-request-method "GET") | ||
| 407 | (url-filename url))))) | ||
| 408 | (if (and creds | ||
| 409 | ;; Don't clear secret for `authsource' since it will | ||
| 410 | ;; corrupt any future fetches for it. | ||
| 411 | (not (eq (plist-get creds :source) 'authsource))) | ||
| 412 | (clear-string (plist-get creds :secret)))))) | ||
| 413 | |||
| 414 | (defun url-digest-auth (url &optional prompt overwrite realm attrs) | ||
| 415 | "Get the HTTP Digest response string for the specified URL. | ||
| 416 | |||
| 417 | If optional argument PROMPT is non-nil, ask for the username and | ||
| 418 | password to use for the URL and its descendants but only if one | ||
| 419 | cannot be found from cache. Look also in Emacs auth-source. | ||
| 420 | |||
| 421 | If optional third argument OVERWRITE is non-nil, overwrite the | ||
| 422 | old credentials, if they're found in cache, with new ones from | ||
| 423 | user prompt or from Emacs auth-source. | ||
| 424 | |||
| 425 | If REALM is specified, use that instead of the URL descendant | ||
| 426 | method to match cached credentials. | ||
| 427 | |||
| 428 | Alist ATTRS contains additional attributes for the authentication | ||
| 429 | challenge such as nonce and opaque." | ||
| 430 | (if attrs | ||
| 431 | (let* ((href (if (stringp url) (url-generic-parse-url url) url)) | ||
| 432 | (enable-recursive-minibuffers t) | ||
| 433 | (key (url-digest-cached-key href realm))) | ||
| 434 | |||
| 435 | (if (or (null key) overwrite) | ||
| 436 | (let ((newkey (url-digest-find-new-key href realm (cond | ||
| 437 | (key nil) | ||
| 438 | (t prompt))))) | ||
| 439 | (if (and newkey key overwrite) | ||
| 440 | (setcdr key (cdr newkey)) | ||
| 441 | (if (and newkey (null key)) | ||
| 442 | (url-digest-cache-key (setq key newkey) href))))) | ||
| 443 | |||
| 444 | (if key | ||
| 445 | (url-digest-auth-build-response key href realm attrs))))) | ||
| 247 | 446 | ||
| 248 | (defvar url-registered-auth-schemes nil | 447 | (defvar url-registered-auth-schemes nil |
| 249 | "A list of the registered authorization schemes and various and sundry | 448 | "A list of the registered authorization schemes and various and sundry |