curl-library
SFTP Public-Key Authentication
Date: Thu, 11 Jul 2013 20:28:14 +0000
I've been trying to upload a file using SFTP with libcurl using public-key
authentication, but have had no luck.
In my `/etc/ssh/sshd_config` file I have turned off password authentication and
enabled public-key and RSA authentication. I have created a public and private key
pair in my `$HOME/.ssh` directory (id_rsa + id_rsa.pub) and copied `id_rsa.pub`
as the `authorized_keys` file. From the shell I am able to log in automatically without
needing to enter a passphrase/password.
However, my program which uploads a file via SFTP using libcurl does not work.
Below is the SFTP upload code I'm using:
#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <curl/curl.h>
using namespace std;
// libcurl Read/Write Callback Functions
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream){
curl_off_t nread;
size_t retcode = fread(ptr, size, nmemb, (FILE*)stream);
nread = (curl_off_t)retcode;
return retcode;
}
int main(void){
// Networking Contexts
CURL *curlUp; // cURL upload context
CURLcode res; // Error code
FILE *memstream; // Memory stream
stringstream file_sstream; // C++ string stream
char buffer[BUFSIZ]; // C string
// Initialize cURL context
curl_global_init(CURL_GLOBAL_DEFAULT);
if(!(curlUp = curl_easy_init())){
fprintf(stderr, "ERROR: cURL Context Initialization\n");
exit(EXIT_FAILURE);
}
// Set URL encoding
curl_easy_setopt(curlUp, CURLOPT_URL, "sftp://localhost/~/output");
curl_easy_setopt(curlUp, CURLOPT_USERNAME, "squirem");
// Other options
curl_easy_setopt(curlUp, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curlUp, CURLOPT_NOSIGNAL, 1L);
// Set our own read/write functions
curl_easy_setopt(curlUp, CURLOPT_READFUNCTION, read_callback);
// Set SSH options
curl_easy_setopt(curlUp, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY);
curl_easy_setopt(curlUp, CURLOPT_SSH_PUBLIC_KEYFILE, "home/squirem/.ssh/id_rsa.pub");
curl_easy_setopt(curlUp, CURLOPT_SSH_PRIVATE_KEYFILE, "home/squirem/.ssh/id_rsa");
curl_easy_setopt(curlUp, CURLOPT_SSH_KNOWNHOSTS, "/home/squirem/.ssh/known_hosts");
curl_easy_setopt(curlUp, CURLOPT_KEYPASSWD, "mypasswd");
// Enable uploading
curl_easy_setopt(curlUp, CURLOPT_UPLOAD, 1L);
file_sstream << "Why" << "\n";
file_sstream << "Won't" << "\n";
file_sstream << "This" << "\n";
file_sstream << "Work!" << "\n";
// Test for buffer overflow
if(file_sstream.str().length() >= BUFSIZ){
fprintf(stderr, "ERROR: NetworkThread Invalid Readouts String\n");
return EXIT_FAILURE;
}
// Copy over string
snprintf(buffer, BUFSIZ, "%s", file_sstream.str().c_str());
// Open readouts string as file
memstream = fmemopen(buffer,BUFSIZ,"r");
// Pass readouts string stream to callback function
curl_easy_setopt(curlUp, CURLOPT_READDATA, memstream);
// Upload File
if((res=curl_easy_perform(curlUp)) != CURLE_OK){
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
fclose(memstream);
curl_easy_cleanup(curlUp); // End cURL upload session
curl_global_cleanup(); // Global libcurl cleanup
return 0;
}
The application prints out the following error:
* About to connect() to localhost port 22 (#0)
* Trying ::1... * connected
* Connected to localhost (::1) port 22 (#0)
* SSH host check: 0, key: bunchOfGibberish
* SSH authentication methods available: publickey,gssapi-keyex,gssapi-with-mic
* Using ssh public key file home/squirem/.ssh/id_rsa.pub
* Using ssh private key file home/squirem/.ssh/id_rsa
* SSH public key authentication failed: Unable to open public key file
* Authentication failure
* Closing connection #0
* Login denied
curl_easy_perform() failed: Login denied
The code compiles with g++ as is. I'm thinking one of my options is incorrect,
or I'm missing one.
Any help would be appreciated.
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-07-12