Implemented Python setuptools build structure
This commit is contained in:
		
							parent
							
								
									c3506607c4
								
							
						
					
					
						commit
						156370a586
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1,2 +1,6 @@ | ||||||
| .vagrant | .vagrant | ||||||
| build | build | ||||||
|  | venv | ||||||
|  | dist | ||||||
|  | *.egg-info | ||||||
|  | __pycache__ | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2020 Benjamin Dweck | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in all | ||||||
|  | copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  | SOFTWARE. | ||||||
							
								
								
									
										5
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | wheel>=0.35.1 | ||||||
|  | setuptools>=44.0.0 | ||||||
|  | stem>=1.8.0 | ||||||
|  | paho-mqtt>=1.5.1 | ||||||
|  | PySocks>=1.7.1 | ||||||
							
								
								
									
										25
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | import setuptools | ||||||
|  | 
 | ||||||
|  | with open("README.md", "r") as fh: | ||||||
|  |     long_description = fh.read() | ||||||
|  | 
 | ||||||
|  | setuptools.setup( | ||||||
|  |     name="torch-agent", | ||||||
|  |     version="0.0.1", | ||||||
|  |     author="B.J. Dweck", | ||||||
|  |     author_email="bjdweck@gmail.com", | ||||||
|  |     description="TORch: Iluminate the Way to your Node", | ||||||
|  |     long_description=long_description, | ||||||
|  |     long_description_content_type="text/markdown", | ||||||
|  |     url="https://git.rudefox.io/bj/torch-agent", | ||||||
|  |     packages=setuptools.find_packages(), | ||||||
|  |     entry_points = { | ||||||
|  |         'console_scripts': ['torch-agent=torch_agent:main'], | ||||||
|  |     }, | ||||||
|  |     classifiers=[ | ||||||
|  |         "Programming Language :: Python :: 3", | ||||||
|  |         "License :: OSI Approved :: MIT License", | ||||||
|  |     ], | ||||||
|  |     python_requires='>=3.6', | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | @ -1,98 +0,0 @@ | ||||||
| from stem.control import Controller |  | ||||||
| import stem.connection |  | ||||||
| import paho.mqtt.client as mqtt |  | ||||||
| import ssl |  | ||||||
| import socks |  | ||||||
| import socket |  | ||||||
| import json |  | ||||||
| import configparser |  | ||||||
| import argparse |  | ||||||
| from datetime import datetime |  | ||||||
| from os import environ |  | ||||||
| 
 |  | ||||||
| parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT') |  | ||||||
| 
 |  | ||||||
| parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch', |  | ||||||
|                    help='configuration directory (default: /etc/torch)') |  | ||||||
| 
 |  | ||||||
| args = parser.parse_args() |  | ||||||
| 
 |  | ||||||
| configPath = args.configPath |  | ||||||
| 
 |  | ||||||
| if "TORCH_CONFIG_DIR" in environ: |  | ||||||
|   configPath = environ.get("TORCH_CONFIG_DIR") |  | ||||||
| 
 |  | ||||||
| if not configPath.endswith("/"): |  | ||||||
|   configPath = configPath + "/" |  | ||||||
| 
 |  | ||||||
| print("Using torch configuration path: " + configPath) |  | ||||||
| 
 |  | ||||||
| config = configparser.ConfigParser() |  | ||||||
| config.read(configPath + "torch.conf") |  | ||||||
| 
 |  | ||||||
| torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050) |  | ||||||
| torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051) |  | ||||||
| 
 |  | ||||||
| sshPort = config['ssh'].getint('Port', fallback = 22) |  | ||||||
| 
 |  | ||||||
| mqttConfig = config['mqtt'] |  | ||||||
| mqttBrokerHost = mqttConfig.get('BrokerHost', fallback = "localhost") |  | ||||||
| mqttBrokerPort = mqttConfig.getint('BrokerPort', fallback = 1883) |  | ||||||
| clientID = mqttConfig.get('ClientID', fallback = socket.gethostname()) |  | ||||||
| mqttTopic = mqttConfig.get('Topic', fallback = "torch/%s/onion_url" % (clientID)) |  | ||||||
| 
 |  | ||||||
| mqttRequireCertificate = mqttConfig.getboolean( |  | ||||||
|                                        'RequireCertificate',  |  | ||||||
|                                        fallback = False) |  | ||||||
| 
 |  | ||||||
| mqttCaFile = configPath + mqttConfig.get('CaFile') |  | ||||||
| mqttCertFile = configPath + mqttConfig.get('CertFile') |  | ||||||
| mqttKeyFile = configPath + mqttConfig.get('KeyFile') |  | ||||||
| 
 |  | ||||||
| with Controller.from_port(port = torControllerPort) as controller: |  | ||||||
|    |  | ||||||
|   protocolInfo = stem.connection.get_protocolinfo(controller) |  | ||||||
| 
 |  | ||||||
|   stem.connection.authenticate_safecookie( |  | ||||||
|                        controller,  |  | ||||||
|                        protocolInfo.cookie_path) |  | ||||||
|    |  | ||||||
|   print("Connected to Tor on port %s" % (torControllerPort)) |  | ||||||
| 
 |  | ||||||
|   service = controller.create_ephemeral_hidden_service( |  | ||||||
|                              sshPort, |  | ||||||
| 							 detached = True) |  | ||||||
| 
 |  | ||||||
|   onionAddress = "%s.onion" % (service.service_id) |  | ||||||
| 
 |  | ||||||
|   print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress)) |  | ||||||
| 
 |  | ||||||
| payload = {  |  | ||||||
|   'clientId': clientID,  |  | ||||||
|   'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),  |  | ||||||
|   'onionAddress': onionAddress,  |  | ||||||
|   'sshPort': sshPort  |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| client = mqtt.Client() |  | ||||||
| protocol = "mqtt" |  | ||||||
| 
 |  | ||||||
| if mqttRequireCertificate: |  | ||||||
|   client.tls_set( |  | ||||||
|           ca_certs = mqttCaFile,  |  | ||||||
|           certfile = mqttCertFile,  |  | ||||||
|           keyfile = mqttKeyFile,  |  | ||||||
|           cert_reqs=ssl.CERT_REQUIRED) |  | ||||||
|   protocol = "mqtts" |  | ||||||
| 
 |  | ||||||
| if mqttBrokerHost.endswith(".onion"): |  | ||||||
|   client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort) |  | ||||||
|   client.tls_insecure_set(True) |  | ||||||
| 
 |  | ||||||
| client.connect(mqttBrokerHost, mqttBrokerPort, 60) |  | ||||||
| client.publish(mqttTopic, json.dumps(payload)) |  | ||||||
| print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqttBrokerHost, mqttBrokerPort, mqttTopic)) |  | ||||||
| print("Published payload: " + json.dumps(payload)) |  | ||||||
| 
 |  | ||||||
| client.disconnect() |  | ||||||
| print("Disconnected from MQTT Broker") |  | ||||||
							
								
								
									
										1
									
								
								torch_agent/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								torch_agent/__init__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | __version__ = "0.0.1" | ||||||
							
								
								
									
										5
									
								
								torch_agent/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								torch_agent/__main__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | import sys | ||||||
|  | from torch_agent import main | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |   sys.exit(main()) | ||||||
							
								
								
									
										97
									
								
								torch_agent/torch_agent.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										97
									
								
								torch_agent/torch_agent.py
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,97 @@ | ||||||
|  | from stem.control import Controller | ||||||
|  | import stem.connection | ||||||
|  | import paho.mqtt.client as mqtt | ||||||
|  | import ssl | ||||||
|  | import socks | ||||||
|  | import socket | ||||||
|  | import json | ||||||
|  | import configparser | ||||||
|  | import argparse | ||||||
|  | from datetime import datetime | ||||||
|  | from os import environ | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |   parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT') | ||||||
|  | 
 | ||||||
|  |   parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch', | ||||||
|  |                      help='configuration directory (default: /etc/torch)') | ||||||
|  | 
 | ||||||
|  |   args = parser.parse_args() | ||||||
|  | 
 | ||||||
|  |   configPath = args.configPath | ||||||
|  | 
 | ||||||
|  |   if "TORCH_CONFIG_DIR" in environ: | ||||||
|  |     configPath = environ.get("TORCH_CONFIG_DIR") | ||||||
|  | 
 | ||||||
|  |   if not configPath.endswith("/"): | ||||||
|  |     configPath = configPath + "/" | ||||||
|  | 
 | ||||||
|  |   print("Using torch configuration path: " + configPath) | ||||||
|  | 
 | ||||||
|  |   config = configparser.ConfigParser() | ||||||
|  |   config.read(configPath + "torch.conf") | ||||||
|  | 
 | ||||||
|  |   torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050) | ||||||
|  |   torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051) | ||||||
|  | 
 | ||||||
|  |   sshPort = config['ssh'].getint('Port', fallback = 22) | ||||||
|  | 
 | ||||||
|  |   mqttConfig = config['mqtt'] | ||||||
|  |   mqttBrokerHost = mqttConfig.get('BrokerHost', fallback = "localhost") | ||||||
|  |   mqttBrokerPort = mqttConfig.getint('BrokerPort', fallback = 1883) | ||||||
|  |   clientID = mqttConfig.get('ClientID', fallback = socket.gethostname()) | ||||||
|  |   mqttTopic = mqttConfig.get('Topic', fallback = "torch/%s/onion_url" % (clientID)) | ||||||
|  | 
 | ||||||
|  |   mqttRequireCertificate = mqttConfig.getboolean( | ||||||
|  |                                          'RequireCertificate',  | ||||||
|  |                                          fallback = False) | ||||||
|  | 
 | ||||||
|  |   mqttCaFile = configPath + mqttConfig.get('CaFile') | ||||||
|  |   mqttCertFile = configPath + mqttConfig.get('CertFile') | ||||||
|  |   mqttKeyFile = configPath + mqttConfig.get('KeyFile') | ||||||
|  | 
 | ||||||
|  |   with Controller.from_port(port = torControllerPort) as controller: | ||||||
|  |      | ||||||
|  |     protocolInfo = stem.connection.get_protocolinfo(controller) | ||||||
|  | 
 | ||||||
|  |     stem.connection.authenticate_safecookie( | ||||||
|  |                          controller,  | ||||||
|  |                          protocolInfo.cookie_path) | ||||||
|  |      | ||||||
|  |     print("Connected to Tor on port %s" % (torControllerPort)) | ||||||
|  | 
 | ||||||
|  |     service = controller.create_ephemeral_hidden_service(sshPort, detached = True) | ||||||
|  | 
 | ||||||
|  |     onionAddress = "%s.onion" % (service.service_id) | ||||||
|  | 
 | ||||||
|  |     print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress)) | ||||||
|  | 
 | ||||||
|  |   payload = {  | ||||||
|  |     'clientId': clientID,  | ||||||
|  |     'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),  | ||||||
|  |     'onionAddress': onionAddress,  | ||||||
|  |     'sshPort': sshPort  | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   client = mqtt.Client() | ||||||
|  |   protocol = "mqtt" | ||||||
|  | 
 | ||||||
|  |   if mqttRequireCertificate: | ||||||
|  |     client.tls_set( | ||||||
|  |             ca_certs = mqttCaFile,  | ||||||
|  |             certfile = mqttCertFile,  | ||||||
|  |             keyfile = mqttKeyFile,  | ||||||
|  |             cert_reqs=ssl.CERT_REQUIRED) | ||||||
|  |     protocol = "mqtts" | ||||||
|  | 
 | ||||||
|  |   if mqttBrokerHost.endswith(".onion"): | ||||||
|  |     client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort) | ||||||
|  |     client.tls_insecure_set(True) | ||||||
|  | 
 | ||||||
|  |   client.connect(mqttBrokerHost, mqttBrokerPort, 60) | ||||||
|  |   client.publish(mqttTopic, json.dumps(payload)) | ||||||
|  |   print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqttBrokerHost, mqttBrokerPort, mqttTopic)) | ||||||
|  |   print("Published payload: " + json.dumps(payload)) | ||||||
|  | 
 | ||||||
|  |   client.disconnect() | ||||||
|  |   print("Disconnected from MQTT Broker") | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user