in reply to Re^4: sftp->do_write howto?
in thread sftp->do_write howto?

OK, I'm positive now: you have a permission problem om your remote host.
I've tried uploading to a directory with perm settings 000, and then I get the permission denied error message.

Here's a version with more testing code:

#!/usr/bin/perl # create a remote file, without creating a local file # use Net::SFTP; use Net::SFTP::Constants qw/:flags/; use strict; use warnings; my $filename = "testfile.dat"; my $file_data = "qwertyuiop"; my %args = ( user => 'insaniac', password => 'xxxx' ); #my $host = "moretrix.com"; my $host = "bear"; my $remote_path = 'not_allowed/'.$filename; my ($err_code, $err_mesg); print "Connecting to $host\n"; my $sftp; eval { $sftp = Net::SFTP->new($host,%args) }; ($err_code, $err_mesg) = $sftp->status; if($err_code){ print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "Open $host:$remote_path\n"; my $remote_handle; eval { $remote_handle = $sftp->do_open($remote_path, SSH2_FXF_WRITE | SSH +2_FXF_CREAT) }; ($err_code, $err_mesg) = $sftp->status; if($err_code){ print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "Write to remote file:\n$file_data\n"; eval { $sftp->do_write($remote_handle, 0, $file_data) }; ($err_code, $err_mesg) = $sftp->status; if($err_code){ print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "Close remote file handle\n"; $sftp->do_close($remote_handle);
The output of the script:
Connecting to bear Open bear:not_allowed/testfile.dat Couldn't get handle: Permission denied at net_sftp.pl line 33 Err_code:3 | err_mesg:Permission denied
And the directory on the remote host is:
bear: [/home/insaniac]# ls -ld not_allowed/ d--------- 2 root root 4096 Sep 23 13:40 not_allowed/

HTH

to ask a question is a moment of shame
to remain ignorant is a lifelong shame

Replies are listed 'Best First'.
Re^6: sftp->do_write howto?
by chrism01 (Friar) on Sep 27, 2005 at 06:12 UTC
    Here's the latest with your debug code:
    #!/usr/bin/perl use Net::SFTP; use Net::SFTP::Constants qw/:flags/; use strict; use warnings; my ( $filename, $payload, $host, $sftp, %args, $path, $handle, $err_code, $err_mesg ); $filename = "testfile.dat"; $payload = "qwertyuiop"; %args = (user => "yyyyyyyyyy", password => "xxxxxx"); $host = "a.b.c.d"; $path = "/network/www/ticketattach/".$filename; print "connecting\n"; eval { $sftp = Net::SFTP->new($host, %args) }; ($err_code, $err_mesg) = $sftp->status; if($err_code) { print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "open\n"; $handle = $sftp->do_open($path, SSH2_FXF_WRITE | SSH2_FXF_CREAT); #$handle = $sftp->do_open($path, 0x02| 0x08); ($err_code, $err_mesg) = $sftp->status; if($err_code) { print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "write\n"; $sftp->do_write($handle, 0, $payload); ($err_code, $err_mesg) = $sftp->status; if($err_code) { print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code }; print "close\n"; $sftp->do_close($handle); ($err_code, $err_mesg) = $sftp->status; if($err_code) { print "Err_code:$err_code | err_mesg:$err_mesg\n"; exit $err_code };
    and the response was...
    connecting Can't call method "status" on an undefined value at ./sftp.pl line 28.
    and as mentioned before I can ssh/sftp fine from the cmd line, but running this script from the same env manually does the above .. grrr... ie won't connect, forget about uploading.
    Cheers
    Chris
      Hm... further investigations make me think there's a bug in Net::SSH::Perl or Net::SFTP.

      try adding this to your code:

      my %args = ( user => 'user', password => 'password', ssh_args => [ debug => 1, options => [ "PreferredAuthentications 'keyboard-interactive,password,h +ostbased,publickey'", ] ], );
      and then:
      eval { $sftp = Net::SFTP->new($host, %args) }; die "Connection failed: $!\n" if $!; die "No SFTP object\n" unless $sftp;
      my output goes like:
      wolf: Reading configuration data /home/insaniac/.ssh/config wolf: Reading configuration data /etc/ssh_config wolf: Connecting to bear, port 22. wolf: Remote protocol version 2.0, remote software version OpenSSH_4.2 +p1 Debian-4 wolf: Net::SSH::Perl Version 1.28, protocol version 2.0. wolf: No compat match: OpenSSH_4.2p1 Debian-4. wolf: Connection established. wolf: Sent key-exchange init (KEXINIT), wait response. wolf: Algorithms, c->s: 3des-cbc hmac-sha1 none wolf: Algorithms, s->c: 3des-cbc hmac-sha1 none wolf: Entering Diffie-Hellman Group 1 key exchange. wolf: Sent DH public key, waiting for reply. wolf: Received host key, type 'ssh-dss'. wolf: Host 'bear' is known and matches the host key. wolf: Computing shared secret key. wolf: Verifying server signature. wolf: Waiting for NEWKEYS message. wolf: Enabling incoming encryption/MAC/compression. wolf: Send NEWKEYS, enable outgoing encryption/MAC/compression. wolf: Sending request for user-authentication service. wolf: Service accepted: ssh-userauth. wolf: Trying empty user-authentication request. wolf: Authentication methods that can continue: publickey,keyboard-int +eractive. wolf: Next method to try is publickey. wolf: Trying pubkey authentication with key file '/home/insaniac/.ssh/ +id_dsa' wolf: Authentication methods that can continue: publickey,keyboard-int +eractive. wolf: Next method to try is publickey. Connection failed: No such file or directory

      So when I try authenticating with an ssh-key, all works out perfectly. When I try to supply a username and a password, they seem to be ignored.. maybe we need to supply a specific value to ssh_args ?
      Per default, Net::SFTP uses the username that's executing the script as SSH username...

      I'll keep you informed if I find a solution...

      Cheers, Johnny

      to ask a question is a moment of shame
      to remain ignorant is a lifelong shame

      Of course! How foolish of me... all we needed was debugging enabled ;-)

      You're remote SSH server is *probably* not accepting cleartext password tunneling. In other words, its /etc/ssh/sshd_config is saying something like:

      PasswordAuthentication no
      And that's what's causing (my) error when trying to use a username and password for authentication. When I changed it to yes, and restarted the remote SSH server, the scripts works, because debugging now said:
      wolf: Sending request for user-authentication service.
      wolf: Service accepted: ssh-userauth.
      wolf: Trying empty user-authentication request.
      wolf: Authentication methods that can continue: publickey,password,keyboard-interactive.
      
      Where it used to be (with PasswordAuthentication no):
      wolf: Sending request for user-authentication service.
      wolf: Service accepted: ssh-userauth.
      wolf: Trying empty user-authentication request.
      wolf: Authentication methods that can continue: publickey,keyboard-interactive.
      
      So the above debugging says that the remote SSH server only accepts ssh keys or a keyboard interactive password..

      My advise is: create an ssh-key for the user that runs your script, and add the public key of that user to the authorized_keys file of your remote user. This is more secure than enabling clear text password tunneling ;-)

      HTH

      to ask a question is a moment of shame
      to remain ignorant is a lifelong shame

        Wolf,
        That's extremely enlightening and probably correct.
        The line in the config file is commented out, but I suspect it defaults to no (it's a BSD box).
        I certainly get the response you mentioned for 'no' when I added the debugging.
        It's been decided however that due to the low value of the info and multi-layer security (it's entirely an internal system) that we really don't need to take this any further.
        I'll certainly try and remember it for future ref though(!)
        I didn't realise there was a diff between interactive passwd and via a script. I assumed it'd use the same encryption/checking... wrong.. :-(
        Thx again
        Chris
        PS: how's your Net::SNMP? See my node 495954.