cURL / Mailing Lists / curl-users / Single Mail

curl-users

Re: attempted scp responds with Info: Channel failed to close: -34

From: Dan Fandrich <dan_at_coneharvesters.com>
Date: Fri, 25 Apr 2014 23:43:29 +0200

On Fri, Apr 25, 2014 at 05:10:31PM -0400, dev wrote:
> Not too sure why I am getting this message.
>
> Info: Channel failed to close: -34
>
> Trying to test an scp upload of a test file.

libssh2 error -34 is LIBSSH2_ERROR_INVAL, which seems pretty generic.
But, it's possible it's related to the issue below.

> curl version :
>
> node002$ curl --version
> curl 7.34.0 (sparc-sun-solaris2.10) libcurl/7.34.0 OpenSSL/1.0.1g
> zlib/1.2.7 libidn/1.26 libssh2/1.4.3
> Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps
> pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
> Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
>
>
> I see this :
>
> == Info: Hostname was NOT found in DNS cache
> == Info: Trying xxx.xxx.xxx.xxx...
> == Info: Adding handle: conn: 0x100157250
> == Info: Adding handle: send: 0
> == Info: Adding handle: recv: 0
> == Info: Curl_addHandleToPipeline: length: 1
> == Info: - Conn 0 (0x100157250) send_pipe: 1, recv_pipe: 0
> == Info: Connected to sometest.server.com (xxx.xxx.xxx.xxx) port 22 (#0)
> == Info: SSH MD5 fingerprint: feedbeef389d2586badcaffe1b8bc9b8
> == Info: SSH authentication methods available:
> gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive
> == Info: Using ssh public key file
> /export/home/debug/pgm/curl/scp_test_001/.ssh/test_rsa.id.pub
> == Info: Using ssh private key file
> /export/home/debug/pgm/curl/scp_test_001/.ssh/test_rsa.id
> == Info: Initialized SSH public key authentication
> == Info: Authentication complete
> == Info: SSH CONNECT phase done
> == Info: Channel failed to close: -34
> == Info: Connection #0 to host sometest.server.com left intact
> 0.000 bytes/sec for 1.473 secs
> res = 0 (write_error = 0)
>
> Data length received : 0 bytes
>
>
> Sure enough at the other end on the remote server I see :
>
> # ls -l drop_things_here/
> total 0
> -rw-r--r-- 1 debug staff 0 Apr 25 20:02 foo.dat
>
>
> A zero byte file. Not too useful.
>
>
> The essential bits of code that did this was :
>
>
> FILE *inputdat;
> FILE *logfile;
>
> struct stat datfid;
> int dat_stat, j, k;
>
> double accum, total_time, speed_upload;
> char* dat_buffer;
> char* ssh_pub_key_file =
> "/export/home/debug/pgm/curl/scp_test_001/.ssh/test_rsa.id.pub";
> char* ssh_priv_key_file =
> "/export/home/debug/pgm/curl/scp_test_001/.ssh/test_rsa.id";
> char* ssh_pass = "some_passphrase_string";
>
> struct dataflags config;
> config.trace_ascii = 1;
>
> dat_stat = stat ( DATFILENAME, &datfid );
>
> if ( dat_stat != 0 ) {
> perror ( "INPUT Error: " );
> exit ( EXIT_FAILURE );
> }
>
> fprintf ( stderr, "input dat file size = %i bytes\n",
> ( int ) datfid.st_size );
>
> dat_buffer = calloc( (size_t) ( ( int ) datfid.st_size + 1 ),
> (size_t) sizeof( unsigned char
> ) );
>
> fprintf ( stderr, "dat_buffer addr = %p\n", dat_buffer );
> fprintf ( stderr, "dat_buffer size = %0xh bytes\n",
> ( int ) datfid.st_size +
> 1 );
>
> inputdat = fopen( DATFILENAME, "r" );
>
> fread ( dat_buffer, datfid.st_size, 1, inputdat );

This sets the input stream to the end of the file...

> logfile = fopen( "/dev/null", "w" );
>
> /* the above is a bit of a waste given that the CURLOPT_READFUNCTION
> will
> be NULL below. For now at least CURLOPT_READDATA will be the input
> file and it has to be read all over again. */
>
> curl_global_init( CURL_GLOBAL_ALL );
> curl = curl_easy_init();
>
> if ( curl ) {
>
> curl_easy_setopt ( curl, CURLOPT_UPLOAD, 1L );
> curl_easy_setopt ( curl, CURLOPT_URL,
>
> "scp://sometest.server.com:22/export/home/debug/drop_things_here/foo.dat");
> curl_easy_setopt ( curl, CURLOPT_SSH_PUBLIC_KEYFILE,
> ssh_pub_key_file );
> curl_easy_setopt ( curl, CURLOPT_SSH_PRIVATE_KEYFILE,
> ssh_priv_key_file );
> curl_easy_setopt ( curl, CURLOPT_KEYPASSWD,
> ssh_pass ); /* note this does not work */
>
> curl_easy_setopt ( curl, CURLOPT_USERPWD,
> "username:password"); /* need this .. don't know why */
> curl_easy_setopt ( curl, CURLOPT_VERBOSE,
> 1L );
>
> curl_easy_setopt ( curl, CURLOPT_DEBUGFUNCTION,
> my_trace );
>
> curl_easy_setopt ( curl, CURLOPT_DEBUGDATA,
> &config );
>
> curl_easy_setopt ( curl,
> CURLOPT_NOPROGRESS, 0L );
>
> curl_easy_setopt ( curl,
> CURLOPT_SSL_VERIFYPEER, 0L );
>
> curl_easy_setopt ( curl,
> CURLOPT_STDERR, logfile );
>
> /* just re-read the file for now */
> curl_easy_setopt ( curl,
> CURLOPT_READFUNCTION, NULL );
>
> /* supply the file here */
> curl_easy_setopt ( curl,
> CURLOPT_READDATA, inputdat );

...so when it's read by libcurl, there's nothing left to read. Hence, a 0-byte
file on the other side. Adding a rewind(inputdat) should fix this, as would
sending the data already read from that buffer instead of reading from the
file again.

>
> /* using SCP CURLOPT_INFILESIZE is needed */
> /* note that CURLOPT_INFILESIZE_LARGE requires type curl_off_t
> */
> curl_easy_setopt ( curl, CURLOPT_INFILESIZE,
> (long) datfid.st_size );
>
> /* Perform the request, res will get the return code */
> res = curl_easy_perform ( curl );
>
> /* Check for errors */
> if ( res != CURLE_OK ) {
> fprintf ( stderr, "FAIL : curl_easy_perform() failed: %s\n",
> curl_easy_strerror ( res ) );
> fprintf ( stderr, "FAIL : res = %d (write_error = %d)\n",
> res, wr_error );
> free ( dat_buffer );
> return ( EXIT_FAILURE );
> }
>
> /* now extract transfer info */
> curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
> curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
>
> fprintf ( stderr, " %.3f bytes/sec for %.3f secs\n",
> speed_upload, total_time);
>
> /*
> * we should null terminate the reply
> * with some sort of data[write_result.pos] = '\0';
> */
> printf( "res = %d (write_error = %d)\n", res, wr_error );
>
> curl_easy_cleanup ( curl );
>
> } else {
> printf ( "\nFAIL : curl init fail.\n" );
> free ( dat_buffer );
> return ( EXIT_FAILURE );
> }
>
> curl_global_cleanup();
>
> fflush ( logfile );
> fclose ( logfile );
> free ( dat_buffer );
> return ( EXIT_SUCCESS ) ;
>
>
>
>
> Mostly that is cleaned up for this email but the options and steps are
> correct.
>
> Now perhaps I need to check the size of the file and perhaps the
> connection ever closes because ... don't know. Any insights are
> appreciated.
>
>
> Dennis
>
> ps: yes .. even though I provide the passphrase I had to resort to
> username and password to auth. That's a separate mystery.

The username is needed so the remote side knows who's trying to log in. If
you're using a public key as authenticator, you can leave the password empty.

>>> Dan
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-users
FAQ: http://curl.haxx.se/docs/faq.html
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2014-04-25