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