1 /// Small wrapper for libssh2 2 /// just link with it on Linux 3 /// it'll need a couple dlls and a lib on windows. 4 5 module arsd.libssh2; 6 7 version(libssh_example) 8 void main() { 9 import std.socket; 10 11 if(libssh2_init(0)) 12 throw new Exception("libssh2_init"); 13 scope(exit) 14 libssh2_exit(); 15 16 auto socket = new Socket(AddressFamily.INET, SocketType.STREAM); 17 socket.connect(new InternetAddress("localhost", 22)); 18 scope(exit) socket.close(); 19 20 auto session = libssh2_session_init_ex(null, null, null, null); 21 if(session is null) throw new Exception("init session"); 22 scope(exit) 23 libssh2_session_disconnect_ex(session, 0, "normal", "EN"); 24 25 if(libssh2_session_handshake(session, socket.handle)) 26 throw new Exception("handshake"); 27 28 auto fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); 29 30 /* 31 import core.stdc.stdio; 32 for(int i = 0; i < 20; i++) 33 printf("%02X ", fingerprint[i]); 34 */ 35 36 /* 37 auto got = libssh2_userauth_list(session, "me", 2); 38 if(got is null) throw new Exception("list"); 39 import core.stdc.stdio; 40 printf("%s\n", got); 41 */ 42 43 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)) 44 throw new Exception("auth"); 45 46 47 auto channel = libssh2_channel_open_ex(session, "session".ptr, "session".length, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, null, 0); 48 49 if(channel is null) 50 throw new Exception("channel open"); 51 52 scope(exit) 53 libssh2_channel_free(channel); 54 55 libssh2_channel_setenv_ex(channel, "ELVISBG".dup.ptr, "ELVISBG".length, "dark".ptr, "dark".length); 56 57 if(libssh2_channel_request_pty_ex(channel, "xterm", "xterm".length, null, 0, 80, 24, 0, 0)) 58 throw new Exception("pty"); 59 60 if(libssh2_channel_process_startup(channel, "shell".ptr, "shell".length, null, 0)) 61 throw new Exception("process_startup"); 62 63 libssh2_keepalive_config(session, 0, 60); 64 libssh2_session_set_blocking(session, 0); 65 66 67 char[1024] buffer; 68 again: 69 auto got = libssh2_channel_read_ex(channel, 0, buffer.ptr, buffer.length); 70 if(got == LIBSSH2_ERROR_EAGAIN) { 71 import core.thread; 72 Thread.sleep(msecs(500)); 73 goto again; 74 } 75 76 import std.stdio; 77 writeln(buffer[0 .. got]); 78 } 79 80 81 82 83 alias socket_t = int; 84 85 version(Windows) { 86 pragma(lib, "libssh2"); 87 } else { 88 pragma(lib, "ssh2"); 89 } 90 91 version(X86) 92 alias ssize_t = int; 93 else version(X86_64) 94 alias ssize_t = long; 95 96 extern(C) { 97 struct LIBSSH2_SESSION {} 98 LIBSSH2_SESSION* libssh2_session_init_ex(void* myalloc, void* myfree, void* myrealloc, void* abstract_); 99 100 int libssh2_session_handshake(LIBSSH2_SESSION* session, socket_t socket); 101 102 enum int LIBSSH2_HOSTKEY_HASH_MD5 = 1; 103 enum int LIBSSH2_HOSTKEY_HASH_SHA1 = 2; 104 const(char)* libssh2_hostkey_hash(LIBSSH2_SESSION*, int hash_type); 105 106 int libssh2_userauth_publickey_fromfile_ex( 107 LIBSSH2_SESSION* session, 108 const char *username, 109 uint ousername_len, 110 const char *publickey, 111 const char *privatekey, 112 const char *passphrase); 113 114 struct LIBSSH2_CHANNEL {} 115 LIBSSH2_CHANNEL* libssh2_channel_open_ex( 116 LIBSSH2_SESSION *session, 117 const char *channel_type, 118 uint channel_type_len, 119 uint window_size, 120 uint packet_size, 121 const char *message, 122 uint message_len); 123 // channel_open_session calls the above 124 125 int libssh2_channel_setenv_ex( 126 LIBSSH2_CHANNEL* channel, 127 char* varname, 128 uint varname_len, 129 const char *value, 130 uint value_len); 131 132 enum LIBSSH2_CHANNEL_WINDOW_DEFAULT = (256*1024); 133 enum LIBSSH2_CHANNEL_PACKET_DEFAULT = 32768; 134 135 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); 136 137 int libssh2_channel_process_startup( 138 LIBSSH2_CHANNEL* channel, 139 const char *request, 140 uint request_len, 141 const char *message, 142 uint message_len); 143 144 145 int libssh2_channel_free(LIBSSH2_CHANNEL *channel); 146 int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang); 147 int libssh2_session_free(LIBSSH2_SESSION *session); 148 149 int libssh2_init(int flags); 150 void libssh2_exit(); 151 152 // stream_id 0 == normal, 1 == error. 153 ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, void *buf, size_t buflen); 154 155 ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, 156 int stream_id, const(void)* buf, 157 size_t buflen); 158 159 void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking); 160 161 void libssh2_keepalive_config(LIBSSH2_SESSION *session, 162 int want_reply, 163 uint interval); 164 165 int libssh2_keepalive_send(LIBSSH2_SESSION *session, 166 int *seconds_to_next); 167 168 LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport); 169 170 int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, 171 int width, int height, 172 int width_px, 173 int height_px); 174 175 char * 176 libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, 177 uint username_len); 178 179 int libssh2_channel_eof(LIBSSH2_CHANNEL*); 180 int libssh2_channel_close(LIBSSH2_CHANNEL*); 181 int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel); 182 183 enum LIBSSH2_ERROR_EAGAIN = -37; 184 185 int libssh2_session_flag(LIBSSH2_SESSION*, int, int); 186 enum LIBSSH2_FLAG_SIGPIPE = 1; 187 enum LIBSSH2_FLAG_COMPRESS = 2; 188 189 }