summaryrefslogtreecommitdiff
path: root/gnu/tests/ssh.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/tests/ssh.scm')
-rw-r--r--gnu/tests/ssh.scm109
1 files changed, 76 insertions, 33 deletions
diff --git a/gnu/tests/ssh.scm b/gnu/tests/ssh.scm
index 456476e69d..c1582c4737 100644
--- a/gnu/tests/ssh.scm
+++ b/gnu/tests/ssh.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -54,10 +55,12 @@
(services (cons service
(operating-system-user-services %base-os)))))
-(define (run-ssh-test name ssh-service pid-file)
+(define* (run-ssh-test name ssh-service pid-file #:key (sftp? #f))
"Run a test of an OS running SSH-SERVICE, which writes its PID to PID-FILE.
SSH-SERVICE must be configured to listen on port 22 and to allow for root and
-empty-password logins."
+empty-password logins.
+
+When SFTP? is true, run an SFTP server test."
(mlet* %store-monad ((os -> (marionette-operating-system
(os-with-service ssh-service)
#:imported-modules '((gnu services herd)
@@ -80,7 +83,8 @@ empty-password logins."
(ice-9 match)
(ssh session)
(ssh auth)
- (ssh channel))
+ (ssh channel)
+ (ssh sftp))
(define marionette
;; Enable TCP forwarding of the guest's port 22.
@@ -101,6 +105,47 @@ empty-password logins."
(error "file didn't show up" ,file))))
marionette))
+ (define (make-session-for-test)
+ "Make a session with predefined parameters for a test."
+ (make-session #:user "root"
+ #:port 2222
+ #:host "localhost"
+ #:log-verbosity 'protocol))
+
+ (define (call-with-connected-session proc)
+ "Call the one-argument procedure PROC with a freshly created and
+connected SSH session object, return the result of the procedure call. The
+session is disconnected when the PROC is finished."
+ (let ((session (make-session-for-test)))
+ (dynamic-wind
+ (lambda ()
+ (let ((result (connect! session)))
+ (unless (equal? result 'ok)
+ (error "Could not connect to a server"
+ session result))))
+ (lambda () (proc session))
+ (lambda () (disconnect! session)))))
+
+ (define (call-with-connected-session/auth proc)
+ "Make an authenticated session. We should be able to connect as
+root with an empty password."
+ (call-with-connected-session
+ (lambda (session)
+ ;; Try the simple authentication methods. Dropbear requires
+ ;; 'none' when there are no passwords, whereas OpenSSH accepts
+ ;; 'password' with an empty password.
+ (let loop ((methods (list (cut userauth-password! <> "")
+ (cut userauth-none! <>))))
+ (match methods
+ (()
+ (error "all the authentication methods failed"))
+ ((auth rest ...)
+ (match (pk 'auth (auth session))
+ ('success
+ (proc session))
+ ('denied
+ (loop rest)))))))))
+
(mkdir #$output)
(chdir #$output)
@@ -131,37 +176,34 @@ empty-password logins."
(current-services))))
marionette))
- ;; Connect to the guest over SSH. We should be able to connect as
- ;; "root" with an empty password. Make sure we can run a shell
+ ;; Connect to the guest over SSH. Make sure we can run a shell
;; command there.
- (test-equal "connect"
+ (test-equal "shell command"
+ 'hello
+ (call-with-connected-session/auth
+ (lambda (session)
+ ;; FIXME: 'get-server-public-key' segfaults.
+ ;; (get-server-public-key session)
+ (let ((channel (make-channel session)))
+ (channel-open-session channel)
+ (channel-request-exec channel "echo hello > /root/witness")
+ (and (zero? (channel-get-exit-status channel))
+ (wait-for-file "/root/witness"))))))
+
+ ;; Connect to the guest over SFTP. Make sure we can write and
+ ;; read a file there.
+ (unless #$sftp?
+ (test-skip 1))
+ (test-equal "SFTP file writing and reading"
'hello
- (let* ((session (make-session #:user "root"
- #:port 2222 #:host "localhost"
- #:log-verbosity 'protocol)))
- (match (connect! session)
- ('ok
- ;; Try the simple authentication methods. Dropbear
- ;; requires 'none' when there are no passwords, whereas
- ;; OpenSSH accepts 'password' with an empty password.
- (let loop ((methods (list (cut userauth-password! <> "")
- (cut userauth-none! <>))))
- (match methods
- (()
- (error "all the authentication methods failed"))
- ((auth rest ...)
- (match (pk 'auth (auth session))
- ('success
- ;; FIXME: 'get-server-public-key' segfaults.
- ;; (get-server-public-key session)
- (let ((channel (make-channel session)))
- (channel-open-session channel)
- (channel-request-exec channel
- "echo hello > /root/witness")
- (and (zero? (channel-get-exit-status channel))
- (wait-for-file "/root/witness"))))
- ('denied
- (loop rest))))))))))
+ (call-with-connected-session/auth
+ (lambda (session)
+ (let ((sftp-session (make-sftp-session session))
+ (witness "/root/sftp-witness"))
+ (call-with-remote-output-file sftp-session witness
+ (cut display "hello" <>))
+ (call-with-remote-input-file sftp-session witness
+ read)))))
(test-end)
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
@@ -179,7 +221,8 @@ empty-password logins."
(openssh-configuration
(permit-root-login #t)
(allow-empty-passwords? #t)))
- "/var/run/sshd.pid"))))
+ "/var/run/sshd.pid"
+ #:sftp? #t))))
(define %test-dropbear
(system-test