-
Notifications
You must be signed in to change notification settings - Fork 24
/
auth.go
177 lines (159 loc) · 5.45 KB
/
auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package libssh
/*
#cgo pkg-config: libssh
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <libssh/libssh.h>
*/
import "C"
func authError(fn string, r C.int) (int, error) {
ret := int(r)
switch ret {
case SSH_AUTH_SUCCESS,
SSH_AUTH_DENIED,
SSH_AUTH_PARTIAL,
SSH_AUTH_INFO,
SSH_AUTH_AGAIN:
return ret, nil
default:
if ret < 0 {
return ret, apiError(fn, ret)
}
return ret, apiError(fn, -1)
}
}
// Get available authentication methods from the server.
// This requires the function ssh_userauth_none() to be called before the methods
// are available. The server MAY return a list of methods that may continue.
//
// Returns
// A bitfield of the fllowing values:
// SSH_AUTH_METHOD_PASSWORD
// SSH_AUTH_METHOD_PUBLICKEY
// SSH_AUTH_METHOD_HOSTBASED
// SSH_AUTH_METHOD_INTERACTIVE
func (s Session) UserAuthList() int {
return int(C.ssh_userauth_list(s.ptr, nil))
}
// Try to do public key authentication with ssh agent.
//
// Note:
// Most server implementations do not permit changing the username during
// authentication. The username should only be set with ssh_options_set() only
// before you connect to the server.
//
// returns:
// state int:
//
func (s Session) UserAuthAgent(name string) (int, error) {
return authError("ssh_userauth_agent", C.ssh_userauth_agent(s.ptr, nil))
}
// Try to authenticate through the "gssapi-with-mic" method.
func (s Session) UserAuthGssapi() (int, error) {
return authError("ssh_userauth_gssapi", C.ssh_userauth_gssapi(s.ptr))
}
// Try to authenticate through the "none" method.
func (s Session) UserAuthNone() (int, error) {
return authError("ssh_userauth_none", C.ssh_userauth_none(s.ptr, nil))
}
// Try to authenticate by password
//
// This authentication method is normally disabled on SSHv2 server. You should
// use keyboard-interactive mode.
//
// The 'password' value MUST be encoded UTF-8. It is up to the server how to
// interpret the password and validate it against the password database.
// However, if you read the password in some other encoding, you MUST convert
// the password to UTF-8.
//
func (s Session) UseAuthPassword(password string) (int, error) {
password_cstr := CString(password)
defer password_cstr.Free()
return authError("ssh_userauth_password", C.ssh_userauth_password(s.ptr, nil, password_cstr.Ptr))
}
// Authenticate with public/private key or certificate.
func (s Session) UserAuthPublicKey(privateKey Key) (int, error) {
return authError("ssh_userauth_try_publickey", C.ssh_userauth_publickey(s.ptr, nil, privateKey.key))
}
// Tries to automatically authenticate with public key and "none".
//
// It may fail, for instance it doesn't ask for a password and uses a default
// asker for passphrases (in case the private key is encrypted)
//
// passphrase:
// Use this passphrase to unlock the privatekey. Use NULL if you don't want to
// use a passphrase or the user should be asked.
func (s Session) UserAuthPublicKeyAuto(passphrase string) (int, error) {
var passphrase_cstr *C.char
if passphrase != "" {
s := CString(passphrase)
defer s.Free()
passphrase_cstr = s.Ptr
}
return authError("ssh_userauth_publickey_auto", C.ssh_userauth_publickey_auto(s.ptr, nil, passphrase_cstr))
}
// Try to authenticate with the given public key.
//
// To avoid unnecessary processing and user interaction, the following method is
// provided for querying whether authentication using the 'pubkey' would be
// possible
func (s Session) UserAuthTryPublickKey(pubkey Key) (int, error) {
return authError("ssh_userauth_try_publickey", C.ssh_userauth_try_publickey(s.ptr, nil, pubkey.key))
}
// Try to authenticate through the "keyboard-interactive" method
func (s Session) UserAuthKeybdInteractive() (int, error) {
return authError("ssh_userauth_kbdint", C.ssh_userauth_kbdint(s.ptr, nil, nil))
}
func (s Session) UserAuthKeybdGetAnswer(n uint) (string, error) {
answer := C.ssh_userauth_kbdint_getanswer(s.ptr, C.uint(n))
if answer == nil {
return "", apiError("ssh_userauth_kbdint_getanswer", "NULL")
}
return C.GoString(answer), nil
}
func (s Session) UserAuthKeybdGetInstruction() (string, error) {
inst := C.ssh_userauth_kbdint_getinstruction(s.ptr)
if inst == nil {
return "", apiError("ssh_userauth_kbdint_getinstruction", "NULL")
}
return C.GoString(inst), nil
}
func (s Session) UserAuthKeybdGetName() (string, error) {
name := C.ssh_userauth_kbdint_getname(s.ptr)
if name == nil {
return "", apiError("ssh_userauth_kbdint_getname", "NULL")
}
return C.GoString(name), nil
}
func (s Session) UserAuthKeybdGetNAnswers() (int, error) {
n := int(C.ssh_userauth_kbdint_getnanswers(s.ptr))
if n < 0 {
return n, apiError("ssh_userauth_kbdint_getnanswers", n)
}
return int(n), nil
}
func (s Session) UserAuthKeybdGetNPrompts() (int, error) {
n := int(C.ssh_userauth_kbdint_getnprompts(s.ptr))
if n < 0 {
return n, apiError("ssh_userauth_kbdint_getnprompts", n)
}
return int(n), nil
}
func (s Session) UserAuthKeybdGetPrompt(i int, echo string) (string, error) {
echo_cstr := CString(echo)
defer echo_cstr.Free()
prompt := C.ssh_userauth_kbdint_getprompt(s.ptr, C.uint(i), echo_cstr.Ptr)
if prompt == nil {
return "", apiError("ssh_userauth_kbdint_getprompt", "NULL")
}
return C.GoString(prompt), nil
}
func (s Session) AuthKbdintSetAnswer(i int, answer string) error {
answer_cstr := CString(answer)
defer answer_cstr.Free()
return apiError("ssh_userauth_kbdint_setanswer",
C.ssh_userauth_kbdint_setanswer(s.ptr, C.uint(i), answer_cstr.Ptr))
}