File tree Expand file tree Collapse file tree 8 files changed +59
-42
lines changed Expand file tree Collapse file tree 8 files changed +59
-42
lines changed Original file line number Diff line number Diff line change 2
2
" Functions for interacting with an SSH agent. The agent is expected to be
3
3
available on the UNIX domain socket referred to by the SSH_AUTH_SOCK
4
4
environment variable."
5
- (:require [clj-libssh2.error :refer [handle-errors with-timeout]]
5
+ (:require [clj-libssh2.error :as error :refer [handle-errors with-timeout]]
6
+ [clj-libssh2.libssh2 :as libssh2]
6
7
[clj-libssh2.libssh2.agent :as libssh2-agent])
7
8
(:import [com.sun.jna.ptr PointerByReference]))
8
9
32
33
(case ret
33
34
0 (.getValue id)
34
35
1 nil
35
- (throw (Exception. " An unknown error occurred" )))))
36
+ (throw (ex-info " libssh2_agent_get_identity returned a bad value."
37
+ {:function " libssh2_agent_get_identity"
38
+ :return ret
39
+ :session session})))))
36
40
37
41
(defn authenticate
38
42
" Attempt to authenticate a session using the agent.
50
54
[session username]
51
55
(let [ssh-agent (libssh2-agent/init (:session session))]
52
56
(when (nil? ssh-agent)
53
- (throw ( Exception. " Failed to initialize agent. " ) ))
57
+ (error/maybe- throw-error session libssh2/ERROR_ALLOC ))
54
58
(try
55
59
(handle-errors session
56
60
(with-timeout :agent
65
69
(libssh2-agent/userauth ssh-agent username id)))
66
70
id)
67
71
false )))
68
- (throw (Exception. " Failed to authenticate with the agent." )))
72
+ (throw (ex-info " Failed to authenticate using the SSH agent."
73
+ {:username username
74
+ :session session})))
69
75
true
70
76
(finally
71
77
(handle-errors session
Original file line number Diff line number Diff line change 4
4
[clj-libssh2.agent :as agent]
5
5
[clj-libssh2.error :refer [handle-errors with-timeout]]
6
6
[clj-libssh2.libssh2.userauth :as libssh2-userauth])
7
- (:import clojure.lang.PersistentArrayMap))
7
+ (:import [java.io FileNotFoundException]
8
+ [clojure.lang PersistentArrayMap]))
8
9
9
10
(defprotocol Credentials
10
11
" A datatype to represent a way of authentication and the necessary data to
21
22
(valid? [credentials] (and (some? username)
22
23
(some? passphrase)
23
24
(some? private-key)
24
- (some? public-key)
25
- (.exists (file private-key))
26
- (.exists (file public-key)))))
25
+ (some? public-key))))
27
26
28
27
(defrecord PasswordCredentials [username password]
29
28
Credentials
54
53
[session credentials]
55
54
(doseq [keyfile (map #(% credentials) [:private-key :public-key ])]
56
55
(when-not (.exists (file keyfile))
57
- (throw (Exception. ( format " %s does not exist. " keyfile) ))))
56
+ (throw (FileNotFoundException. keyfile))))
58
57
(handle-errors session
59
58
(with-timeout :auth
60
59
(libssh2-userauth/publickey-fromfile (:session session)
81
80
(authenticate session creds)
82
81
(if (< 1 (count m))
83
82
(recur (rest m))
84
- (throw (Exception. " Invalid credentials" )))))))
83
+ (throw (ex-info " Failed to determine credentials type."
84
+ {:items (keys credentials)
85
+ :session session})))))))
Original file line number Diff line number Diff line change 164
164
:else (str v)))
165
165
fail-if-forbidden (fn [ret]
166
166
(if (= libssh2/ERROR_CHANNEL_REQUEST_DENIED ret)
167
- (throw (Exception. " Setting environment variables is not permitted." ))
167
+ (throw (ex-info " Setting environment variables is not permitted."
168
+ {:session session}))
168
169
ret))]
169
170
(doseq [[k v] env]
170
171
(block session
322
323
(when (and (= pump-fn pull)
323
324
(= :eagain new-status)
324
325
(< (-> session :options :read-timeout ) (- now last-read-time)))
325
- (throw (Exception. (format " Read timeout for %s stream %d"
326
- (-> stream :direction name)
327
- (-> stream :id )))))
326
+ (throw (ex-info " Read timeout on a channel."
327
+ {:direction (-> stream :direction name)
328
+ :id (-> stream :id )
329
+ :timeout (-> session :options :read-timeout )
330
+ :session session})))
328
331
(assoc stream :status new-status :last-read-time now))
329
332
stream))
330
333
Original file line number Diff line number Diff line change 109
109
which may be useful to debug the error handling itself:
110
110
111
111
:error The error message from error-messages, if any.
112
- :session-error The error message from session-error-message, if any.
113
- :error-code The numeric return value."
112
+ :error-code The numeric return value.
113
+ :session The clj-libssh2.session.Session object, if any.
114
+ :session-error The error message from session-error-message, if any."
114
115
[session error-code]
115
116
(when (and (some? error-code)
116
117
(> 0 error-code)
121
122
default-message
122
123
(format " An unknown error occurred: %d" error-code))
123
124
{:error default-message
124
- :session-error session-message
125
- :error-code error-code})))))
125
+ :error-code error-code
126
+ :session session
127
+ :session-error session-message})))))
126
128
127
129
(defmacro handle-errors
128
130
" Run some code that might return a negative number to indicate an error.
197
199
timeout# (get-timeout ~timeout)]
198
200
(loop [timedout# false ]
199
201
(if timedout#
200
- (throw (Exception. " Timeout!" ))
202
+ (throw (ex-info " Timeout exceeded."
203
+ {:timeout ~timeout
204
+ :timeout-length timeout#}))
201
205
(let [r# (do ~@body)]
202
206
(if (= r# libssh2/ERROR_EAGAIN)
203
207
(recur (< timeout# (- (System/currentTimeMillis ) start#)))
Original file line number Diff line number Diff line change 2
2
" Utilities for checking the fingerprint of a remote machine against a list of
3
3
known hosts."
4
4
(:require [clojure.java.io :refer [file]]
5
- [clj-libssh2.error :refer [handle-errors with-timeout]]
5
+ [clj-libssh2.error :as error : refer [handle-errors with-timeout]]
6
6
[clj-libssh2.libssh2 :as libssh2]
7
7
[clj-libssh2.libssh2.knownhost :as libssh2-knownhost]
8
8
[clj-libssh2.libssh2.session :as libssh2-session])
39
39
libssh2/ERROR_HOSTKEY_SIGN
40
40
0 )
41
41
libssh2/KNOWNHOST_CHECK_FAILURE libssh2/ERROR_HOSTKEY_SIGN
42
- (throw (Exception. (format " Unknown return code from libssh2-knownhost/checkp: %d" result)))))
42
+ (throw (ex-info " Unknown return code from libssh2_knownhost_checkp."
43
+ {:function " libssh2_knownhost_checkp"
44
+ :return result}))))
43
45
44
46
(defn- host-fingerprint
45
47
" Get the remote host's fingerprint.
131
133
fail-on-mismatch (-> session-options :fail-unless-known-hosts-matches )
132
134
fail-on-missing (-> session-options :fail-if-not-in-known-hosts )]
133
135
(when (nil? known-hosts)
134
- (throw ( Exception. " Failed to initialize known hosts store. " ) ))
136
+ (error/maybe- throw-error session libssh2/ERROR_ALLOC ))
135
137
(try
136
138
(load-known-hosts session known-hosts file)
137
139
(check-fingerprint session
Original file line number Diff line number Diff line change 4
4
[clj-libssh2.libssh2 :as libssh2]
5
5
[clj-libssh2.libssh2.session :as libssh2-session]
6
6
[clj-libssh2.authentication :refer [authenticate]]
7
- [clj-libssh2.error :refer [handle-errors with-timeout]]
7
+ [clj-libssh2.error :as error : refer [handle-errors with-timeout]]
8
8
[clj-libssh2.known-hosts :as known-hosts]
9
9
[clj-libssh2.socket :as socket]))
10
10
37
37
[]
38
38
(let [session (libssh2-session/init )]
39
39
(when-not session
40
- (throw ( Exception. " Failed to create a libssh2 session. " ) ))
40
+ (error/maybe- throw-error nil libssh2/ERROR_ALLOC ))
41
41
session))
42
42
43
43
(defn- create-session-options
73
73
nil or throws an exception if requested."
74
74
([session]
75
75
(destroy-session session " Shutting down normally." false ))
76
- ([{ session :session } reason raise]
76
+ ([session reason raise]
77
77
(handle-errors nil
78
78
(with-timeout :session
79
- (libssh2-session/disconnect session reason)))
79
+ (libssh2-session/disconnect ( : session session) reason)))
80
80
(handle-errors nil
81
81
(with-timeout :session
82
- (libssh2-session/free session)))
82
+ (libssh2-session/free ( : session session) )))
83
83
(when raise
84
- (throw (Exception. reason)))))
84
+ (throw (ex-info reason { :session session} )))))
85
85
86
86
(defn- handshake
87
87
" Perform the startup handshake with the remote host.
147
147
(authenticate session credentials)
148
148
(swap! sessions conj session)
149
149
session
150
- (catch Exception e
150
+ (catch Throwable t
151
151
(close session)
152
- (throw e )))))
152
+ (throw t )))))
153
153
154
154
(defmacro with-session
155
155
" A convenience macro for running some code with a particular session.
Original file line number Diff line number Diff line change 29
29
port)]
30
30
(when (> 0 socket)
31
31
; ; Magic numbers are from libsimplesocket.h
32
- (throw ( Exception. (condp = socket
33
- SIMPLE_SOCKET_BAD_ADDRESS
34
- (format " %s is not a valid IP address" address)
32
+ (let [message (condp = socket
33
+ SIMPLE_SOCKET_BAD_ADDRESS
34
+ (format " %s is not a valid IP address" address)
35
35
36
- SIMPLE_SOCKET_SOCKET_FAILED
37
- " Failed to create a TCP socket"
36
+ SIMPLE_SOCKET_SOCKET_FAILED
37
+ " Failed to create a TCP socket"
38
38
39
- SIMPLE_SOCKET_CONNECT_FAILED
40
- (format " Failed to connect to %s:%d" address port)
39
+ SIMPLE_SOCKET_CONNECT_FAILED
40
+ (format " Failed to connect to %s:%d" address port)
41
41
42
- " An unknown error occurred" ))))
42
+ " simple_socket_connect returned a bad value" )]
43
+ (throw (ex-info message {:socket socket}))))
43
44
socket))
44
45
45
46
(defn select
Original file line number Diff line number Diff line change 16
16
(session/close session))
17
17
(is (= 0 (count @session/sessions))))
18
18
19
- ; This is more fully tested in clj-libssh2.test-authentication
19
+ ; This is more fully tested in clj-libssh2.test-agent
20
20
(deftest agent-authentication-works
21
21
(is (auth (->AgentCredentials (test/ssh-user )))))
22
22
49
49
(is (valid? unauthorized))
50
50
(is (thrown? Exception (auth unauthorized))))
51
51
(testing " It fails if the private key file doesn't exist"
52
- (is (not ( valid? bad-privkey) ))
52
+ (is (valid? bad-privkey))
53
53
(is (thrown? Exception (auth bad-privkey))))
54
54
(testing " It fails if the public key file doesn't exist"
55
- (is (not ( valid? bad-pubkey) ))
55
+ (is (valid? bad-pubkey))
56
56
(is (thrown? Exception (auth bad-pubkey))))
57
57
(testing " It fails if the passphrase is incorrect"
58
58
(is (valid? with-wrong-passphrase))
78
78
(deftest authenticating-with-a-map-fails-if-there 's-no-equivalent-record
79
79
(is (thrown-with-msg?
80
80
Exception
81
- #"Invalid credentials"
81
+ #"Failed to determine credentials type "
82
82
(auth {:password " foo" }))))
You can’t perform that action at this time.
0 commit comments