Python sshtunnel - How to Validate SSH Connection? - python

Using Python, how might I validate that SSH connection is successful after the following:
server = SSHTunnelForwarder(
(host_or_ip, 22),
ssh_username = "ssh_username",
ssh_private_key = path_to_key,
remote_bind_address = (another_host_or_ip, 5432)
)
server.start()

I use this to see if tunnel is open:
server.skip_tunnel_checkup = False
server.start()
server.check_tunnels()
print(server.tunnel_is_up, flush=True)
And in the log you will see :
{('0.0.0.0', 44004): True} # this tunnel is up
{('0.0.0.0', 44004): False} # this tunnel is not up

You can do that using a try-exceptblock.
ssh_address_or_host = ...
ssh_username = ...
ssh_password = ...
remote_bind_address = ...
try:
with SSHTunnelForwarder(
ssh_address_or_host = ssh_address_or_host,
ssh_username = ssh_username,
ssh_password = ssh_password,
remote_bind_address = remote_bind_address
) as server:
print("connected")
except Exception as e:
print("Non connected because: " + e)

Related

Python: message not sending in sockets

I'm working in a sockets Python project, I encountered a bug in where I was not able to send two or more different messages from server to client. Here, for example, if the client requests to log in, the server answers with [CODE 10] Log in request and immediatly I wanted to respond if the log in was successful or not:
conn.send("[CODE 10] Log in request".encode(FORMAT))
success_login = login(current_username, current_password)
if success_login:
conn.send("[CODE 110] Log in successful".encode(FORMAT))
else:
conn.send("[CODE 111] Log in error".encode(FORMAT))
Instead I must press enter in client prompt between [CODE 10] Log in request and one of CODE 110 or CODE 111 response, is the anything wrong with my implementation?
I think it has to deal with client.py in the infinite loop but not sure how to fix it, can anyone tell me what I am doing wrong?
client.py
import socket
HEADER = 64
PORT = 9999
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'
SERVER = 'localhost'
ADDRESS = (SERVER,PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 9999))
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(1024).decode(FORMAT))
while True:
msg = input()
if msg.encode() == DISSCONECT_MESSAGE:
print("[DISSCONECTED FROM SERVER]")
client.send(DISSCONECT_MESSAGE)
break
else:
send(msg)
server.py
import socket
import threading
from dbms import *
HEADER = 64
PORT = 9999
SERVER = socket.gethostbyname(socket.gethostname())
ADDRESS = ('',PORT)
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'
exec(open('dbms.py').read())
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDRESS)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length == '0': # DISSCONECT_MESSAGE decoded
connected = False
break
elif msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
# sign in
if msg[:2] == "50":
new_usuario = msg.split()[1]
new_password = msg.split()[2]
conn.send("[CODE 50] Request to sign in".encode(FORMAT))
success_insert = insert(new_usuario , new_password)
if success_insert:
conn.send("[CODE 510] Sign in successful".encode(FORMAT))
else:
conn.send("[CODE 511] Sign in error".encode(FORMAT))
# log in
if msg[:2] == "10":
current_username = msg.split()[1]
current_password = msg.split()[2]
conn.send("[CODE 10] Solicitud para inicio de sesion".encode(FORMAT))
success_login = login(current_username, current_password)
if success_login:
conn.send("[CODE 110] Log in successful".encode(FORMAT))
else:
conn.send("[CODE 111] Log in error".encode(FORMAT))
print(f"[{addr}] {msg}")
conn.send("Message recived".encode(FORMAT))
print(f"[{addr}] DISSCONNECTED")
conn.close()
exit()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept() # Wait to a new connection
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount()-1}")
print("[STARTING] Server is starting...")
start()
exit()
dbms.py
import psycopg2
print("[IMPORT] dbms.py imported correctly")
conn_db = psycopg2.connect(database="aaa", user = "bbb", password = "ccc", host = "127.0.0.1", port = "5432")
print("[DATABASE] Successfully connected with database")
cursor = conn_db.cursor()
def insert(new_usuario,new_password):
try:
postgres_insert_query = """ INSERT INTO users (username, password) VALUES (%s,%s) """
record_to_insert = (new_usuario, new_password)
cursor.execute(postgres_insert_query, record_to_insert)
conn_db.commit()
count = cursor.rowcount
print(count, "[DATABASE] Record inserted successfully into USERS table")
return True
except (Exception, psycopg2.Error):
if(conn_db):
print("[ERROR] Failed to insert record into table USERS")
return False
def login(current_username, current_password):
""" Validate if a user already exists in DB """
try:
postgres_query = """SELECT username, password FROM users WHERE username = %s AND password = %s"""
record_to_validate = (current_username, current_password)
cursor.execute(postgres_query, record_to_validate)
count = cursor.rowcount
print(count, "[DATABASE] Credentials validated successfully")
return True
except (Exception, psycopg2.Error):
if(conn_db):
print("[ERROR] Failed to validate credentials")
return False

i want use sshtunnel reconnect and query database with database of pythonanywhere

import sshtunnel
import time
import logging
import mysql.connector
class SelectCommand():
def __init__(self,dbcmd,value = None, mul = False):
self.dbcmd = dbcmd
self.value = value
self.mul = mul
def execute(self):
try:
print("try1")
connection = mysql.connector.connect(
user='**myuser**', password='**pass**',
host='127.0.0.1', port=server.local_bind_port,
database='**myuser$test**', autocommit = True
)
print("try2")
connection.autocommit = True
mycursor = connection.cursor()
sql = self.dbcmd
val = self.value
mycursor.execute(sql, val)
myresult = mycursor.fetchone()
mycursor.close()
connection.close()
if myresult == None or self.mul == True:
return myresult
return myresult[0]
except Exception as e:
print(e)
return "server disconnect "
sshtunnel.SSH_TIMEOUT = 5.0
sshtunnel.TUNNEL_TIMEOUT = 5.0
def get_server():
#sshtunnel.DEFAULT_LOGLEVEL = logging.DEBUG
server = sshtunnel.SSHTunnelForwarder(
('ssh.pythonanywhere.com'),
ssh_username='**myuser**', ssh_password='**mypass**',
remote_bind_address=('**myuser.mysql.pythonanywhere-services.com**', 3306))
return server
server = get_server()
server.start()
while True :
if(server.is_active):
print("alive... " + (time.ctime()))
print(SelectCommand("SELECT * FROM A_table WHERE id = %s", (1,), mul = True).execute())
else:
print("reconnecting... " + time.ctime())
server.stop()
server = get_server()
server.start()
time.sleep(8)
Now i want use sshtunnel connect with database of pythonanywhere, and i want check connecting of sshtunnel if connect do select command else wait for new connecting. i try do Python: Automatically reconnect ssh tunnel after remote server gone down . but my problem is when i query database i try turn off my WIFI
my console show this message (Could not establish connection from ('127.0.0.1', 54466) to remote side of the tunnel) and Socket exception: An existing connection was forcibly closed by the remote host (10054) then it's result to stopping of my program. How can i fix.

Python multiple clients chatting across a server

The server is not broadcasting the sent messages back to the clients. The server is also not seeing the messages but is seeing that there is something being sent via the broadcast. The client who sends the message should not be sent the message again.
ChatClient
import socket, threading
def send():
while True:
msg = raw_input('\nMe : ')
cli_sock.send(msg)
def receive():
while True:
sen_name = cli_sock.recv(1024)
data = cli_sock.recv(1024)
print('\n' + str(sen_name) + ' : ' + str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
uname = raw_input('Enter your name to enter the chat : ')
cli_sock.send(uname)
thread_send = threading.Thread(target = send)
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
ChatServer
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
thread_client = threading.Thread(target = broadcast_usr, args=
[uname, cli_sock])
thread_client.start()
def broadcast_usr(uname, cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
print "{0} spoke".format(uname)
b_usr(cli_sock, uname, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for client in CONNECTION_LIST:
if client[1] != cs_sock:
client[1].send(sen_name)
client[1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
The expected should be if user is Dan(me):
John: Hi
Me: Hi
Me: How are you
John: Great
Stephen: Awesome
The actual is only displaying the "Me" on the specific client's side

How to keep trying to establish connection in Python

If the server is not up when I try to run the following code, I just get a Connection refused error.
How can I make the sender below to keep trying to establish connection and perhaps sending until the remote server is indeed up and the connection is successfully established?
HOST = client_ip # The remote host
PORT = port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(msg)
if expect_receive:
received_data = s.recv(1024)
print received_data
#client has started
s.close()
return
How about brute force? Something like this
import time
while 1:
HOST = client_ip # The remote host
PORT = port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((HOST, PORT))
except:
print("FAILED. Sleep briefly & try again")
time.sleep(10)
continue
s.sendall(msg)
if expect_receive:
received_data = s.recv(1024)
print received_data
#client has started
s.close()
return
I am using ssl with threads and the following works for me.
import socket, ssl
from threading import *
from _thread import *
from time import sleep
HOST_1, PORT_1, CERT_1 = '127.0.0.1', 443, 'certificate_1.pem'
HOST_2, PORT_2 = '127.0.0.1', 4430
def enviar():
#global morte;
sock = socket.socket(socket.AF_INET)
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH);
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
context.check_hostname = False;
context.load_verify_locations(cafile='certificate_2.pem');
conn = context.wrap_socket(sock, server_hostname=HOST_2);
while True:
try:
conn.connect((HOST_2, PORT_2));
break;
except:
print("\n=====Failed connection=====\n");
sleep(1);#vital, without it the script raises an exception
try:
while True:
x = input("--> ");
x = bytes(x, "utf-8");
conn.write(x)
print(conn.recv().decode())
except ssl.SSLError as e:
print(e);
except Exception as e:
print(e);
except KeyboardInterrupt:
print("\n====Bye!====\n");
if conn:
conn.close();
#morte = True;
###################
#parte original abaixo
def receber():
sock = socket.socket();
sock.bind((HOST_1, PORT_1));
sock.listen(5);
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH);
context.load_cert_chain(certfile=CERT_1, keyfile="private_1.pem") # 1. key, 2. cert, 3. intermediates
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # optional
context.set_ciphers('EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH')
while True:
conn = None;
ssock, addr = sock.accept();
try:
conn = context.wrap_socket(ssock, server_side=True);
while True:
print(conn.recv());
conn.write(b'HTTP/1.1 200 OK\n\n%s' % conn.getpeername()[0].encode());
break
except ssl.SSLError as e:
print(e)
except Exception as e:
print(e);
if conn:
conn.close();
finally:
if conn:
conn.close()
print("End!");
if __name__ == '__main__':
start_new_thread(receber, ());#1
start_new_thread(enviar, ());#2
If you run in association with another similar script (using other private key and certificates, obviously) it will run mostly ok, but, it will raise an:
EOF occurred in violation of protocol (_ssl.c:2472)
I am still trying to figure out how to deal with it.

Python Networked Chat

I was working on a networked chat by following a tutorial. I have two modules, chatServer.py3 and chatClient.py3. On starting the server and then a client and attempting to send a message I get the following error:
Traceback (most recent call last): File "chatClient.py3", line 49,
in <module>
Main() File "chatClient.py3", line 38, in Main
s.sendto(alias+": "+message, server)
socket.error: [Errno 57] Socket is not connected
Please keep in mind that I am a rookie and therefore I would appreciate if the solutions along with their explanations were simplistic.
chatClient.py3
import socket, time, threading
tLock = threading.Lock()
shutdown = False
def recieveing(name,sock):
locked = False
while not shutdown:
try:
tLock.aquire()
locked = True
while True:
data , addr = sock.recv(1024)
print str(data)
except:
pass
finally:
if locked:
tLock.release()
def Main():
host = '127.0.0.1'
port = 0
server = ('127.0.0.1', 5000)
s = socket.socket()
s.bind((host,port))
s.setblocking(0)
rT = threading.Thread(target=recieveing,args=("RecivedThread",s))
rT.start()
alias = raw_input("Name: ")
message = raw_input(alias+"-> ")
while message != "q":
if message != "":
s.sendto(alias+": "+message, server)
tLock.aquire()
message = raw_input(alias+"-> ")
tLock.release()
time.sleep(0.2)
shutdown = True
rT.join()
s.close()
if __name__ == '__main__':
Main()
chatServer.py3
import socket,time
host = '127.0.0.1'
port = 5000
clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.setblocking(0)
quitting = False
print "Server Started."
while not quitting:
try:
data, addr = s.recvfrom(1024)
if "Quit" in str(data):
quitting = True
if addr not in clients:
clients.append(addr)
print time.ctime(time.time()) + str(addr) + " : : "+str(data)
for client in clients:
s.sendto(data, client)
except:
pass
s.close()
You don't need to bind your client to the host and port. The bind command defines where the server needs to listen. The client needs to connect to the server. Like this:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server = ('127.0.0.1', 5000)
s.connect(server)

Categories

Resources