1 /*
2 * Sample showing how to do SFTP write transfers.
3 *
4 * The sample code has default values for host name, user name, password
5 * and path to copy, but you can specify them on the command line like:
6 *
7 * "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
8 */
9
10 #include "libssh2_config.h"
11 #include <libssh2.h>
12 #include <libssh2_sftp.h>
13
14 #ifdef HAVE_WINSOCK2_H
15 # include <winsock2.h>
16 #endif
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
19 #endif
20 #ifdef HAVE_NETINET_IN_H
21 # include <netinet/in.h>
22 #endif
23 # ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 #ifdef HAVE_ARPA_INET_H
27 # include <arpa/inet.h>
28 #endif
29
30 #include <sys/types.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <ctype.h>
35
main(int argc,char * argv[])36 int main(int argc, char *argv[])
37 {
38 unsigned long hostaddr;
39 int sock, i, auth_pw = 1;
40 struct sockaddr_in sin;
41 const char *fingerprint;
42 LIBSSH2_SESSION *session;
43 const char *username = "username";
44 const char *password = "password";
45 const char *loclfile = "sftp_write.c";
46 const char *sftppath = "/tmp/TEST";
47 int rc;
48 FILE *local;
49 LIBSSH2_SFTP *sftp_session;
50 LIBSSH2_SFTP_HANDLE *sftp_handle;
51 char mem[1024*100];
52 size_t nread;
53 char *ptr;
54
55 #ifdef WIN32
56 WSADATA wsadata;
57 int err;
58
59 err = WSAStartup(MAKEWORD(2, 0), &wsadata);
60 if(err != 0) {
61 fprintf(stderr, "WSAStartup failed with error: %d\n", err);
62 return 1;
63 }
64 #endif
65
66 if(argc > 1) {
67 hostaddr = inet_addr(argv[1]);
68 }
69 else {
70 hostaddr = htonl(0x7F000001);
71 }
72
73 if(argc > 2) {
74 username = argv[2];
75 }
76 if(argc > 3) {
77 password = argv[3];
78 }
79 if(argc > 4) {
80 loclfile = argv[4];
81 }
82 if(argc > 5) {
83 sftppath = argv[5];
84 }
85
86 rc = libssh2_init(0);
87 if(rc != 0) {
88 fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
89 return 1;
90 }
91
92 local = fopen(loclfile, "rb");
93 if(!local) {
94 fprintf(stderr, "Can't open local file %s\n", loclfile);
95 return -1;
96 }
97
98 /*
99 * The application code is responsible for creating the socket
100 * and establishing the connection
101 */
102 sock = socket(AF_INET, SOCK_STREAM, 0);
103
104 sin.sin_family = AF_INET;
105 sin.sin_port = htons(22);
106 sin.sin_addr.s_addr = hostaddr;
107 if(connect(sock, (struct sockaddr*)(&sin),
108 sizeof(struct sockaddr_in)) != 0) {
109 fprintf(stderr, "failed to connect!\n");
110 return -1;
111 }
112
113 /* Create a session instance
114 */
115 session = libssh2_session_init();
116 if(!session)
117 return -1;
118
119 /* Since we have set non-blocking, tell libssh2 we are blocking */
120 libssh2_session_set_blocking(session, 1);
121
122 /* ... start it up. This will trade welcome banners, exchange keys,
123 * and setup crypto, compression, and MAC layers
124 */
125 rc = libssh2_session_handshake(session, sock);
126 if(rc) {
127 fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
128 return -1;
129 }
130
131 /* At this point we havn't yet authenticated. The first thing to do
132 * is check the hostkey's fingerprint against our known hosts Your app
133 * may have it hard coded, may go to a file, may present it to the
134 * user, that's your call
135 */
136 fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
137 fprintf(stderr, "Fingerprint: ");
138 for(i = 0; i < 20; i++) {
139 fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
140 }
141 fprintf(stderr, "\n");
142
143 if(auth_pw) {
144 /* We could authenticate via password */
145 if(libssh2_userauth_password(session, username, password)) {
146 fprintf(stderr, "Authentication by password failed.\n");
147 goto shutdown;
148 }
149 }
150 else {
151 /* Or by public key */
152 const char *pubkey = "/home/username/.ssh/id_rsa.pub";
153 const char *privkey = "/home/username/.ssh/id_rsa.pub";
154 if(libssh2_userauth_publickey_fromfile(session, username,
155 pubkey, privkey,
156 password)) {
157 fprintf(stderr, "\tAuthentication by public key failed\n");
158 goto shutdown;
159 }
160 }
161
162 fprintf(stderr, "libssh2_sftp_init()!\n");
163 sftp_session = libssh2_sftp_init(session);
164
165 if(!sftp_session) {
166 fprintf(stderr, "Unable to init SFTP session\n");
167 goto shutdown;
168 }
169
170 fprintf(stderr, "libssh2_sftp_open()!\n");
171 /* Request a file via SFTP */
172 sftp_handle =
173 libssh2_sftp_open(sftp_session, sftppath,
174 LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
175 LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
176 LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
177
178 if(!sftp_handle) {
179 fprintf(stderr, "Unable to open file with SFTP\n");
180 goto shutdown;
181 }
182 fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
183 do {
184 nread = fread(mem, 1, sizeof(mem), local);
185 if(nread <= 0) {
186 /* end of file */
187 break;
188 }
189 ptr = mem;
190
191 do {
192 /* write data in a loop until we block */
193 rc = libssh2_sftp_write(sftp_handle, ptr, nread);
194 if(rc < 0)
195 break;
196 ptr += rc;
197 nread -= rc;
198 } while(nread);
199
200 } while(rc > 0);
201
202 libssh2_sftp_close(sftp_handle);
203 libssh2_sftp_shutdown(sftp_session);
204
205 shutdown:
206 libssh2_session_disconnect(session,
207 "Normal Shutdown, Thank you for playing");
208 libssh2_session_free(session);
209
210 #ifdef WIN32
211 closesocket(sock);
212 #else
213 close(sock);
214 #endif
215 if(local)
216 fclose(local);
217 fprintf(stderr, "all done\n");
218
219 libssh2_exit();
220
221 return 0;
222 }
223