pysftp gives pysftp.exceptions.ConnectionException: (host, port) with no details on it - python-2.7

I'm trying to connect to sftp server with pysftp library. Here is my code:
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection("sftp://host", "login", "password", cnopts=cnopts) as sftp:
sftp.listdir()
It gives me exception:
pysftp.exceptions.ConnectionException: ('host', port)
But I have no clue what this exception means and what the problem is.

You don't have much explanation because this library has bugs. See the source code on BitBucket.
The ConnectionException class is not well implemented:
class ConnectionException(Exception):
"""Exception raised for connection problems
Attributes:
message -- explanation of the error
"""
def __init__(self, host, port):
# Call the base class constructor with the parameters it needs
Exception.__init__(self, host, port)
self.message = 'Could not connect to host:port. %s:%s'
As you can see, the format 'Could not connect to host:port. %s:%s' is not filled with the host and port values.
However, the name of the exception is clear: you have a connection error.
The details of the error are, unfortunately, lost:
def _start_transport(self, host, port):
'''start the transport and set the ciphers if specified.'''
try:
self._transport = paramiko.Transport((host, port))
# Set security ciphers if set
if self._cnopts.ciphers is not None:
ciphers = self._cnopts.ciphers
self._transport.get_security_options().ciphers = ciphers
except (AttributeError, socket.gaierror):
# couldn't connect
raise ConnectionException(host, port)
You can try to get the last error (not sure):
import sys
sys.exc_info()
note: I suggest you to use another library (for instance Paramiko).

Related

unable to post data to mosquitto broker continuously

I am trying to send data continuously from raspberry pi to a windows pc using MQTT,
I am trying to send 5 data to mosquitto, but the mosquitto seems to get only one value
coding in raspberry pi
import paho.mqtt.client as mqtt
client=mqtt.Client()
client.connect("192.168.0.104",1883,60)
for i in range(0,5):
data={"protocol":"mqtt"}
client.publish("/test",str(data))
coding at the broker to receive data is
import paho.mqtt.client as mqtt
print("attempting to connect...")
def on_connect(client, userdata, flags, rc):
if(rc==0):
print("connection successful broker linked")
elif(rc==1):
print("connection refused - incorrect protocol version")
elif(rc==2):
print("connection refused - invalid client identifier")
elif(rc==3):
print("connection refused- server unavailable")
elif(rc==4):
print("connection refused- bad username or password")
elif(rc==5):
print("connection refused- not authorised")
else:
print("currently unused")
client.subscribe("s/test")
def on_message(client, userdata, msg):
data=eval(msg.payload)
print(data)
client = mqtt.Client()
client.connect("localhost",1883,60)
client.on_connect = on_connect
client.on_message = on_message
client.loop_forever()
Have you thought about following the answer I posted here?
https://github.com/eclipse/mosquitto/issues/972
You need to make sure the network loop runs for the publishing client as well a the subscriber. The network loop actually handles sending the messages.
The following is the simplest modification to your code.
import paho.mqtt.client as mqtt
client=mqtt.Client()
client.connect("192.168.0.104",1883,60)
for i in range(0,5):
data={"protocol":"mqtt"}
client.publish("/test",str(data))
client.loop()

Python 2.7 portScanner

I am wondering why my portScanner module runs and claims that all my ports are closed?
I am running Python 2.7 because thats what Violent Python(the book) uses.
Only solution I have tried so far was I have set my DNS to 8.8.8.8 and secondary to 8.8.4.4 because my socket takes 'www.google.com' as the Ip.
Code:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverIp = socket.gethostbyname('www.google.com')
def pscan(port):
try:
s.connect((serverIp,port))
return True
except:
return False
for x in range(1,101):
if pscan(x):
print("Port %d is open!!!" % (x))
else:
print("Port %d is closed" % (x))
You only create a single socket and try to use it in multiple connect's. This is not possible. If you look at the details of the Exception you will notice that the first one (port 1) fails slowly because the connect timed out but the following ones all fail quickly because of "Operation already in progress".
The fix is to create a new socket before each connect. Additionally it might be helpful to reduce the time it tries to connect with s.settimeout(1).

python SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),))

I was scraping this aspx website https://gra206.aca.ntu.edu.tw/Temp/W2.aspx?Type=2 .
As it required, I have to parse in __VIEWSTATE and __EVENTVALIDATION while sending a post request. Now I am trying to send a get request first to have those two values, and then parse then afterward.
However, I have tried several times to send a get request. It always turns out throwing this error message:
requests.exceptions.SSLError: HTTPSConnectionPool(host='gra206.aca.ntu.edu.tw', port=443): Max retries exceeded with url: /Temp/W2.aspx?Type=2 (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),))
I have tried:
upgrade OpenSSL
download requests[security]
However, none of them works.
I am currently using:
env:
python 2.7
bs4 4.6.0
request 2.18.4
openssl 1.0.2n
Here is my code:
import requests
from bs4 import BeautifulSoup
with requests.Session() as s:
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
url = 'https://gra206.aca.ntu.edu.tw/Temp/W2.aspx?Type=2'
r = s.get(url, headers={'x-test2': 'true'})
soup = BeautifulSoup(r.content, 'lxml')
viewstate = soup.find('input', {'id': '__VIEWSTATE' })['value']
validation = soup.find('input', {'id': '__EVENTVALIDATION' })['value']
print viewstate, generator, validation
I am also looking for a solution for it. Some sites have deprecated TLSv1.0 and Requests + Openssl (on Windows 7) has trouble to build handshake with such peer host. Wireshark log showed the TLSv1 Client Hello was issued by the client but the host did not answer correctly. This error propagated up as the error message Requests showed. Even with the most updated Openssl/pyOpenssl/Requests and tried on Py3.6/2.7.12, no luck. Intrestingly when I replace the url to other like "google.com", the log showed TLSv1.2 Hello was issued and responded by the host. Please check images tlsv1 and
tlsv1.2.
Clearly the client has TLSv1.2 capability but why it use v1.0 Hello in the former case?
[EDIT]
I was wrong in previous statement. Wireshark misinterpreted unfinished TLSv1.2 HELLO exchanged as TLSv1. After more digging into it, I found these hosts is expecting pure TLSv1, but not a TLSv1 fallback from TLSv1.2. Due to Openssl's lack of some fields in the Hello extension fields (maybe Supported Version) when compared with the log from Chrome. I found a workaround to it. 1. Force the use of TLSv1 negotiation. 2. Change the default cipher suite to py3.4 style to re-enable 3DES.
import ssl
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
#from urllib3.poolmanager import PoolManager
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
# py3.4 default
CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
'!eNULL:!MD5'
)
class DESAdapter(HTTPAdapter):
"""
A TransportAdapter that re-enables 3DES support in Requests.
"""
def create_ssl_context(self):
#ctx = create_urllib3_context(ciphers=FORCED_CIPHERS)
ctx = ssl.create_default_context()
# allow TLS 1.0 and TLS 1.2 and later (disable SSLv3 and SSLv2)
#ctx.options |= ssl.OP_NO_SSLv2
#ctx.options |= ssl.OP_NO_SSLv3
#ctx.options |= ssl.OP_NO_TLSv1
ctx.options |= ssl.OP_NO_TLSv1_2
ctx.options |= ssl.OP_NO_TLSv1_1
#ctx.options |= ssl.OP_NO_TLSv1_3
ctx.set_ciphers( CIPHERS )
#ctx.set_alpn_protocols(['http/1.1', 'spdy/2'])
return ctx
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = self.create_ssl_context()
return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = self.create_ssl_context()
return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
tmoval=10
proxies={}
hdr = {'Accept-Language':'zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4', 'Cache-Control':'max-age=0', 'Connection':'keep-alive', 'Proxy-Connection':'keep-alive', #'Cache-Control':'no-cache', 'Connection':'close',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36',
'Accept-Encoding':'gzip,deflate,sdch','Accept':'*/*'}
ses = requests.session()
ses.mount(url, DESAdapter())
response = ses.get(url, timeout=tmoval, headers = hdr, proxies=proxies)
[EDIT2]
When your HTTPS url contains any uppercase letter, the patch would fail to work. You need to reverse them to lowercase. Something unknown in the stack requests/urllib3/openssl cause the patch logic being restored to its default TLS1.2 fashion.
[EDIT3]
from http://docs.python-requests.org/en/master/user/advanced/
The mount call registers a specific instance of a Transport Adapter to a prefix. Once mounted, any HTTP request made using that session whose URL starts with the given prefix will use the given Transport Adapter.
So, to make all HTTPS requests include those redirected by the server afterwards to use the new adapter, must change this line to:
ses.mount('https://', DESAdapter())
Somehow it fixed the uppercase problem mentioned above.

How can I get around Name too long for LOGINREC in pymssql without changing the username

I am attempting to use pymssql to connect to a client's database, but have thus far been unable to succeed. I believe that the root of the problem is this entry in the stack trace of my TDSDUMP:
dblib.c:761:dbsetlname(0x1ac3e10, <username>#<servername>.database.windows.net, 2)
dblib.c:7929:dbperror((nil), 20042, 0)
dblib.c:7981:20042: "Name too long for LOGINREC field"
One problem is that <servername>.database.windows.net already exceeds the string limit (which seems to be 30 according to this: How to use PHP's dblib PDO driver with long usernames? / SQLSTATE[HY000] Name too long for LOGINREC field (severity 2)).
I have also attempted to exclude the #<servername>.database.windows.net portion in the username entry only to receive the following error:
msgno 40532: "Cannot open server "1433D" requested by the login. The login failed."
According to https://github.com/pymssql/pymssql/issues/330 the #<servername> portion is requested by the server.
So at this point, I attempted to do the following:
user = username + "#{}".format(server)
user = user[:30]
And I received the following information (which was a slight improvement but still not ideal, given that I could still not establish the connection):
"Cannot open server "<server_name minus the last 6 characters>" requested by the login. The login failed."
If possible, I would prefer passing some parameter to pymssql's connect method that would override this character limit or do something to append the server to the username on the backend after calling dbsetlname on just <username> without the #<servername> portion. Does anyone have any recommendations (again the preference is to not ask the client to change our username, but we may have to resort to that or trying to use pyodbc if there's no other option).
These are a few of the connection methods I have tried:
conn = pymssql.connect(
host=host,
database=database,
user=username,
password=password,
port=int(port) # this is 1433
)
conn = pymssql.connect(
host=host,
database=database,
user=username + '#{}'.format(servername),
password=password,
port=int(port) # this is 1433
)
conn = pymssql.connect(
server=<servername>.database.windows.net,
database=database,
user=username,
password=password,
port=int(port) # this is 1433
)
Thanks in advance for any help/advice that you may be able to offer!
You can probably use an alternate connecting string method.
If you're using SQL Server Auth, try this:
conn = pymssql.connect(
server="<servername>.database.windows.net",
port=1433,
user="username",
password="password",
database="dbname"
)
If you're using Windows Auth:
conn = pymssql.connect(
server="<servername>.database.windows.net",
port=1433,
user="DOMAIN\USERNAME",
password="password",
database="dbname"
)
Have you tried either of these connect methods?

Python telnet connection refuse exception

I'm using following function to make telnet connection verification
telnetlib.Telnet("172.28.5.240", "8080")
When the connection refused it shows exception message. Is it possible to hide the message and detect as success or failed through if condition?
You can use try-except-finally blocks
try:
#
#
response = 'Success'
except:
response = 'Failed'
finally:
print response
Based on Suku's answer I develop my code. that is a working answer. And following is my script for reference.
try:
conn = telnetlib.Telnet("172.28.5.240", "80")
response = 'Success'
except:
response = 'Failed'
finally:
print response
None of the options helped me.
Maybe someone will come in handy.
100% working version:
Used to check the availability of the RDP server in ZABBIX:
import telnetlib
response = ''
HOST = '192.168.1.201'
PORT = 3389
tn = telnetlib.Telnet()
try:
tn.open(HOST, PORT, 3)
response = '2'
except Exception:
response = '0'
finally:
tn.close()
print(response)