123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- ;;; auth.scm -- API for SSH user authentication.
- ;; Copyright (C) 2013, 2014 Artyom V. Poptsov <poptsov.artyom@gmail.com>
- ;;
- ;; This file is a part of Guile-SSH.
- ;;
- ;; Guile-SSH is free software: you can redistribute it and/or
- ;; modify it under the terms of the GNU General Public License as
- ;; published by the Free Software Foundation, either version 3 of the
- ;; License, or (at your option) any later version.
- ;;
- ;; Guile-SSH is distributed in the hope that it will be useful, but
- ;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ;; General Public License for more details.
- ;;
- ;; You should have received a copy of the GNU General Public License
- ;; along with Guile-SSH. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;; This module contains API that is used for SSH user authentication.
- ;;
- ;; These methods are exported:
- ;;
- ;; userauth-public-key!
- ;; userauth-public-key/auto!
- ;; userauth-public-key/try
- ;; userauth-agent!
- ;; userauth-password!
- ;; userauth-none!
- ;; userauth-get-list
- ;;; Code:
- (define-module (ssh auth)
- #:use-module (ice-9 popen)
- #:use-module (ice-9 rdelim)
- #:use-module (ice-9 regex)
- #:use-module (ssh log)
- #:use-module (ssh session)
- #:export (userauth-public-key!
- userauth-public-key/auto!
- userauth-public-key/try
- userauth-agent!
- userauth-password!
- userauth-none!
- userauth-get-list
- openssh-agent-start
- openssh-agent-info
- openssh-agent-setenv))
- ;;;
- (define %ssh-auth-sock-regexp
- (make-regexp "SSH_AUTH_SOCK=(.*); export SSH_AUTH_SOCK;"))
- (define %ssh-agent-pid-regexp
- (make-regexp "SSH_AGENT_PID=(.*); export SSH_AGENT_PID;"))
- (define (openssh-agent-start)
- "Start an OpenSSH agent. Return a list with SSH agent information."
- (let ((p (open-input-pipe "ssh-agent -s")))
- (let ((ssh-auth-sock-data (read-line p))
- (ssh-agent-pid-data (read-line p)))
- `((SSH_AUTH_SOCK
- . ,(let ((match (regexp-exec %ssh-auth-sock-regexp
- ssh-auth-sock-data)))
- (match:substring match 1)))
- (SSH_AGENT_PID
- . ,(let ((match (regexp-exec %ssh-agent-pid-regexp
- ssh-agent-pid-data)))
- (match:substring match 1)))))))
- ;;;
- (define %ssh-agent-dir-regexp
- (make-regexp "ssh-[0-9A-Za-z]+$"))
- (define* (openssh-agent-info #:optional (user (getenv "USER")))
- "Get OpenSSH agent information for a given USER as a list."
- (define (owned-by-user? file-name uid)
- (= (stat:uid (stat file-name)) uid))
- (define (user->uid user)
- (passwd:uid (getpwnam user)))
- (define (readdir-3rd dir-name)
- (let ((stream (opendir dir-name)))
- (readdir stream)
- (readdir stream)
- (let ((file (readdir stream)))
- (closedir stream)
- file)))
- (define (agent-socket->pid agent-socket)
- (cdr (string-split agent-socket #\.)))
- (let ((dir (opendir "/tmp"))
- (uid (user->uid user)))
- (let loop ((entry (readdir dir))
- (info '()))
- (if (eof-object? entry)
- info
- (let ((file-name (string-append "/tmp/" entry)))
- (if (and (regexp-exec %ssh-agent-dir-regexp entry)
- (owned-by-user? file-name uid))
- (let ((agent-socket (readdir-3rd file-name)))
- (loop (readdir dir)
- (cons `(,(string-append file-name "/" agent-socket)
- . ,(agent-socket->pid agent-socket))
- info)))
- (loop (readdir dir) info)))))))
- ;;;
- (define (openssh-agent-setenv)
- "Setup openssh agent environment variables for the current user."
- (setenv "SSH_AUTH_SOCK" (caar (openssh-agent-info))))
- ;;;
- (load-extension "libguile-ssh" "init_auth_func")
- ;;; auth.scm ends here.
|