From 34846014399f8756962051df02d251b91b65bb0c Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Sat, 18 Apr 2015 21:12:03 +0200 Subject: Update documentation changelog and examples. Final touches --- Changelog | 11 ++++++++++ INSTALL | 17 ++++++++------- README | 17 +++++++-------- beinc_config_sample.json | 46 +++++++++++++++++++++++++++-------------- beinc_config_sample.json.readme | 19 +++++++++-------- beinc_server.py | 14 +++++++++---- beinc_weechat.py | 33 ++++++++++++++++++----------- 7 files changed, 99 insertions(+), 58 deletions(-) create mode 100644 Changelog diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..f678c6e --- /dev/null +++ b/Changelog @@ -0,0 +1,11 @@ +v2.0: + - replace charrypy with TwistedWeb as beinc_server.py backend + - use XMLRPC instead of HTTP POST for a cleaner and more robust API + - several ssl options like ssl_version and ssl_ciphers added + - bugfixes + +v1.1: + - when beinc_poller.py fetches several messages from a queue it won't let the last one to completely overwrite the previous ones + +v1.0 + - Initial version diff --git a/INSTALL b/INSTALL index d00a3d9..f26a6f9 100644 --- a/INSTALL +++ b/INSTALL @@ -9,16 +9,16 @@ Installing the dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Gentoo GNU/Linux 2013, 2014 +Gentoo GNU/Linux 2014, 2015 .......................... -# emerge -va dev-python/pyopenssl dev-python/cherrypy dev-python/notify-python dev-python/pyosd +# emerge -va dev-python/pyopenssl dev-python/twisted-web dev-python/notify-python dev-python/pyosd Ubuntu GNU/Linux ................ -# apt-get install python-openssl python-cherrypy python-notify2 python-pyosd +# apt-get install python-openssl python-twisted-web python-notify2 python-pyosd FreeBSD 9, 10 @@ -27,7 +27,7 @@ FreeBSD 9, 10 # cd /usr/ports/security/py-openssl # make install clean -# cd /usr/ports/www/py-cherrypy +# cd /usr/ports/www/py-twistedWeb # make install clean # cd /usr/ports/devel/py-notify @@ -45,7 +45,7 @@ This is where virtualenv may become handy (provided that it has been installed): $ virtualenv beinc_installation $ cd beinc_installation $ source bin/activate -$ pip install cherrypy +$ pip install Twisted $ pip install pyopenssl $ cd beinc- $ ./beinc_server.py -h @@ -71,13 +71,14 @@ Create a configuration file based on beinc_config_sample.json, defining your ins Start the BEINC server: $ ./beinc_server.py -H 10.0.0.44 -p 9678 The example loads the server listening on 10.0.0.44, port 9678 using the default -~/.beinc_server.json as a configuration file and usually gives you the cherrypy console +~/.beinc_server.json as a configuration file and usually gives you the Twisted +log console beinc_poller.py: $ ./beinc_poller.py -h The example lists all available command options -$ ./beinc_poller.py -t 10 -f 7 --cert-file /home/sgs/weechat_cert.crt \ - -P /home/sgs/.weechat_beinc_passwd https://10.0.0.44:9678/pull/weechat +$ ./beinc_poller.py -n weechat -t 10 -f 7 --cert-file /home/sgs/weechat_cert.crt \ + -p /home/sgs/.weechat_beinc_passwd https://10.0.0.44:9678 Starts polling from the instance (target) defined above, defining an OSD timeout of 10 seconds, polling frequency of 7 seconds, checking whether the server's SSL certificate was signed (issued) by /home/sgs/weechat_cert.crt, diff --git a/README b/README index 492e892..f3e241e 100644 --- a/README +++ b/README @@ -80,25 +80,24 @@ There are 2 operations that can be done on an instance: A pull is available only for instances defined for queueing. (read beinc_config_sample.json.readme for details!) Example: -If you defined a beinc_server.py instance with SSL-support called "beinc_test", -your URL for pushing will be: https://hostname:port/push/beinc_test -and for polling: https://hostname:port/pull/beinc_test +If you defined a beinc_server.py instance with SSL-support, +your URL will be: https://hostname:port Supported systems & requirements -------------------------------- Any system running the software required for the selected components. -All components tested on: Gentoo GNU/Linux 2013,2014, - Ubuntu GNU/Linux 14.4,13.10, - FreeBSD 9.x +All components tested on: Gentoo GNU/Linux 2014,2015, + Ubuntu GNU/Linux 14.4,14.10, + FreeBSD 10.x Requirements: -All components: Python 2.7.* -beinc_server.py: cherrypy >= 3.2.0, pyopenssl >= 0.13.0 (opntional (ssl support)), +All components: Python 2.7.* (for TLS1.1 and TLS1.2 client support you ned Python>=2.7.9) +beinc_server.py: Twisted Web >= 14.0, pyopenssl >= 0.13.0, pynotify >= 0.1 (optional), pyosd >= 0.2 (optional) beinc_weechat.py: Weechat >= 0.4.0 -beinc_poller.py: pynotify >= 0.1 (optional), pyosd >= 0.2 (optional) +beinc_poller.py: pynotify >= 0.1 or pyosd >= 0.2 beinc_generic_client.py: No additional software required Read INSTALL in this very same folder for more details about installing the requirements! diff --git a/beinc_config_sample.json b/beinc_config_sample.json index 046e3fa..ecfe9bb 100644 --- a/beinc_config_sample.json +++ b/beinc_config_sample.json @@ -1,23 +1,35 @@ { "server": { "general": { - "ssl_private_key": "key.pem", - "ssl_certificate": "cert.crt", - "ssl_acceptable_ciphers": "auto", - "ssl_version": "auto" + "ssl_private_key": "/home/user/.key.pem", + "ssl_certificate": "/home/user/.cert.pem", + "ssl_version": "TLSv1_2", + "ssl_ciphers": "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384" }, "instances": [ { - "name": "test", + "name": "instance1", + "password": "changeme", + "osd_system": "pynotify", + "osd_timeout": 5 + }, + { + "name": "instance2", "password": "changeme", "osd_system": "pyosd", - "osd_timeout": 5, - "pyosd_font": "", + "osd_timeout": 6, + "pyosd_font": "-adobe-courier-bold-o-normal--24-240-75-75-m-150-iso8859-1", "pyosd_vertical_offset": 120, "pyosd_horizontal_offset": 30, "pyosd_align": "left", - "pyosd_position": "bottom", - "pyosd_color": "blue", + "pyosd_position": "top", + "pyosd_color": "blue" + }, + { + "name": "instance3", + "password": "changeme", + "osd_system": "none", + "osd_timeout": 5, "queue_size": 4 } ] @@ -29,26 +41,28 @@ "name": "weechat_main", "target_url": "https://10.0.0.2:9898", "target_password": "changeme", - "target_cert_file": "", + "target_cert_file": "/home/user/.ca_cert.pem", "target_timestamp_format": "%H:%M:%S", - "socket_timeout": 30, + "ssl_version": "TLSv1_2", + "ssl_ciphers": "auto", + "disable-hostname-check": 0, + "socket_timeout": 2, "pm_title_template": "%s @ %S", "pm_message_template": "%m", "cm_title_template": "%c @ %S", "cm_message_template": "%s -> %m", "nm_title_template": "%c @ %S", "nm_message_template": "%s -> %m", - "channel_list": ["RedpillLinpro.#python", + "channel_list": ["Freenode.#python", "Exile.#test", - "RedpillLinpro.#adult", + "Freenode.#gentoo", "Exile.#pichove"], "nick_list": ["Exile.Blackmore"], "channel_messages_policy": 2, "private_messages_policy": 1, "notifications_policy": 1, - "debug": 1, - "enabled": 1, - "socket_timeout": 3 + "debug": 0, + "enabled": 1 } ] }, diff --git a/beinc_config_sample.json.readme b/beinc_config_sample.json.readme index 9c5aecc..edf5845 100644 --- a/beinc_config_sample.json.readme +++ b/beinc_config_sample.json.readme @@ -30,7 +30,7 @@ documentation to better illustrate the comments. # Encryption method for the BEINC server # Possible values: - # "auto" - Let Twisted decide (use the newest possible method) + # "" or "auto" - Let Twisted decide (use the newest possible method) # "SSLv3" - SSLv3 (weak) # "TLSv1" - TLSv1.0 # "TLSv1_1" - TLSv1.1 @@ -98,16 +98,17 @@ documentation to better illustrate the comments. "targets": [ { # Unique name for the defined target - # Default: 4 characters random string - # Defining your own name will make life easier for you + # Default: "" (making the target useless) + # The name should match the name of the server instance you + # want to connect to "name": "weechat_main", # Target URL. - # Default: None (making the target useless) + # Default: "" (making the target useless) "target_url": "https://10.0.0.2:9998", # Password corresponding to the target BEINC instance - # Default: None + # Default: "" "target_password": "beincpasswd", # The filename of the SSL certificate authority (CA) used to @@ -118,11 +119,11 @@ documentation to better illustrate the comments. "target_cert_file": "", # A list of preferred ciphers for this target - # Default: "" (use the OpenSSL default ciphers) + # Default: "auto" or "" (use the OpenSSL default ciphers) "ssl_ciphers": "ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384", # Don't check whether the target's hostname matches the server's - # certificate. (Only Python >= 2.7.9) + # certificate. (Only for Python >= 2.7.9) # Default: 0 "disable-hostname-check": 0, @@ -168,9 +169,9 @@ documentation to better illustrate the comments. # Channel list # Default: [] (empty) - "channel_list": ["RedpillLinpro.#python", + "channel_list": ["Freenode.#python", "Exile.#test", - "RedpillLinpro.#adult", + "Freenode.#gentoo", "Exile.#pichove"], # Nick list diff --git a/beinc_server.py b/beinc_server.py index 53f12c5..84f7a82 100755 --- a/beinc_server.py +++ b/beinc_server.py @@ -59,6 +59,8 @@ BEINC_OSD_TYPE_NONE = 0 BEINC_OSD_TYPE_PYNOTIFY = 1 BEINC_OSD_TYPE_PYOSD = 2 +BEINC_CURRENT_CONFIG_VERSION = 2 + BEINC_SSL_METHODS = {'SSLv3': OpenSSL.SSL.SSLv3_METHOD, 'TLSv1': OpenSSL.SSL.TLSv1_METHOD} try: @@ -351,11 +353,15 @@ def main(): e)) sys.exit(errno.EIO) try: - if config_dict.get('config_version') != 2: + if config_dict.get('config_version') != BEINC_CURRENT_CONFIG_VERSION: sys.stderr.write( - 'Incompatible or missing config-file version for {0}\n'.format( - args.config_file)) - sys.exit(1) + 'WARNING: The version of the config-file: {0} ({1}) ' + 'does not correspond to the latest version supported ' + 'by this program ({2})\nCheck beinc_config_sample.json ' + 'for the newest features!\n'.format( + args.config_file, + config_dict.get('config_version', 'Not set'), + BEINC_CURRENT_CONFIG_VERSION)) ssl_certificate = config_dict['server']['general'].get( 'ssl_certificate') ssl_private_key = config_dict['server']['general'].get( diff --git a/beinc_weechat.py b/beinc_weechat.py index 52e83b6..1e8afb8 100644 --- a/beinc_weechat.py +++ b/beinc_weechat.py @@ -120,11 +120,15 @@ class WeechatTarget(object): """ target_dict: the config-dictionary node that represents this instance """ - self.__name = target_dict.get( - 'name', - ''.join([chr(random.randrange(97, 123)) for x in range(4)])) - self.__url = target_dict.get('target_url') - self.__password = target_dict.get('target_password') + self.__name = target_dict.get('name', '') + if self.__name == '': + beinc_prnt('WARNING: Adding a target with no name ' + 'will make the target useless') + self.__url = target_dict.get('target_url', '') + if self.__url == '': + beinc_prnt('WARNING: Adding a target with no URL ' + 'will make the target useless') + self.__password = target_dict.get('target_password', '') self.__pm_title_template = target_dict.get('pm_title_template', '%s @ %S') self.__pm_message_template = target_dict.get('pm_message_template', @@ -158,6 +162,7 @@ class WeechatTarget(object): self.__disable_hostname_check = bool( target_dict.get('disable-hostname-check', False)) self.__ssl_version = target_dict.get('ssl_version', 'auto') + self.__last_message = None # datetime.datetime instance self.__connection = None # xmlrpclib.ServerProxy instance self.__connection_setup() @@ -227,11 +232,14 @@ class WeechatTarget(object): def __repr__(self): """ """ + last_message = 'never' + if self.__last_message is not None: + last_message = self.__last_message.strftime('%Y-%m-%d %H:%M:%S') return ('name: {0}\nurl: {1}\nenabled: {2}\nchannel_list: {3}\n' 'nick_list: {4}\nchannel_messages_policy: {5}\n' 'private_messages_policy: {6}\nnotifications_policy: {7}\n' - 'connected: {8}\nsocket timeout: {9}\nssl-version: {10}\n' - 'ciphers: {11}\ndisable_hostname_check: {12}\n' + 'last message: {8}\nsocket timeout: {9}\nssl-version: {10}\n' + 'ciphers: {11}\ndisable hostname check: {12}\n' 'debug: {13}\n\n'.format( self.__name, self.__url, @@ -241,11 +249,11 @@ class WeechatTarget(object): self.__chan_messages_policy, self.__priv_messages_policy, self.__notifications_policy, - 'no' if self.__connection is None else 'yes', + last_message, self.__socket_timeout, self.__ssl_version, - self.__ssl_ciphers or 'default', - 'yes' if self.__disable_hostname_check else 'no' + self.__ssl_ciphers or 'auto', + 'yes' if self.__disable_hostname_check else 'no', 'yes' if self.__debug else 'no')) def send_private_message_notification(self, values): @@ -357,7 +365,7 @@ class WeechatTarget(object): self.__cert_file)) context.check_hostname = bool( not self.__disable_hostname_check) - if self.__ssl_ciphers: + if self.__ssl_ciphers and self.__ssl_ciphers != 'auto': context.set_ciphers(self.__ssl_ciphers) transport = xmlrpclib.SafeTransport(context=context) else: @@ -368,7 +376,7 @@ class WeechatTarget(object): ssl_options['ca_certs'] = os.path.expanduser( self.__cert_file) ssl_options['cert_reqs'] = ssl.CERT_REQUIRED - if self.__ssl_ciphers: + if self.__ssl_ciphers and self.__ssl_ciphers != 'auto': ssl_options['ciphers'] = self.__ssl_ciphers transport = BEINCCustomSafeTransport( custom_ssl_options=ssl_options) @@ -432,6 +440,7 @@ class WeechatTarget(object): message) if self.__debug: beinc_prnt('BEINC DEBUG: Server responded: {0}'.format(result)) + self.__last_message = datetime.datetime.now() return True except xmlrpclib.Fault as fault: if self.__debug: -- cgit v1.3