cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: SFTP Public-Key Authentication

From: Ryan <meokid2_at_yahoo.com>
Date: Fri, 12 Jul 2013 21:27:47 +0800

On Jul 12, 2013, at 4:28 AM, Saddam Quirem <SQuirem_at_fbdfrozen.com> wrote:

> 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:

Could you please upload the code to PasteBin or similar? Email messes up the formatting, at least for me. You can even specify the language as C++ to get syntax highlighting as well. I always do this because a) it makes the email shorter and b) the formatting will be more proper.

Also - just saying you have a problem doesn't help us help you. Can you turn on verbose output, or at least do something so you have a working theory as to why it isn't working? Looks like the error is that it can't open the public key file - have you checked permissions or made sure it's reading from the right path?

Here's a hint - instead of home/squirem/.ssh/id_rsa.pub try /home/squirem/.ssh/id_rsa.pub . Otherwise, it'll look in the current directory, and I doubt that's what you want.

>
> #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

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-07-12