Python FTP to iPad - python

I'm on Windows 7.
I cannot connect to my iPad with a simple Python script:
HOST = '192.168.1.122'
try:
f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
MessageBox.Show('ERROR: cannot reach "%s"' % HOST)
return
try:
f.connect(HOST,2121)
f.login()
except ftplib.error_perm:
MessageBox.Show('ERROR: cannot login anonymously')
f.quit()
return
The errors I have is "getaddrinfo returns an empty list" and the "cannot reach..." message... Cannot solve it...
I tried to FTP with several programs on the iPad without success. If I FTP via DOS box or using a FTP software it works. I tried as well another FTP server on my PC and it works.
I am forced to use port 2121, so can't change it.
Any clue or experience?

You should read docs before anything:
class ftplib.FTP([host[, user[,
passwd[, acct[, timeout]]]]]) Return a
new instance of the FTP class. When
host is given, the method call
connect(host) is made. When user is
given, additionally the method call
login(user, passwd, acct) is made
(where passwd and acct default to the
empty string when not given). The
optional timeout parameter specifies a
timeout in seconds for blocking
operations like the connection attempt
(if is not specified, the global
default timeout setting will be used).
So, if you do f = ftplib.FTP(HOST) it fails because it will try to connect to standard port (21) and not 2121.
You should get an instance of ftplib and later use f.connect(HOST, 2121).
http://docs.python.org/library/ftplib.html

Related

Checking ip:port is open on remote host

I have a list of servers and ip:ports (external addressses) and i need to check if each server can connect to those addresses.
Looping through the file and trying to open an sshtunnel and doing connect as below
tunnel=sshtunnel.SSHTunnelForwarder(
ssh_host=host,
ssh_port=22,
ssh_username=ssh_username,
ssh_pkey=privkey,
remote_bind_address=(addr_ip, int(addr_port)),
local_bind_address=('0.0.0.0', 10022)
#,logger=sshtunnel.create_logger(loglevel=10)
)
tunnel.start()
# use socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect(('localhost', 10022))
print(res)
#s.connect((addr_ip, int(addr_port)))
s.close()
except socket.error as err:
print('socket err:')
print(err)
finally:
s.close()
time.sleep(2)
tunnel.stop()
When i do this though, the response is always 0 (i.e. the sock can connect to the local bind) even if the remote is incorrect - however sshtunnelforwarder throws
ERROR | Secsh channel 0 open FAILED: Network is unreachable: Connect failed
ERROR | Could not establish connection from ('127.0.0.1', 10022) to remote side of the tunnel
How do I make my socket command check if the remote_bind_address is available?
I tried to do use telnetlib, but get a similar issue
the code is effectively the same with the socket block replaced with
tn=telnetlib.Telnet()
tn.open('localhost',10022)
tn.close()
Im relatively new to all this, so still learning. If there is a better way to achieve what i need to do please let me know.
Thanks
Set the attribute skip_tunnel_checkup to False to enable checking of the remote side availability (it's disabled by default for backwards compatibility):
tunnel.skip_tunnel_checkup = False
Adding this before starting the tunnel checks the remote side is up on start and throws an exception which can be handled.
Removed my socket code.
I haven't tried that, but there's the tunnel_is_up attribute of the SSH tunnel class, which according to the documentation:
Describe whether or not the other side of the tunnel was reported to be up (and we must close it) or not (skip shutting down that tunnel)
Example of its content (it's a dictionary):
{('127.0.0.1', 55550): True, # this tunnel is up
('127.0.0.1', 55551): False} # this one isn't
So you shouldn't need to make an explicit connection yourself.
Note: you may need to set the attribute skip_tunnel_checkup to False (which is True by default for backwards compatibility) first before setting up the tunnel, otherwise tunnel_is_up may always report True:
When skip_tunnel_checkup is disabled or the local bind is a UNIX socket, the value will always be True
So the code may look like:
tunnel=sshtunnel.SSHTunnelForwarder(
# ...
)
tunnel.skip_tunnel_checkup = False
tunnel.start()
# tunnel.tunnel_is_up should be populated with actual tunnel status(es) now
In the code you posted, you're setting up a tunnel and then just opening a socket to the local endpoint of the tunnel, which is apparently open no matter what state the tunnel is in, so it always connects successfully.
Another approach would be to actually try to establish an SSH connection through the tunnel, but that's the paramiko.SSHclient alternative you're mentioning in a comment I guess.

With pysftp, how can I specify a timeout value for the connection?

With pysftp, I see how to set a timeout for any commands once you're already connected, but I don't see how to set a timeout for the connection itself. I feel like I'm missing something somewhere. Just to try it, I tried adding timeout=3 to the Connection method and got an error, and tried using cnopts.timeout=3 and that did nothing at all. For the record, I'm using Python 3 on Windows, if that affects anything.
Here's some simple test code you can experiment with, if it helps. (As is, the connection times out after about 30 seconds.)
import pysftp
print("\n"*25)
cnopts=pysftp.CnOpts()
# - I know this next line is insecure, it's just for this test program.
cnopts.hostkeys = None
print('Connecting...')
# - 8.8.8.8 is Google's public DNS server. It doesn't respond to sftp requests at all,
# - so it's a good test case for how long a connection timeout takes.
with pysftp.Connection('8.8.8.8', username='anonymous', password='password',
cnopts=cnopts) as SFTP:
print("Wait, how did you get this far?")
print("Done.")
It does not look like that pysftp allows setting a connection timeout.
You can use Paramiko directly instead (pysftp is just a wrapper around Paramiko).
Paramiko SSHClient.connect method has timeout parameter.
ssh = paramiko.SSHClient()
ssh.connect(host, username=username, password=password, timeout=timeout)
sftp = ssh.open_sftp()
you can do it with:
Connection.timeout (35000)

Python - ftplib.FTP_TLS Port

Can someone help me confirm the default port when using ftplib.FTP_TLS? We have opened port 990 and 21 but my script fails to connect.
import ftplib
session = ftplib.FTP_TLS('xxx.ftp.com','user','password')
file = open('Bkup.tar.gz','rb')
session.storbinary('STOR Bkup.tar.gz', file)
file.close()
session.quit()
Thank You!
You could try:
ftplib.FTP_TLS.port = 21
According to it's own documentation, as well as the spec, FTPS (or FTP over TLS) connects to port 21.
You appear to be missing a login clause to authenticate the session.
Try calling session.login() followed by session.prot_p() before attempting to store the binary.
This documentation can be found by using the help function or in the online documentation here.
I hope that helps.
Please don't modify the port directly. If you get a closer look at FTP_TLS super __init__ you can clearly see that if it's called with a host param connect gets automatically called with just the host as param so the port defaults to FTP_PORT which is 21.
A better approach would be to call FTP_TLS without any params and then manually call the connect method where you can specify host as well as port.
from ftplib import FTP_TLS
client = FTP_TLS()
client.connect(host="ftp.example.com", port=12121)
Oddly, the FTP_TLS object has no direct port parameter on the constructor like the FTP object does.
you can set the port prior to calling the constructor and that works.
ftplib.FTP_TLS.port=1234
ftplib.FTP_TLS( 'ftphost.domain.tld', 'user', 'password' )

FTP Connection/Instantiation Hangs Application

I am attempting to open a connection via FTP using the following simple code. But the code is just hanging at this line. Its not advancing, its not throwing any exceptions or errors. My code is 6 months old and I've been able to use this code to connect to my website and download files all this time. Today its just started to hang when I go to open a FTP connection.
Do you know what could be going wrong?
ftp = ftplib.FTP("www.mySite.com") # hangs on this line
print("Im alive") # Never get printed out
ftp.login(username, password)
I administer the website with a couple of other people but we haven't changed anything.
Edit: Just tried to FTP in using Filezilla with the same username and password and it failed. The output was:
Status: Resolving address of www.mySite.com
Status: Connecting to IPADDRESS...
Status: Connection established, waiting for welcome message...
Error: Connection timed out
Error: Could not connect to server
Status: Waiting to retry...
Status: Resolving address of www.mySite.com
Status: Connecting to IPADDRESS...
Status: Connection established, waiting for welcome message...
Error: Connection timed out
Error: Could not connect to server
Looks like you have server issues, but if you'd like the Python program to error out instead of waiting forever for the server, you can specify a timeout kwarg to ftplib.FTP. From the docs (https://docs.python.org/2/library/ftplib.html#ftplib.FTP)
class ftplib.FTP([host[, user[, passwd[, acct[, timeout]]]]])
Return a new instance of the FTP class. When host is given, the method call connect(host) is made. When user is given, additionally
the method call login(user, passwd, acct) is made (where passwd and
acct default to the empty string when not given). The optional timeout
parameter specifies a timeout in seconds for blocking operations like
the connection attempt (if is not specified, the global default
timeout setting will be used).
Changed in version 2.6: timeout was added.

paramiko no existing session exception

Using the python interactive shell and openssh running locally, I keep getting an "No existing session" exception using paramiko. My code is below.
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('localhost',username=name,password=pw)
Results in:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/paramiko-1.7.7.1-py2.6.egg/paramiko/client.py", line 332, in connect
self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
File "/usr/local/lib/python2.6/dist-packages/paramiko-1.7.7.1-py2.6.egg/paramiko/client.py", line 493, in _auth
raise saved_exception
paramiko.SSHException: No existing session
I was able to connect previously, but had been trying to adjust this to allow for key based authorization. That failed, and since then I have not been able to connect locally. I have tried restarting openssh, and have connected to another server successfully. After searching through here, all I have found are mentions of authorization exceptions, which does not appear to be the case here.
As you already have password you don't need to talk to agent or look for private keys stored on your machine. So try passing extra parameters allow_agent, look_for_keys:
ssh.connect('localhost',username=name,password=pw,allow_agent=False,look_for_keys=False)
I had a spare public key with a key pass phrase in my ssh-add list. Once I removed it, I was able to execute my paramiko based script properly.
To list:
ssh-add -l
To delete all:
ssh-add -D
To re-add:
ssh-add /FULL/PATH/TO/id_rsa
https://bugs.launchpad.net/paramiko/+bug/912123
Which OS are you using?
Maybe you can check your env variable:
SSH_AUTH_SOCK
for "connect", it will try to use ssh agent.
in agent.py
self.conn = None
self.keys = ()
if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'):
conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
conn.connect(os.environ['SSH_AUTH_SOCK'])
except:
# probably a dangling env var: the ssh agent is gone
return
self.conn = conn
elif sys.platform == 'win32':
import win_pageant
if win_pageant.can_talk_to_agent():
self.conn = win_pageant.PageantConnection()
else:
return
Just got the same error ERROR:SSHException('No existing session',) but since it was in a clean docker container, there was no ssh-agent.
After some hours of debugging, I found a different solution: it can happen when there is a timeout during key exchange! In my case, the ssh server is a router over GSM link, which is very slow.
You can enable debug on paramiko with:
logging.getLogger("paramiko").setLevel(logging.DEBUG)
And if you see the exception between the Connected and the Switch to new keys ..., it means the timeout was during the key exchange. In this case, you have to set timeout to a bigger value! (documentation says timeout is only for TCP connect, but in fact, it is also for the whole negotiation before auth!)
In my case ,I have try use allow_agent=False,look_for_keys=False, but not work .
I ssh to a 2G device, so timeout=10 is Ok, timeout=3 get" Unable to establish SSH connection: No existing session". Not timeout except.
So try timeout= a long time,if connect to a not establish ssh.
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,22,username,passwd,timeout=10,allow_agent=True,look_for_keys=True)
print ('%s\tOK\n'%(ip) )
except socket.timeout:
print ("%s time out"%(ip))
except paramiko.AuthenticationException:
print("Authentication failed, please verify your credentials: %s"%(ip))
except paramiko.SSHException as sshException:
print("Unable to establish SSH connection: %s" %(sshException))
except paramiko.BadHostKeyException as badHostKeyException:
print("Unable to verify server's host key: %s" %(badHostKeyException))
finally:
ssh.close()
Replace 'localhost' by '127.0.0.1'.

Categories