Created
March 10, 2025 22:34
-
-
Save mtward/675417e84f4e924f9b8144a8b4ad8d36 to your computer and use it in GitHub Desktop.
portchecker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/libexec/platform-python | |
import socket | |
import sys | |
import select | |
import http.client | |
import ssl | |
def print_help(): | |
"""Prints command-line usage help.""" | |
print(""" | |
Usage: portcheck <host> <port> [options] | |
Options: | |
-http Force an HTTP connection, even on non-standard ports. | |
-https Force an HTTPS connection, even on non-standard ports (ignores certificate verification). | |
-h Show this help message and exit. | |
Examples: | |
portcheck example.com 22 | |
portcheck example.com 80 | |
portcheck example.com 443 | |
portcheck example.com 8443 -https # Force HTTPS connection, ignoring cert errors | |
portcheck example.com 8080 -http # Force HTTP connection on port 8080 | |
""") | |
sys.exit(0) | |
def check_connection(host, port, timeout=5, force_http=False, force_https=False): | |
print(f"Resolving hostname...") | |
try: | |
ip = socket.gethostbyname(host) | |
print(f"Resolved {host} to {ip}") | |
print(f"Trying to connect...") | |
except socket.gaierror: | |
print(f"Error: Unable to resolve hostname {host}") | |
return | |
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: | |
s.settimeout(timeout) | |
try: | |
s.connect((ip, port)) | |
local_ip, local_port = s.getsockname() | |
print(f"Successfully connected to {host} ({ip}) on port {port}") | |
print(f"Connected from: {local_ip}:{local_port}") | |
# Force HTTPS connection if -https flag is used or if port is 443 | |
if force_https or port == 443: | |
print(f"Establishing HTTPS connection to {host} (ignoring certificate verification)...") | |
try: | |
context = ssl.create_default_context() | |
context.check_hostname = False | |
context.verify_mode = ssl.CERT_NONE # Ignore certificate verification | |
with context.wrap_socket(s, server_hostname=host) as secure_socket: | |
secure_socket.sendall(b"HEAD / HTTP/1.1\r\nHost: " + host.encode() + b"\r\nConnection: close\r\n\r\n") | |
response = secure_socket.recv(1024) | |
if response: | |
print(f"Response from HTTPS server:\n{response.decode('utf-8', 'ignore')}") | |
else: | |
print("No response received from HTTPS server.") | |
except ssl.SSLError as e: | |
print(f"SSL error (ignored if CERTIFICATE_VERIFY_FAILED): {e}") | |
except Exception as e: | |
print(f"Error making HTTPS request: {e}") | |
# Force HTTP connection if -http flag is used or if port is 80 | |
elif force_http or port == 80: | |
print(f"Sending HTTP GET request to {host}...") | |
try: | |
connection = http.client.HTTPConnection(host, port, timeout=timeout) | |
connection.request("HEAD", "/") | |
response = connection.getresponse() | |
print(f"HTTP Status: {response.status} {response.reason}") | |
connection.close() | |
except Exception as e: | |
print(f"Error making HTTP request: {e}") | |
# Handle non-HTTP/HTTPS connections | |
else: | |
s.sendall(b'GET /') | |
# Use select to check if data is available | |
ready = select.select([s], [], [], 1) | |
if ready[0]: | |
response = s.recv(1024) | |
if response: | |
print(f"Header returned: {response.decode('utf-8', 'ignore')}") | |
else: | |
print("No data received from the host.") | |
except socket.error as e: | |
local_ip, local_port = s.getsockname() | |
print(f"Error: Unable to connect to {host} ({ip}) on port {port}: {e}") | |
print(f"Tried to connect from: {local_ip}:{local_port}") | |
if __name__ == "__main__": | |
if "-h" in sys.argv: | |
print_help() | |
force_http = "-http" in sys.argv | |
force_https = "-https" in sys.argv | |
# Remove flags from arguments | |
args = [arg for arg in sys.argv[1:] if arg not in ["-http", "-https"]] | |
if len(args) >= 2: | |
host, port = args[0], int(args[1]) | |
else: | |
host = input("Host: ") | |
port = int(input("Port: ")) | |
check_connection(host, port, force_http=force_http, force_https=force_https) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment