Reproducing the problem
Your public key looks fine. I believeI've tried reproducing the error you are getting might be related, but it seems to work for me, below I will describe how I did it, and some speculations regarding your problem:
- Made a directory and copied in the example file
sftp_write.cfrom libssh2. - Changed
auth_pwfrom1to0on line 27. - Changed pubkey and privkey to use my own keys, and added debugging.
const char *pubkey = "/home/user/.ssh/id_rsa_PEM.pub";
const char *privkey = "/home/user/.ssh/id_rsa_PEM";
int liberr;
if(liberr = libssh2_userauth_publickey_fromfile(session, username,
pubkey, privkey,
password)) {
fprintf(stderr, "\tAuthentication by public key failed: %d\n", liberr);
goto shutdown;
}
- changed
#include "libssh2_config.h"
#include <libssh2.h>
#include <libssh2_sftp.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
to
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
To match my setup.
- Used Docker to compile the image by running
docker run -i --rm \
-w $(pwd) -v $(pwd):$(pwd) \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
-u $(id -u):$(id -u) \
datafr/libssh2:latest \
gcc -g -I /usr/include/ -L /usr/lib/ -l ssh2 sftp_write.c -o a.out
- Ran the program with
./a.out 127.0.0.1 $USER
Results
Running this code results in error -19: LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED. This is because the private keydocker image uses an older version of libssh2 which you setrequires older PEM keys. This is fixed by creating a new keypair with
ssh-keygen -m PEM -t rsa -P "" -f id_rsa_PEM
And modifying the code to NULLuse the new keys. Try passing your private
Running the code once more gives us error -18: LIBSSH2_ERROR_AUTHENTICATION_FAILED. This is fixed by adding our new public key id_rsa_PEM.pub to libssh2the servers authorized_keys-file.
After this, we get no more errors, and make surethe output looks like this:
$ ./a.out 127.0.0.1 $USER
Fingerprint: XXXXXXX
libssh2_sftp_init()!
libssh2_sftp_open()!
libssh2_sftp_open() is done, now send data!
all done
And I can confirm the creation of a file called /tmp/TEST containing our code from sftp_write.c.
Further speculations
I've noticed that error -16: LIBSSH2_ERROR_FILE occurs when the file is either non-existent or has the wrong permissions, so I'll ask you to adddouble check your public key to the servers authorized keysfile permissions. I'll post my own permissions as reference.
Client ~/.ssh/ directory:
$ ls -alh
total 28K
drwx------ 2 user user 4,0K Sep 28 15:37 .
drwxr-xr-x 32 user user 4,0K Sep 28 15:36 ..
-rw-rw-r-- 1 user user 2,7K Sep 28 15:36 config
-rw------- 1 user user 2,5K Sep 28 15:36 id_rsa_PEM
-rw-r--r-- 1 user user 574 Sep 28 15:36 id_rsa_PEM.pub
-rw------- 1 user user 6,3K Sep 28 15:36 known_hosts
Server ~/.ssh/ directory:
$ ls -alh
total 20K
drwx------ 2 user user 4,0K Sep 28 15:39 .
drwxr-xr-x 32 user user 4,0K Sep 28 15:39 ..
-rw------- 1 user user 3,4K Sep 28 15:39 authorized_keys