summaryrefslogtreecommitdiff
path: root/beinc_generic_client.py
diff options
context:
space:
mode:
authorSimeon Simeonov2015-04-14 23:08:21 +0200
committerSimeon Simeonov2015-04-14 23:08:21 +0200
commita5a26cba29ba37f3ef7c4f60c6cbf3f663161b27 (patch)
treeb7fa2ed496cee78ad67c14338039a08a30742814 /beinc_generic_client.py
parent36dda1cca9503fc00c15ed22c4c5969e80edc1f7 (diff)
beinc_generic_client.py v.2.0 almost fone
Diffstat (limited to 'beinc_generic_client.py')
-rwxr-xr-xbeinc_generic_client.py129
1 files changed, 84 insertions, 45 deletions
diff --git a/beinc_generic_client.py b/beinc_generic_client.py
index b46d3fd..da671f2 100755
--- a/beinc_generic_client.py
+++ b/beinc_generic_client.py
@@ -1,7 +1,7 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: utf-8 -*- 2# -*- coding: utf-8 -*-
3 3
4# Blackmore's Enhanced IRC-Notification Collection (BEINC) v1.0 4# Blackmore's Enhanced IRC-Notification Collection (BEINC) v2.0
5# Copyright (C) 2013-2015 Simeon Simeonov 5# Copyright (C) 2013-2015 Simeon Simeonov
6 6
7# This program is free software: you can redistribute it and/or modify 7# This program is free software: you can redistribute it and/or modify
@@ -21,12 +21,12 @@
21import argparse 21import argparse
22import errno 22import errno
23import getpass 23import getpass
24import httplib 24import httplib # for Python < 2.7.9
25import socket 25import os
26import socket # for Python < 2.7.9
26import ssl 27import ssl
27import sys 28import sys
28import urllib 29import xmlrpclib
29import urllib2
30 30
31 31
32__author__ = 'Simeon Simeonov' 32__author__ = 'Simeon Simeonov'
@@ -34,62 +34,91 @@ __version__ = '1.0'
34__license__ = 'GPL3' 34__license__ = 'GPL3'
35 35
36 36
37class ValidHTTPSConnection(httplib.HTTPConnection): 37class BEINCCustomHTTPSConnection(httplib.HTTPConnection):
38 """
39 Implements a simple CERT verification functionality
40 """ 38 """
39 This class allows communication via SSL.
41 40
41 It is a reimplementation of httplib.HTTPSConnection and
42 allows the server certificate to be validated against CA
43 This functionality lacks in Python < 2.7.9
44 """
42 default_port = httplib.HTTPS_PORT 45 default_port = httplib.HTTPS_PORT
43 46
44 def __init__(self, *args, **kwargs): 47 def __init__(self, host, port=None, key_file=None, cert_file=None,
45 httplib.HTTPConnection.__init__(self, *args, **kwargs) 48 strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
49 source_address=None, ca_cert=None):
50 httplib.HTTPConnection.__init__(self, host, port, strict, timeout,
51 source_address)
52 self.key_file = key_file
53 self.cert_file = cert_file
54 self.ca_cert = ca_cert
46 55
47 def connect(self): 56 def connect(self):
57 "Connect to a host on a given (SSL) port."
48 sock = socket.create_connection((self.host, self.port), 58 sock = socket.create_connection((self.host, self.port),
49 self.timeout, self.source_address) 59 self.timeout, self.source_address)
50 if self._tunnel_host: 60 if self._tunnel_host:
51 self.sock = sock 61 self.sock = sock
52 self._tunnel() 62 self._tunnel()
53 self.sock = ssl.wrap_socket(sock, 63 self.sock = ssl.wrap_socket(sock,
54 ca_certs=global_beinc_cert_file, 64 self.key_file,
55 cert_reqs=ssl.CERT_REQUIRED) 65 self.cert_file,
56 66 cert_reqs=ssl.CERT_REQUIRED,
67 ca_certs=self.ca_cert)
57 68
58class ValidHTTPSHandler(urllib2.HTTPSHandler): 69class BEINCCustomSafeTransport(xmlrpclib.Transport):
59 """
60 Implements a simple CERT verification functionality
61 """
62 70
63 def https_open(self, req): 71 def __init__(self, use_datetime=0, ca_cert=None):
64 return self.do_open(ValidHTTPSConnection, req) 72 xmlrpclib.Transport.__init__(self, use_datetime=use_datetime)
73 self.ca_cert = ca_cert
74
75 def make_connection(self, host):
76 if self._connection and host == self._connection[0]:
77 return self._connection[1]
78 try:
79 HTTPS = BEINCCustomHTTPSConnection
80 except AttributeError:
81 raise NotImplementedError(
82 "your version of httplib doesn't support HTTPS"
83 )
84 else:
85 chost, self._extra_headers, x509 = self.get_host_info(host)
86 self._connection = host, HTTPS(chost,
87 None,
88 ca_cert=self.ca_cert,
89 **(x509 or {}))
90 return self._connection[1]
65 91
66 92
67def action_push(args): 93def action_execute(args):
68 """ 94 """
69 """ 95 """
70 try: 96 try:
71 post_values = {'title': args.title, 97 if sys.hexversion >= 0x20709f0:
72 'message': args.message, 98 # Python >= 2.7.9
73 'password': args.password} 99 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
74 data = urllib.urlencode(post_values) 100 context.verify_mode = ssl.CERT_REQUIRED
75 req = urllib2.Request(args.url, data) 101 context.check_hostname = False
76 if args.cert: # check for cert validity 102 context.load_verify_locations(os.path.expanduser(args.cert))
77 global global_beinc_cert_file # ugly hack 103 transport = xmlrpclib.SafeTransport(context=context)
78 global_beinc_cert_file = args.cert 104 else:
79 opener = urllib2.build_opener(ValidHTTPSHandler) 105 # Python < 2.7.9
80 response = opener.open(req) 106 transport = BEINCCustomSafeTransport(
81 else: # ... or don't 107 ca_cert=os.path.expanduser(args.cert))
82 response = urllib2.urlopen(req) 108 server = xmlrpclib.ServerProxy(args.url,
83 res_code = response.code 109 transport=transport)
84 if res_code == 200: 110 if args.pull:
85 print('Server responded: OK') 111 print(server.pull(args.rname, args.password))
86 else: 112 else:
87 print('Server responded: {0}'.format(res_code)) 113 print(server.push(args.rname,
88 print('Body:\n{0}'.format(response.read())) 114 args.password,
89 response.close() 115 args.title,
90 except urllib2.HTTPError as e: 116 args.message))
91 sys.stderr.write('BEINC-server error ({0} - {1})\n'.format(e.code, 117 except xmlrpclib.Fault as fault:
92 e.reason)) 118 sys.stderr.write(
119 'BEINC server answered with errorCode={0}: {1}\n'.format(
120 fault.faultCode,
121 fault.faultString))
93 except Exception as e: 122 except Exception as e:
94 sys.stderr.write('BEINC generic client error: {0}\n'.format(e)) 123 sys.stderr.write('BEINC generic client error: {0}\n'.format(e))
95 sys.exit(errno.EPERM) 124 sys.exit(errno.EPERM)
@@ -101,8 +130,6 @@ def main():
101 parser.add_argument('url', 130 parser.add_argument('url',
102 metavar='URL', 131 metavar='URL',
103 type=str, 132 type=str,
104 #dest='url',
105 #required=True,
106 help='Destination URL') 133 help='Destination URL')
107 parser.add_argument('-c', '--cert-file', 134 parser.add_argument('-c', '--cert-file',
108 metavar='FILE', 135 metavar='FILE',
@@ -116,12 +143,24 @@ def main():
116 dest='message', 143 dest='message',
117 default='BEINC message', 144 default='BEINC message',
118 help='BEINC message') 145 help='BEINC message')
146 parser.add_argument('-n', '--resource-name',
147 metavar='NAME',
148 type=str,
149 dest='rname',
150 required=True,
151 help='The name of the BEINC-resource on '
152 'the remote server')
119 parser.add_argument('-p', '--password', 153 parser.add_argument('-p', '--password',
120 metavar='PASSWORD', 154 metavar='PASSWORD',
121 type=str, 155 type=str,
122 dest='password', 156 dest='password',
123 default='', 157 default='',
124 help='Password') 158 help='Password')
159 parser.add_argument('--pull',
160 action='store_true',
161 dest='pull',
162 default=False,
163 help='Perform a pull operation (default: push)')
125 parser.add_argument('-t', '--title', 164 parser.add_argument('-t', '--title',
126 metavar='TITLE', 165 metavar='TITLE',
127 type=str, 166 type=str,
@@ -139,9 +178,9 @@ def main():
139 except Exception as e: 178 except Exception as e:
140 sys.stderr.write('Prompt terminated\n') 179 sys.stderr.write('Prompt terminated\n')
141 sys.exit(errno.EACCES) 180 sys.exit(errno.EACCES)
142 action_push(args) 181 action_execute(args)
143 sys.exit(0) 182 sys.exit(0)
144 183
145 184
146if __name__ == '__main__': 185if __name__ == '__main__':
147 main() 186 main()