File: [local] / acopm / dist / acopm-dronebl-submit.py.in (download)
Revision 1.1.1.1 (vendor branch), Sat May 8 15:42:29 2021 UTC (3 years, 4 months ago) by bountyht
Branch: alphachat, MAIN
CVS Tags: start, HEAD Changes since 1.1: +0 -0 lines
Initial import
|
#!/usr/bin/env python
#
# Copyright (C) 2008 DroneBL Contributors
# Copyright (C) 2008 William Pitcock <nenolod@dereferenced.org>
# Copyright (C) 2017 Aaron M. D. Jones <aaronmdjones@gmail.com>
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of
# its contributors may be used to endorse or promote products
# derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.
#
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
__version__ = '@PACKAGE_VERSION@'
import os
import sys
import urllib
import httplib
import xml.etree.ElementTree as ElementTree
class ACOPMNoVersionException(Exception):
def __str__(self):
return 'Version number missing -- are you using the INSTALLED copy of this script?'
class ACOPMMissingEnvironmentException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return 'The environment variable "{}" is missing'.format(self.value)
class ACOPMMalformedEnvironmentException(ACOPMMissingEnvironmentException):
def __str__(self):
return 'The environment variable "{}" is missing or malformed'.format(self.value)
def acopm_is_number(s):
try:
float(s)
return True
except ValueError:
return False
def acopm_get_env(name, required=True, length=0):
val = os.getenv(name, default='')
if required and not val:
raise ACOPMMissingEnvironmentException(name)
if not val:
return None
if length and len(val) != length:
raise ACOPMMalformedEnvironmentException(name)
return val
def acopm_proto_to_dbl_type(proto):
if proto == 'SOCKS4' or proto == 'SOCKS5':
return '8'
if proto == 'HTTP' or proto == 'HTTPS':
return '9'
sys.exit(0)
def acopm_build_dbl_add_request(addr, port, proto, rpckey):
type_id = acopm_proto_to_dbl_type(proto)
request = '<?xml version="1.0"?>\n'
request += '<request key="{}" staging="1">\n'.format(rpckey)
request += ' <add ip="{}" port="{}" type="{}" />\n'.format(addr, port, type_id)
request += '</request>\n'
return request
if __name__ == "__main__":
if not acopm_is_number(__version__):
raise ACOPMNoVersionException
addr = acopm_get_env('ADDRESS')
port = acopm_get_env('PORT')
proto = acopm_get_env('TYPE')
rpckey = acopm_get_env('CONFIG1', length=32)
stype, srest = urllib.splittype('https://dronebl.org/rpc2')
shost, spath = urllib.splithost(srest)
request = acopm_build_dbl_add_request(addr, port, proto, rpckey)
connection = httplib.HTTPSConnection(shost)
connection.putrequest('POST', spath)
connection.putheader('Content-Type', 'text/xml')
connection.putheader('Content-Length', len(request))
connection.putheader('User-Agent', 'ACOPM/v{} DroneBL submission script'.format(__version__))
net_name = acopm_get_env('CONFIG2', required=False)
if net_name:
connection.putheader('From', net_name)
connection.endheaders()
connection.send(request)
response = connection.getresponse()
response_data = response.read()
root = ElementTree.fromstring(response_data)
if root.tag != 'response':
sys.stderr.write('Unexpected: root tag is "{}"\n'.format(root.tag))
sys.exit(1)
if not 'type' in root.attrib:
sys.stderr.write('Unexpected: no "type" attribute in response tag\n')
sys.exit(2)
if root.attrib['type'] == 'error':
for child in root:
if child.tag == 'data':
sys.stderr.write('Error: {}\n'.format(child.text))
sys.exit(3)
sys.stderr.write('Error: error type without data tag\n')
sys.exit(4)
elif root.attrib['type'] != 'success':
sys.stderr.write('Unexpected: not an error, but not success: "{}"\n'.format(root.attrib['type']))
sys.exit(5)
for child in root:
if child.tag == 'warning':
if not 'data' in child.attrib:
sys.stderr.write('Warning: "{}"\n'.format(child.attrib))
sys.stderr.write('Warning: {}\n'.format(child.attrib['data']))
elif child.tag != 'success':
sys.stderr.write('Unexpected: not a warning, but not success: "{}"\n'.format(child.attrib))
sys.exit(6)
elif 'data' in child.attrib:
sys.stdout.write('{}\n'.format(child.attrib['data']))