170 lines
5.3 KiB
Scheme
170 lines
5.3 KiB
Scheme
;;; netrc.scm -- parse authentication information contained in ~/.netrc
|
|
;;
|
|
;; $Id: netrc.scm,v 1.2 2001/11/15 11:12:24 mainzelm Exp $
|
|
;;
|
|
;; Please send suggestions and bug reports to <emarsden@mail.dotcom.fr>
|
|
|
|
|
|
|
|
;;; Overview =====================================================
|
|
;;
|
|
;; On Unix systems the ~/.netrc file (in the user's home directory)
|
|
;; may contain information allowing automatic login to remote hosts.
|
|
;; The format of the file is defined in the ftp(1) manual page.
|
|
;; Example lines are
|
|
;;
|
|
;; machine ondine.cict.fr login marsden password secret
|
|
;; default login anonymous password user@site
|
|
;;
|
|
;; The ~/.netrc file should be protected by appropriate permissions,
|
|
;; and (like /usr/bin/ftp) this library will refuse to read the file if
|
|
;; it is badly protected.
|
|
|
|
|
|
;;; Entry points =======================================================
|
|
;;
|
|
;; (user-mail-address) -> string
|
|
;; Calculate the user's email address, as per the Emacs function of
|
|
;; the same name. Will take into account the environment variable
|
|
;; REPLYTO, if set.
|
|
;;
|
|
;; (netrc:default-login) -> string | #f
|
|
;; Return the default login specified by the ~/.netrc file, or #f.
|
|
;;
|
|
;; (netrc:default-password) -> string | #f
|
|
;; Return the default password specified by the ~/.netrc file, or #f.
|
|
;;
|
|
;; (netrc:lookup machine) -> string x string x string
|
|
;; Return the login,password,account information for MACHINE
|
|
;; specified by the ~/.netrc file.
|
|
|
|
|
|
;;; Related work ========================================================
|
|
;;
|
|
;; * Graham Barr has written a similar library for Perl, called
|
|
;; Netrc.pm
|
|
;;
|
|
;; * ange-ftp.el (transparent remote file access for Emacs) parses the
|
|
;; user's ~/.netrc file
|
|
|
|
|
|
;;; Portability ==================================================
|
|
;;
|
|
;; getenv, scsh file primitives, regexp code, format
|
|
;; define-record
|
|
|
|
|
|
(define (user-mail-address)
|
|
(or (getenv "REPLYTO")
|
|
(string-append (user-login-name) "@" (system-fqdn))))
|
|
|
|
(define (netrc:default-login) *netrc:default-login*)
|
|
(define (netrc:default-password) *netrc:default-password*)
|
|
|
|
;;: string -> string x string x string
|
|
(define (netrc:lookup machine)
|
|
(let ((record
|
|
(find-suchthat (lambda (rec)
|
|
(and (equal? (netrc:machine rec) machine)
|
|
(list (netrc:login rec)
|
|
(netrc:password rec)
|
|
(netrc:account rec))))
|
|
*netrc*)))
|
|
(values (netrc:login record)
|
|
(netrc:password record)
|
|
(netrc:account record))))
|
|
|
|
(define (netrc:lookup-password machine)
|
|
(receive (login password account)
|
|
(netrc:lookup machine)
|
|
password))
|
|
|
|
(define (netrc:lookup-login machine)
|
|
(receive (login password account)
|
|
(netrc:lookup machine)
|
|
login))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; nothing exported below
|
|
|
|
(define-record netrc
|
|
machine
|
|
login
|
|
password
|
|
account)
|
|
|
|
(define *netrc* '())
|
|
(define *netrc:default-login* "anonymous")
|
|
(define *netrc:default-password* (user-mail-address))
|
|
(define *netrc:file* (resolve-file-name "~/.netrc"))
|
|
|
|
|
|
(define (netrc:parse)
|
|
(netrc:check-permissions)
|
|
(set! *netrc* '())
|
|
(let ((fd (open-input-file *netrc:file*)))
|
|
(for-each-line netrc:parse-line fd)))
|
|
|
|
;; raise error if any permissions are set for group or others.
|
|
(define (netrc:check-permissions)
|
|
(let ((perms (- (file-mode *netrc:file*) 32768)))
|
|
(if (positive? (bitwise-and #b000111111 perms))
|
|
(error "Not parsing ~/.netrc file; dangerous permissions"))))
|
|
|
|
(define (netrc:try-match target line)
|
|
(let ((match (string-match target line)))
|
|
(and match
|
|
(match:substring match 1))))
|
|
|
|
(define (netrc:parse-default line)
|
|
(let ((login (netrc:try-match "login[ \t]+([^ \t]+)" line))
|
|
(password (netrc:try-match "password[ \t]+([^ \t]+)" line)))
|
|
(if login
|
|
(set! *netrc:default-login* login))
|
|
(if password
|
|
(set! *netrc:default-password* password))))
|
|
|
|
(define (netrc:parse-line line)
|
|
(cond ((string-match "default" line)
|
|
(netrc:parse-default line))
|
|
(else
|
|
(let ((machine (netrc:try-match "machine[ \t]+([^ \t]+)" line))
|
|
(login (netrc:try-match "login[ \t]+([^ \t]+)" line))
|
|
(password (netrc:try-match "password[ \t]+([^ \t]+)" line))
|
|
(account (netrc:try-match "account[ \t]+([^ \t]+)" line)))
|
|
(if (or machine login password account)
|
|
(netrc:add machine login password account))))))
|
|
|
|
(define (netrc:add machine login password account)
|
|
(set! *netrc* (cons (make-netrc machine login password account) *netrc*)))
|
|
|
|
;; for testing
|
|
(define (netrc:dump)
|
|
(format #t "~%--- Dumping ~~/.netrc contents ---")
|
|
(for-each (lambda (rec)
|
|
(format #t "~% machine ~a login ~a password ~a account ~a"
|
|
(netrc:machine rec)
|
|
(netrc:login rec)
|
|
(netrc:password rec)
|
|
(netrc:account rec)))
|
|
*netrc*)
|
|
(format #t "~%--- End of ~~/.netrc contents ---~%"))
|
|
|
|
(define (for-each-line proc fd)
|
|
(let ((line (read-line fd)))
|
|
(and (not (eof-object? line))
|
|
(proc line)
|
|
(for-each-line proc fd))))
|
|
|
|
(define (find-suchthat pred l)
|
|
(if (null? l) #f
|
|
(or (pred (car l))
|
|
(find-suchthat pred (cdr l)))))
|
|
|
|
; do we need this here?
|
|
;(netrc:parse)
|
|
|
|
;; EOF
|