forked from adamdruppe/arsd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libssh2.d
189 lines (138 loc) · 5.23 KB
/
libssh2.d
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
178
179
180
181
182
183
184
185
186
187
188
189
/// Small wrapper for libssh2
/// just link with it on Linux
/// it'll need a couple dlls and a lib on windows.
module arsd.libssh2;
version(libssh_example)
void main() {
import std.socket;
if(libssh2_init(0))
throw new Exception("libssh2_init");
scope(exit)
libssh2_exit();
auto socket = new Socket(AddressFamily.INET, SocketType.STREAM);
socket.connect(new InternetAddress("localhost", 22));
scope(exit) socket.close();
auto session = libssh2_session_init_ex(null, null, null, null);
if(session is null) throw new Exception("init session");
scope(exit)
libssh2_session_disconnect_ex(session, 0, "normal", "EN");
if(libssh2_session_handshake(session, socket.handle))
throw new Exception("handshake");
auto fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
/*
import core.stdc.stdio;
for(int i = 0; i < 20; i++)
printf("%02X ", fingerprint[i]);
*/
/*
auto got = libssh2_userauth_list(session, "me", 2);
if(got is null) throw new Exception("list");
import core.stdc.stdio;
printf("%s\n", got);
*/
if(auto err = libssh2_userauth_publickey_fromfile_ex(session, "me".ptr, "me".length, "/home/me/.ssh/id_rsa.pub", "/home/me/.ssh/id_rsa", null))
throw new Exception("auth");
auto channel = libssh2_channel_open_ex(session, "session".ptr, "session".length, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, null, 0);
if(channel is null)
throw new Exception("channel open");
scope(exit)
libssh2_channel_free(channel);
libssh2_channel_setenv_ex(channel, "ELVISBG".dup.ptr, "ELVISBG".length, "dark".ptr, "dark".length);
if(libssh2_channel_request_pty_ex(channel, "xterm", "xterm".length, null, 0, 80, 24, 0, 0))
throw new Exception("pty");
if(libssh2_channel_process_startup(channel, "shell".ptr, "shell".length, null, 0))
throw new Exception("process_startup");
libssh2_keepalive_config(session, 0, 60);
libssh2_session_set_blocking(session, 0);
char[1024] buffer;
again:
auto got = libssh2_channel_read_ex(channel, 0, buffer.ptr, buffer.length);
if(got == LIBSSH2_ERROR_EAGAIN) {
import core.thread;
Thread.sleep(msecs(500));
goto again;
}
import std.stdio;
writeln(buffer[0 .. got]);
}
alias socket_t = int;
version(Windows) {
pragma(lib, "libssh2");
} else {
pragma(lib, "ssh2");
}
version(X86)
alias ssize_t = int;
else version(X86_64)
alias ssize_t = long;
extern(C) {
struct LIBSSH2_SESSION {}
LIBSSH2_SESSION* libssh2_session_init_ex(void* myalloc, void* myfree, void* myrealloc, void* abstract_);
int libssh2_session_handshake(LIBSSH2_SESSION* session, socket_t socket);
enum int LIBSSH2_HOSTKEY_HASH_MD5 = 1;
enum int LIBSSH2_HOSTKEY_HASH_SHA1 = 2;
const(char)* libssh2_hostkey_hash(LIBSSH2_SESSION*, int hash_type);
int libssh2_userauth_publickey_fromfile_ex(
LIBSSH2_SESSION* session,
const char *username,
uint ousername_len,
const char *publickey,
const char *privatekey,
const char *passphrase);
struct LIBSSH2_CHANNEL {}
LIBSSH2_CHANNEL* libssh2_channel_open_ex(
LIBSSH2_SESSION *session,
const char *channel_type,
uint channel_type_len,
uint window_size,
uint packet_size,
const char *message,
uint message_len);
// channel_open_session calls the above
int libssh2_channel_setenv_ex(
LIBSSH2_CHANNEL* channel,
char* varname,
uint varname_len,
const char *value,
uint value_len);
enum LIBSSH2_CHANNEL_WINDOW_DEFAULT = (256*1024);
enum LIBSSH2_CHANNEL_PACKET_DEFAULT = 32768;
int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, uint term_len, const char *modes, uint modes_len, int width, int height, int width_px, int height_px);
int libssh2_channel_process_startup(
LIBSSH2_CHANNEL* channel,
const char *request,
uint request_len,
const char *message,
uint message_len);
int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang);
int libssh2_session_free(LIBSSH2_SESSION *session);
int libssh2_init(int flags);
void libssh2_exit();
// stream_id 0 == normal, 1 == error.
ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, void *buf, size_t buflen);
ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
int stream_id, const(void)* buf,
size_t buflen);
void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking);
void libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
uint interval);
int libssh2_keepalive_send(LIBSSH2_SESSION *session,
int *seconds_to_next);
LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport);
int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
int width, int height,
int width_px,
int height_px);
char *
libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username,
uint username_len);
int libssh2_channel_eof(LIBSSH2_CHANNEL*);
int libssh2_channel_close(LIBSSH2_CHANNEL*);
int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
enum LIBSSH2_ERROR_EAGAIN = -37;
int libssh2_session_flag(LIBSSH2_SESSION*, int, int);
enum LIBSSH2_FLAG_SIGPIPE = 1;
enum LIBSSH2_FLAG_COMPRESS = 2;
}