1 ;;; sasl.el --- basic functions for SASL
3 ;; Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
5 ;; Author: Kenichi OKADA <okada@opaopa.org>
6 ;; Keywords: SMTP, SASL, RFC2222
8 ;; This file is part of FLIM (Faithful Library about Internet Message).
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
30 (defun sasl-cram-md5 (username passphrase challenge)
31 (let ((secure-word (copy-sequence passphrase)))
32 (setq secure-word (unwind-protect
33 (hmac-md5 challenge secure-word)
34 (fillarray secure-word 0))
35 secure-word (unwind-protect
36 (encode-hex-string secure-word)
37 (fillarray secure-word 0))
38 secure-word (unwind-protect
39 (concat username " " secure-word)
40 (fillarray secure-word 0)))))
43 (defun sasl-plain (authorid authenid passphrase)
44 (concat authorid "\0" authenid "\0" passphrase))
47 (defvar sasl-scram-md5-client-security-info
48 (scram-make-security-info nil t 0))
50 (defun sasl-scram-md5-client-msg-1 (authenticate-id &optional authorize-id)
51 (scram-md5-make-client-msg-1 authenticate-id authorize-id))
53 (defun sasl-scram-md5-client-msg-2 (server-msg-1 client-msg-1 passphrase)
55 (scram-md5-make-client-msg-2
56 sasl-scram-md5-client-security-info
57 (scram-md5-make-client-proof
59 (scram-md5-make-client-key
60 (scram-md5-make-salted-pass
63 (scram-md5-parse-server-msg-1 server-msg-1)))))
64 (scram-md5-make-shared-key
67 sasl-scram-md5-client-security-info
68 (scram-md5-make-client-verifier client-key))))))
70 (defun sasl-scram-md5-authenticate-server (server-msg-1
74 (scram-md5-authenticate-server
78 sasl-scram-md5-client-security-info
80 (scram-md5-parse-server-msg-1 server-msg-1))
81 (scram-md5-make-salted-pass
84 (scram-md5-parse-server-msg-1 server-msg-1)))))
87 (defun sasl-number-base36 (num len)
92 (concat (sasl-number-base36 (/ num 36) (1- len))
93 (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210"
96 (defvar sasl-unique-id-char nil)
98 (defun sasl-unique-id ()
99 ;; Don't use microseconds from (current-time), they may be unsupported.
100 ;; Instead we use this randomly inited counter.
101 (setq sasl-unique-id-char
102 (% (1+ (or sasl-unique-id-char (logand (random t) (1- (lsh 1 20)))))
103 ;; (current-time) returns 16-bit ints,
104 ;; and 2^16*25 just fits into 4 digits i base 36.
106 (let ((tm (static-if (fboundp 'current-time)
108 (let* ((cts (split-string (current-time-string) "[ :]"))
109 (m (cdr (assoc (nth 1 cts)
110 '(("Jan" . "01") ("Feb" . "02")
111 ("Mar" . "03") ("Apr" . "04")
112 ("May" . "05") ("Jun" . "06")
113 ("Jul" . "07") ("Aug" . "08")
114 ("Sep" . "09") ("Oct" . "10")
115 ("Nov" . "11") ("Dec" . "12"))))))
116 (list (string-to-int (concat (nth 6 cts) m
117 (substring (nth 2 cts) 0 1)))
118 (string-to-int (concat (substring (nth 2 cts) 1)
119 (nth 4 cts) (nth 5 cts)
122 (if (memq system-type '(ms-dos emx vax-vms))
123 (let ((user (downcase (user-login-name))))
124 (while (string-match "[^a-z0-9_]" user)
125 (aset user (match-beginning 0) ?_))
127 (sasl-number-base36 (user-uid) -1))
128 (sasl-number-base36 (+ (car tm)
129 (lsh (% sasl-unique-id-char 25) 16)) 4)
130 (sasl-number-base36 (+ (nth 1 tm)
131 (lsh (/ sasl-unique-id-char 25) 16)) 4)
132 ;; Append the name of the message interface, because while the
133 ;; generated ID is unique to this newsreader, other newsreaders
134 ;; might otherwise generate the same ID via another algorithm.
139 ;;; sasl.el ends here