From 5c5b14bc535820e16aec82e79a4bc3728878d604 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 5 Jan 2014 23:12:36 -0800 Subject: [PATCH 01/95] XMPP, Info update --- NOTICE.rst | 4 +- cryptoim/xmpp_test.py | 157 ++++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 cryptoim/xmpp_test.py diff --git a/NOTICE.rst b/NOTICE.rst index 4836a0d..3fd21f7 100644 --- a/NOTICE.rst +++ b/NOTICE.rst @@ -10,4 +10,6 @@ All Authors and Contributors are named in the AUTHORS.rst file. Used libraries ============== -None. +nose 1.3.0 +sleekxmpp 1.1.11 +coveralls-python 2.4.2 diff --git a/cryptoim/xmpp_test.py b/cryptoim/xmpp_test.py new file mode 100644 index 0000000..18125a0 --- /dev/null +++ b/cryptoim/xmpp_test.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file LICENSE for copying permission. +""" + +import sys +import logging +import getpass +from optparse import OptionParser + +import sleekxmpp + +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +if sys.version_info < (3, 0): + from sleekxmpp.util.misc_ops import setdefaultencoding + setdefaultencoding('utf8') +else: + raw_input = input + + +class EchoBot(sleekxmpp.ClientXMPP): + + """ + A simple SleekXMPP bot that will echo messages it + receives, along with a short thank you message. + """ + + def __init__(self, jid, password): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + + # The session_start event will be triggered when + # the bot establishes its connection with the server + # and the XML streams are ready for use. We want to + # listen for this event so that we we can initialize + # our roster. + self.add_event_handler("session_start", self.start) + + # The message event is triggered whenever a message + # stanza is received. Be aware that that includes + # MUC messages and error messages. + self.add_event_handler("message", self.message) + + def start(self, event): + """ + Process the session_start event. + + Typical actions for the session_start event are + requesting the roster and broadcasting an initial + presence stanza. + + Arguments: + event -- An empty dictionary. The session_start + event does not provide any additional + data. + """ + self.send_presence() + self.get_roster() + + def message(self, msg): + """ + Process incoming message stanzas. Be aware that this also + includes MUC messages and error messages. It is usually + a good idea to check the messages's type before processing + or sending replies. + + Arguments: + msg -- The received message stanza. See the documentation + for stanza objects and the Message stanza to see + how it may be used. + """ + if msg['type'] in ('chat', 'normal'): + msg.reply("Thanks for sending\n%(body)s" % msg).send() + + +if __name__ == '__main__': + # Setup the command line arguments. + optp = OptionParser() + + # Output verbosity options. + optp.add_option('-q', '--quiet', help='set logging to ERROR', + action='store_const', dest='loglevel', + const=logging.ERROR, default=logging.INFO) + optp.add_option('-d', '--debug', help='set logging to DEBUG', + action='store_const', dest='loglevel', + const=logging.DEBUG, default=logging.INFO) + optp.add_option('-v', '--verbose', help='set logging to COMM', + action='store_const', dest='loglevel', + const=5, default=logging.INFO) + + # JID and password options. + optp.add_option("-j", "--jid", dest="jid", + help="JID to use") + optp.add_option("-p", "--password", dest="password", + help="password to use") + + opts, args = optp.parse_args() + + # Setup logging. + logging.basicConfig(level=opts.loglevel, + format='%(levelname)-8s %(message)s') + + if opts.jid is None: + opts.jid = raw_input("Username: ") + if opts.password is None: + opts.password = getpass.getpass("Password: ") + + # Setup the EchoBot and register plugins. Note that while plugins may + # have interdependencies, the order in which you register them does + # not matter. + xmpp = EchoBot(opts.jid, opts.password) + xmpp.register_plugin('xep_0030') # Service Discovery + xmpp.register_plugin('xep_0004') # Data Forms + xmpp.register_plugin('xep_0060') # PubSub + xmpp.register_plugin('xep_0199') # XMPP Ping + + # If you are connecting to Facebook and wish to use the + # X-FACEBOOK-PLATFORM authentication mechanism, you will need + # your API key and an access token. Then you'll set: + # xmpp.credentials['api_key'] = 'THE_API_KEY' + # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' + + # If you are connecting to MSN, then you will need an + # access token, and it does not matter what JID you + # specify other than that the domain is 'messenger.live.com', + # so '_@messenger.live.com' will work. You can specify + # the access token as so: + # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' + + # If you are working with an OpenFire server, you may need + # to adjust the SSL version used: + # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 + + # If you want to verify the SSL certificates offered by a server: + # xmpp.ca_certs = "path/to/ca/cert" + + # Connect to the XMPP server and start processing XMPP stanzas. + if xmpp.connect(): + # If you do not have the dnspython library installed, you will need + # to manually specify the name of the server if it does not match + # the one in the JID. For example, to use Google Talk you would + # need to use: + # + # if xmpp.connect(('talk.google.com', 5222)): + # ... + xmpp.process(block=False) + print("Done") + else: + print("Unable to connect.") diff --git a/setup.py b/setup.py index 4030ec8..bb08a93 100755 --- a/setup.py +++ b/setup.py @@ -41,9 +41,8 @@ ], long_description = open("README").read(), install_requires = [ - "docutils >= 0.3", "nose >= 1.3.0", - "nosexcover >= 1.0.8", "python-coveralls >= 2.4.2", + "sleekxmpp >= 1.1.11" ], ) From eac3ce184ae002fea594b4cbe35e0c1ee5fec2b1 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 9 Jan 2014 18:18:50 +0100 Subject: [PATCH 02/95] Updated README --- README | 40 ++++++++++++++++++++++++++++++++++++++++ README.rst | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/README b/README index 6ce2d1f..109e7e1 100644 --- a/README +++ b/README @@ -32,6 +32,46 @@ Building * **Build**: ``python setup.py build`` and ``sudo python setup.py install`` +* To **run**: ``python main.py`` -- TODO + * To run **unit tests**: ``python setup.py nosetests`` * To **clean**, run: ``python setup.py clean --all`` + +Contributing +============ + +**Everyone** is encouraged to help improve this project. + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by translating to a new language +* by writing or editing documentation +* by writing specifications +* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) +* by refactoring code +* by closing `issues `_ +* by reviewing patches + +Submitting an Issue +=================== + +We use the `GitHub issue tracker `_ to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a `Gist `_ +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your Java version and operating system. + +Submitting a Pull Request +========================= + +1. `Fork the repository `_. +2. `Create a topic branch `_. +3. Implement your feature or bug fix. +4. Run ``python setup.py nosetests``. If the tests fail, return to step 3. +5. If applicable, add tests for your feature or bug fix. +6. Add, commit, and push your changes. +7. `Submit a pull request`_. diff --git a/README.rst b/README.rst index 6ce2d1f..109e7e1 100644 --- a/README.rst +++ b/README.rst @@ -32,6 +32,46 @@ Building * **Build**: ``python setup.py build`` and ``sudo python setup.py install`` +* To **run**: ``python main.py`` -- TODO + * To run **unit tests**: ``python setup.py nosetests`` * To **clean**, run: ``python setup.py clean --all`` + +Contributing +============ + +**Everyone** is encouraged to help improve this project. + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by translating to a new language +* by writing or editing documentation +* by writing specifications +* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) +* by refactoring code +* by closing `issues `_ +* by reviewing patches + +Submitting an Issue +=================== + +We use the `GitHub issue tracker `_ to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a `Gist `_ +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your Java version and operating system. + +Submitting a Pull Request +========================= + +1. `Fork the repository `_. +2. `Create a topic branch `_. +3. Implement your feature or bug fix. +4. Run ``python setup.py nosetests``. If the tests fail, return to step 3. +5. If applicable, add tests for your feature or bug fix. +6. Add, commit, and push your changes. +7. `Submit a pull request`_. From 182fdd63454dad374444d3229c9d32a44ef11e16 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 9 Jan 2014 18:20:35 +0100 Subject: [PATCH 03/95] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 109e7e1..42a978b 100644 --- a/README.rst +++ b/README.rst @@ -74,4 +74,4 @@ Submitting a Pull Request 4. Run ``python setup.py nosetests``. If the tests fail, return to step 3. 5. If applicable, add tests for your feature or bug fix. 6. Add, commit, and push your changes. -7. `Submit a pull request`_. +7. `Submit a pull request `_. From 8e78454d839fdc8d74a34785ddbbd7201a92e501 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 19:22:47 +0100 Subject: [PATCH 04/95] Updated README --- README | 6 +++++- README.rst | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README b/README index 109e7e1..404e6b6 100644 --- a/README +++ b/README @@ -4,9 +4,11 @@ CryptoIM .. image:: https://travis-ci.org/oskopek/CryptoIM.png?branch=develop :target: https://travis-ci.org/oskopek/CryptoIM + :alt: TravisCI .. image:: https://coveralls.io/repos/oskopek/CryptoIM/badge.png?branch=develop :target: https://coveralls.io/r/oskopek/CryptoIM?branch=develop + :alt: Coveralls .. image:: https://pypip.in/v/CryptoIM/badge.png :target: https://pypi.python.org/pypi/CryptoIM/ @@ -20,7 +22,9 @@ CryptoIM :target: https://pypi.python.org/pypi/CryptoIM/ :alt: License -A crypto-aware instant messenger written in Python out of sheer fun. +A secure* instant messenger written in Python out of sheer fun. + +* not really secure (at least not yet) Info ==== diff --git a/README.rst b/README.rst index 109e7e1..404e6b6 100644 --- a/README.rst +++ b/README.rst @@ -4,9 +4,11 @@ CryptoIM .. image:: https://travis-ci.org/oskopek/CryptoIM.png?branch=develop :target: https://travis-ci.org/oskopek/CryptoIM + :alt: TravisCI .. image:: https://coveralls.io/repos/oskopek/CryptoIM/badge.png?branch=develop :target: https://coveralls.io/r/oskopek/CryptoIM?branch=develop + :alt: Coveralls .. image:: https://pypip.in/v/CryptoIM/badge.png :target: https://pypi.python.org/pypi/CryptoIM/ @@ -20,7 +22,9 @@ CryptoIM :target: https://pypi.python.org/pypi/CryptoIM/ :alt: License -A crypto-aware instant messenger written in Python out of sheer fun. +A secure* instant messenger written in Python out of sheer fun. + +* not really secure (at least not yet) Info ==== From a18b85955c329b15c6c488b51bbcd7926d1a5852 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 19:26:09 +0100 Subject: [PATCH 05/95] Added main.py --- README | 2 +- README.rst | 2 +- main.py | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 main.py diff --git a/README b/README index 404e6b6..9bbf184 100644 --- a/README +++ b/README @@ -36,7 +36,7 @@ Building * **Build**: ``python setup.py build`` and ``sudo python setup.py install`` -* To **run**: ``python main.py`` -- TODO +* To **run**: ``python main.py`` * To run **unit tests**: ``python setup.py nosetests`` diff --git a/README.rst b/README.rst index 404e6b6..9bbf184 100644 --- a/README.rst +++ b/README.rst @@ -36,7 +36,7 @@ Building * **Build**: ``python setup.py build`` and ``sudo python setup.py install`` -* To **run**: ``python main.py`` -- TODO +* To **run**: ``python main.py`` * To run **unit tests**: ``python setup.py nosetests`` diff --git a/main.py b/main.py new file mode 100644 index 0000000..c99a8a0 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +if __name__ == "__main__": + print("Not Yet Implemented!"); From d7600689c430137f8f2bc8eb5b2a576906d454ad Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 19:31:25 +0100 Subject: [PATCH 06/95] Fixed licensing issues --- NOTICE.rst | 31 ++++++++++++++++++++++++++----- cryptoim/xmpp_test.py | 20 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/NOTICE.rst b/NOTICE.rst index 3fd21f7..477f601 100644 --- a/NOTICE.rst +++ b/NOTICE.rst @@ -7,9 +7,30 @@ All rights reserved. All Authors and Contributors are named in the AUTHORS.rst file. -Used libraries -============== +Used Third Party Code +===================== -nose 1.3.0 -sleekxmpp 1.1.11 -coveralls-python 2.4.2 +SleekXMPP +========= + +``` +Copyright (c) 2010 Nathanael C. Fritz + +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. +``` diff --git a/cryptoim/xmpp_test.py b/cryptoim/xmpp_test.py index 18125a0..f77a783 100644 --- a/cryptoim/xmpp_test.py +++ b/cryptoim/xmpp_test.py @@ -1,12 +1,28 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" """ SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. - See the file LICENSE for copying permission. + See the file NOTICE.rst file for copying permission. """ import sys From 0672cab784b023957426195038572be4760f239e Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 20:44:27 +0100 Subject: [PATCH 07/95] Remade the xmpp client, added a test --- cryptoim/__init__.py | 4 +- cryptoim/xmpp.py | 152 +++++++++++++++++++++++++++++++++++++ cryptoim/xmpp_test.py | 173 ------------------------------------------ tests/TestXMPP.py | 45 +++++++++++ 4 files changed, 199 insertions(+), 175 deletions(-) create mode 100644 cryptoim/xmpp.py delete mode 100644 cryptoim/xmpp_test.py create mode 100644 tests/TestXMPP.py diff --git a/cryptoim/__init__.py b/cryptoim/__init__.py index 94038e3..8879f68 100644 --- a/cryptoim/__init__.py +++ b/cryptoim/__init__.py @@ -14,6 +14,6 @@ limitations under the License. """ -from cryptoim import decryptor_core, encryptor_core, const, common +from cryptoim import decryptor_core, encryptor_core, const, common, xmpp -__all__ = ["decryptor_core", "encryptor_core", "const", "common", ] +__all__ = ["decryptor_core", "encryptor_core", "const", "common", "xmpp", ] diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py new file mode 100644 index 0000000..c522a89 --- /dev/null +++ b/cryptoim/xmpp.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz + This file is part of SleekXMPP. + + See the file NOTICE.rst file for copying permission. +""" + +import logging +import sleekxmpp + +# Python versions before 3.0 do not use UTF-8 encoding +# by default. To ensure that Unicode is handled properly +# throughout SleekXMPP, we will set the default encoding +# ourselves to UTF-8. +""" +if sys.version_info < (3, 0): + from sleekxmpp.util.misc_ops import setdefaultencoding + setdefaultencoding('utf8') +else: + raw_input = input +""" + +class CryptoXMPP(sleekxmpp.ClientXMPP): + + """ + A simple SleekXMPP client. + """ + + def __init__(self, jid, password): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + + # The session_start event will be triggered when + # the bot establishes its connection with the server + # and the XML streams are ready for use. We want to + # listen for this event so that we we can initialize + # our roster. + self.add_event_handler("session_start", self.start) + + # The message event is triggered whenever a message + # stanza is received. Be aware that that includes + # MUC messages and error messages. + self.add_event_handler("message", self.message) + + def start(self, event): + """ + Process the session_start event. + + Typical actions for the session_start event are + requesting the roster and broadcasting an initial + presence stanza. + + Arguments: + event -- An empty dictionary. The session_start + event does not provide any additional + data. + """ + self.send_presence() + self.get_roster() + + def message(self, msg): + """ + Process incoming message stanzas. Be aware that this also + includes MUC messages and error messages. It is usually + a good idea to check the messages's type before processing + or sending replies. + + Arguments: + msg -- The received message stanza. See the documentation + for stanza objects and the Message stanza to see + how it may be used. + """ + if msg['type'] in ('chat', 'normal'): + msg.reply("Thanks for sending\n%(body)s" % msg).send() + print("DEBUG: MSG: %(body)s" % msg) + + +class XMPPClient(object): + """ + The XMPP client object, used as a wrapper for the SleekXMPP client. + """ + + def __init__(self, jid, password, loglevel=logging.DEBUG): + """ + Initializes the ClientXMPP, logging, etc + """ + + # Setup logging. + logging.basicConfig(level=loglevel, + format='%(levelname)-8s %(message)s') + + # Setup the ClientXMPP and register plugins. Note that while plugins may + # have interdependencies, the order in which you register them does + # not matter. + self.xmpp = CryptoXMPP(jid, password) + self.xmpp.register_plugin('xep_0030') # Service Discovery + self.xmpp.register_plugin('xep_0004') # Data Forms + self.xmpp.register_plugin('xep_0060') # PubSub + self.xmpp.register_plugin('xep_0199') # XMPP Ping + + + def connect_server(self, should_block=False): + """ + Connects the ClientXMPP to the server, specify thread blocking. + """ + + # Connect to the XMPP server and start processing XMPP stanzas. + if self.xmpp.connect(): + # If you do not have the dnspython library installed, you will need + # to manually specify the name of the server if it does not match + # the one in the JID. For example, to use Google Talk you would + # need to use: + # + # if xmpp.connect(('talk.google.com', 5222)): + # ... + self.xmpp.process(block=should_block) + print("Connected.") + else: + print("Unable to connect.") + + def disconnect_server(self): + """ + Disconnects the ClientXMPP from the server. + """ + + self.xmpp.disconnect(wait=True) + + def is_connected(self): + """ + Checks if the ClientXMPP is currently connected to the server. + """ + + return self.xmpp.state.current_state() == "connected" diff --git a/cryptoim/xmpp_test.py b/cryptoim/xmpp_test.py deleted file mode 100644 index f77a783..0000000 --- a/cryptoim/xmpp_test.py +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -""" - Copyright 2014 CryptoIM Development Team - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -""" - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz - This file is part of SleekXMPP. - - See the file NOTICE.rst file for copying permission. -""" - -import sys -import logging -import getpass -from optparse import OptionParser - -import sleekxmpp - -# Python versions before 3.0 do not use UTF-8 encoding -# by default. To ensure that Unicode is handled properly -# throughout SleekXMPP, we will set the default encoding -# ourselves to UTF-8. -if sys.version_info < (3, 0): - from sleekxmpp.util.misc_ops import setdefaultencoding - setdefaultencoding('utf8') -else: - raw_input = input - - -class EchoBot(sleekxmpp.ClientXMPP): - - """ - A simple SleekXMPP bot that will echo messages it - receives, along with a short thank you message. - """ - - def __init__(self, jid, password): - sleekxmpp.ClientXMPP.__init__(self, jid, password) - - # The session_start event will be triggered when - # the bot establishes its connection with the server - # and the XML streams are ready for use. We want to - # listen for this event so that we we can initialize - # our roster. - self.add_event_handler("session_start", self.start) - - # The message event is triggered whenever a message - # stanza is received. Be aware that that includes - # MUC messages and error messages. - self.add_event_handler("message", self.message) - - def start(self, event): - """ - Process the session_start event. - - Typical actions for the session_start event are - requesting the roster and broadcasting an initial - presence stanza. - - Arguments: - event -- An empty dictionary. The session_start - event does not provide any additional - data. - """ - self.send_presence() - self.get_roster() - - def message(self, msg): - """ - Process incoming message stanzas. Be aware that this also - includes MUC messages and error messages. It is usually - a good idea to check the messages's type before processing - or sending replies. - - Arguments: - msg -- The received message stanza. See the documentation - for stanza objects and the Message stanza to see - how it may be used. - """ - if msg['type'] in ('chat', 'normal'): - msg.reply("Thanks for sending\n%(body)s" % msg).send() - - -if __name__ == '__main__': - # Setup the command line arguments. - optp = OptionParser() - - # Output verbosity options. - optp.add_option('-q', '--quiet', help='set logging to ERROR', - action='store_const', dest='loglevel', - const=logging.ERROR, default=logging.INFO) - optp.add_option('-d', '--debug', help='set logging to DEBUG', - action='store_const', dest='loglevel', - const=logging.DEBUG, default=logging.INFO) - optp.add_option('-v', '--verbose', help='set logging to COMM', - action='store_const', dest='loglevel', - const=5, default=logging.INFO) - - # JID and password options. - optp.add_option("-j", "--jid", dest="jid", - help="JID to use") - optp.add_option("-p", "--password", dest="password", - help="password to use") - - opts, args = optp.parse_args() - - # Setup logging. - logging.basicConfig(level=opts.loglevel, - format='%(levelname)-8s %(message)s') - - if opts.jid is None: - opts.jid = raw_input("Username: ") - if opts.password is None: - opts.password = getpass.getpass("Password: ") - - # Setup the EchoBot and register plugins. Note that while plugins may - # have interdependencies, the order in which you register them does - # not matter. - xmpp = EchoBot(opts.jid, opts.password) - xmpp.register_plugin('xep_0030') # Service Discovery - xmpp.register_plugin('xep_0004') # Data Forms - xmpp.register_plugin('xep_0060') # PubSub - xmpp.register_plugin('xep_0199') # XMPP Ping - - # If you are connecting to Facebook and wish to use the - # X-FACEBOOK-PLATFORM authentication mechanism, you will need - # your API key and an access token. Then you'll set: - # xmpp.credentials['api_key'] = 'THE_API_KEY' - # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' - - # If you are connecting to MSN, then you will need an - # access token, and it does not matter what JID you - # specify other than that the domain is 'messenger.live.com', - # so '_@messenger.live.com' will work. You can specify - # the access token as so: - # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN' - - # If you are working with an OpenFire server, you may need - # to adjust the SSL version used: - # xmpp.ssl_version = ssl.PROTOCOL_SSLv3 - - # If you want to verify the SSL certificates offered by a server: - # xmpp.ca_certs = "path/to/ca/cert" - - # Connect to the XMPP server and start processing XMPP stanzas. - if xmpp.connect(): - # If you do not have the dnspython library installed, you will need - # to manually specify the name of the server if it does not match - # the one in the JID. For example, to use Google Talk you would - # need to use: - # - # if xmpp.connect(('talk.google.com', 5222)): - # ... - xmpp.process(block=False) - print("Done") - else: - print("Unable to connect.") diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py new file mode 100644 index 0000000..c90e150 --- /dev/null +++ b/tests/TestXMPP.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import cryptoim.xmpp as xmpp +from nose.tools import ok_, eq_, with_setup + +def test_xmpp_connection(): + xmpp_cli = xmpp.XMPPClient("cryptoim@jabber.de", "crypto_test") + xmpp_cli.connect_server(should_block=False) + yield check_connect, xmpp_cli + +def check_connect(xmpp_client): + """ + Check for xmpp.xmpp_client.connectServer and disconnectServer + """ + + eq_(xmpp_client.is_connected(), True) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + + # Uncomment the following to enable a second check -- note, will require a ~10s timeout + """ + xmpp_client.connect_server() + eq_(xmpp_client.is_connected(), True) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + """ From 933901e9c34878ce89e76320101b436f6845f84c Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 22:40:49 +0100 Subject: [PATCH 08/95] Added a lot of functionality to xmpp and it's test --- cryptoim/xmpp.py | 63 +++++++++++++++++++++++---- tests/TestXMPP.py | 107 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 156 insertions(+), 14 deletions(-) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index c522a89..ac26980 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -45,6 +45,8 @@ class CryptoXMPP(sleekxmpp.ClientXMPP): """ A simple SleekXMPP client. """ + in_session = False + is_connected = False def __init__(self, jid, password): sleekxmpp.ClientXMPP.__init__(self, jid, password) @@ -54,12 +56,37 @@ def __init__(self, jid, password): # and the XML streams are ready for use. We want to # listen for this event so that we we can initialize # our roster. - self.add_event_handler("session_start", self.start) + self.add_event_handler('session_start', self.start) + self.add_event_handler('session_end', self.session_end) # The message event is triggered whenever a message # stanza is received. Be aware that that includes # MUC messages and error messages. - self.add_event_handler("message", self.message) + self.add_event_handler('message', self.message) + + self.add_event_handler('connected', self.connected) + self.add_event_handler('disconnected', self.disconnected) + + def connected(self, event): + """ + Process the connected event. + """ + + self.is_connected = True + + def disconnected(self, event): + """ + Process the disconnected event. + """ + + self.is_connected = False + + def session_end(self, event): + """ + Process the session_end event. + """ + + self.in_session = False def start(self, event): """ @@ -76,6 +103,7 @@ def start(self, event): """ self.send_presence() self.get_roster() + self.in_session = True def message(self, msg): """ @@ -89,9 +117,12 @@ def message(self, msg): for stanza objects and the Message stanza to see how it may be used. """ + + # TODO Implement a queue here: http://docs.python.org/3.3/library/queue.html + if msg['type'] in ('chat', 'normal'): - msg.reply("Thanks for sending\n%(body)s" % msg).send() - print("DEBUG: MSG: %(body)s" % msg) + msg.reply('Thanks for sending\n%(body)s' % msg).send() + print('DEBUG: MSG: %(body)s' % msg) class XMPPClient(object): @@ -118,13 +149,13 @@ def __init__(self, jid, password, loglevel=logging.DEBUG): self.xmpp.register_plugin('xep_0199') # XMPP Ping - def connect_server(self, should_block=False): + def connect_server(self, should_block=False, should_reattempt=True): """ Connects the ClientXMPP to the server, specify thread blocking. """ # Connect to the XMPP server and start processing XMPP stanzas. - if self.xmpp.connect(): + if self.xmpp.connect(reattempt=should_reattempt): # If you do not have the dnspython library installed, you will need # to manually specify the name of the server if it does not match # the one in the JID. For example, to use Google Talk you would @@ -133,9 +164,9 @@ def connect_server(self, should_block=False): # if xmpp.connect(('talk.google.com', 5222)): # ... self.xmpp.process(block=should_block) - print("Connected.") + print('Connected.') else: - print("Unable to connect.") + print('Unable to connect.') def disconnect_server(self): """ @@ -149,4 +180,18 @@ def is_connected(self): Checks if the ClientXMPP is currently connected to the server. """ - return self.xmpp.state.current_state() == "connected" + return self.xmpp.is_connected + + def is_in_session(self): + """ + Checks if the ClientXMPP is currently in a session + """ + + return self.xmpp.in_session + + def send_message(self, recipient, msg): + """ + Sends a chat message to the designated recipient. + """ + + self.xmpp.send_message(mto = recipient, mbody = msg, mtype = 'chat') diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index c90e150..3b83540 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -18,16 +18,36 @@ """ import cryptoim.xmpp as xmpp -from nose.tools import ok_, eq_, with_setup +from nose.tools import ok_, eq_, nottest +import time -def test_xmpp_connection(): - xmpp_cli = xmpp.XMPPClient("cryptoim@jabber.de", "crypto_test") +def test_xmpp(): + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') xmpp_cli.connect_server(should_block=False) + + eq_(xmpp_cli.is_connected(), True) + yield check_connect, xmpp_cli + # TODO fix this reuse + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') + xmpp_cli.connect_server(should_block=False) + + eq_(xmpp_cli.is_connected(), True) + + yield check_send_message, xmpp_cli + + # TODO fix this reuse + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') + xmpp_cli.connect_server(should_block=False) + + eq_(xmpp_cli.is_connected(), True) + + yield check_receive_message, xmpp_cli + def check_connect(xmpp_client): """ - Check for xmpp.xmpp_client.connectServer and disconnectServer + Check for xmpp.XMPPClient.connect_server and disconnect_server """ eq_(xmpp_client.is_connected(), True) @@ -37,9 +57,86 @@ def check_connect(xmpp_client): # Uncomment the following to enable a second check -- note, will require a ~10s timeout """ - xmpp_client.connect_server() + xmpp_client.connect_server(should_block=False) + eq_(xmpp_client.is_connected(), True) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + """ + +def check_send_message(xmpp_client): + """ + Check for xmpp.XMPPClient.send_message + """ + eq_(xmpp_client.is_connected(), True) + while not xmpp_client.is_in_session(): + time.sleep(0.1) + + # TODO Works, but check + xmpp_client.send_message('cryptoim2@jabber.de', 'Hello, CryptoIM check_send_message!') + xmpp_client.disconnect_server() eq_(xmpp_client.is_connected(), False) + + + +def test_not_connect(): + """ + Check for xmpp.XMPPClient.connect_server and disconnect_server """ + + # Wrong host + xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test') + xmpp_client.connect_server(should_block=False, should_reattempt=False) + + eq_(xmpp_client.is_connected(), False) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + + + # Wrong pass + xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'wrong_pass') + xmpp_client.connect_server(should_block=False, should_reattempt=False) + + eq_(xmpp_client.is_connected(), False) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + + # Wrong name + xmpp_client = xmpp.XMPPClient('cryptoim0@jabber.de', 'crypto_test') + xmpp_client.connect_server(should_block=False, should_reattempt=False) + + eq_(xmpp_client.is_connected(), False) + + xmpp_client.disconnect_server() + eq_(xmpp_client.is_connected(), False) + + +def check_receive_message(xmpp_client): + """ + Check for CryptoXMPP.message + """ + + # Assert connected + xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2') + xmpp_client2.connect_server(should_block=False) + eq_(xmpp_client.is_connected(), True) + eq_(xmpp_client2.is_connected(), True) + + while not (xmpp_client.is_in_session() and xmpp_client2.is_in_session()): + time.sleep(0.1) + + # Send and receive message + xmpp_client.send_message(xmpp_client2.xmpp.jid, 'Hello, CryptoIM check_receive_message!') + + # TODO Assert that xmpp_client2 got it + + # Disconnect + xmpp_client.disconnect_server(); + eq_(xmpp_client.is_connected(), False) + xmpp_client2.disconnect_server() + eq_(xmpp_client2.is_connected(), False) From 3fc54f7efac3f1672b448b0128e445af56dc0d4d Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 22:42:31 +0100 Subject: [PATCH 09/95] Escaping characters in README --- README | 4 ++-- README.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 9bbf184..da919ce 100644 --- a/README +++ b/README @@ -24,7 +24,7 @@ CryptoIM A secure* instant messenger written in Python out of sheer fun. -* not really secure (at least not yet) +\* not really secure (at least not yet) Info ==== @@ -78,4 +78,4 @@ Submitting a Pull Request 4. Run ``python setup.py nosetests``. If the tests fail, return to step 3. 5. If applicable, add tests for your feature or bug fix. 6. Add, commit, and push your changes. -7. `Submit a pull request`_. +7. `Submit a pull request `_. diff --git a/README.rst b/README.rst index c6608c3..da919ce 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ CryptoIM A secure* instant messenger written in Python out of sheer fun. -* not really secure (at least not yet) +\* not really secure (at least not yet) Info ==== From 81d637983e3665b520e1812fb4b2abf0dc8ec31f Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 13 Jan 2014 23:18:13 +0100 Subject: [PATCH 10/95] Fixed waiting for connections on slower networks for xmpp test --- tests/TestXMPP.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 3b83540..994847a 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -50,18 +50,18 @@ def check_connect(xmpp_client): Check for xmpp.XMPPClient.connect_server and disconnect_server """ - eq_(xmpp_client.is_connected(), True) + waitForConnection(xmpp_client, True) xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) # Uncomment the following to enable a second check -- note, will require a ~10s timeout """ xmpp_client.connect_server(should_block=False) - eq_(xmpp_client.is_connected(), True) + waitForConnection(xmpp_client, True) xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) """ def check_send_message(xmpp_client): @@ -69,7 +69,7 @@ def check_send_message(xmpp_client): Check for xmpp.XMPPClient.send_message """ - eq_(xmpp_client.is_connected(), True) + waitForConnection(xmpp_client, True) while not xmpp_client.is_in_session(): time.sleep(0.1) @@ -78,7 +78,7 @@ def check_send_message(xmpp_client): xmpp_client.send_message('cryptoim2@jabber.de', 'Hello, CryptoIM check_send_message!') xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) @@ -91,29 +91,29 @@ def test_not_connect(): xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test') xmpp_client.connect_server(should_block=False, should_reattempt=False) - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) # Wrong pass xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'wrong_pass') xmpp_client.connect_server(should_block=False, should_reattempt=False) - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) # Wrong name xmpp_client = xmpp.XMPPClient('cryptoim0@jabber.de', 'crypto_test') xmpp_client.connect_server(should_block=False, should_reattempt=False) - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) xmpp_client.disconnect_server() - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) def check_receive_message(xmpp_client): @@ -124,8 +124,8 @@ def check_receive_message(xmpp_client): # Assert connected xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2') xmpp_client2.connect_server(should_block=False) - eq_(xmpp_client.is_connected(), True) - eq_(xmpp_client2.is_connected(), True) + waitForConnection(xmpp_client, True) + waitForConnection(xmpp_client2, True) while not (xmpp_client.is_in_session() and xmpp_client2.is_in_session()): time.sleep(0.1) @@ -137,6 +137,13 @@ def check_receive_message(xmpp_client): # Disconnect xmpp_client.disconnect_server(); - eq_(xmpp_client.is_connected(), False) + waitForConnection(xmpp_client, False) xmpp_client2.disconnect_server() - eq_(xmpp_client2.is_connected(), False) + waitForConnection(xmpp_client2, False) + waitForConnection(xmpp_client, False) + +def waitForConnection(xmpp_client, should_be_connected): + while not xmpp_client.is_connected() == should_be_connected: + time.sleep(0.1) + eq_(xmpp_client.is_connected(), should_be_connected) + From f6b9794384febfad57fba77a73fd95bb5b71f384 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 14 Jan 2014 10:32:20 +0100 Subject: [PATCH 11/95] Added cli.py command line interface --- cryptoim/cli.py | 41 +++++++++++++++++++++++++++++++++++++++++ main.py | 4 +++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 cryptoim/cli.py mode change 100644 => 100755 main.py diff --git a/cryptoim/cli.py b/cryptoim/cli.py new file mode 100644 index 0000000..3d72fb4 --- /dev/null +++ b/cryptoim/cli.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this logfile except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import cmd + +class CryptoShell(cmd.Cmd): + intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' + prompt = '(cryptoim) ' + + # ----- basic commands ----- + def do_exit(self, arg): + 'Quit CryptoIM' + + print('Thank you for using CryptoIM!') + quit() + + + # -- overrides -- + def emptyline(self): + return + + +def parse(arg): + 'Convert a series of zero or more numbers to an argument tuple' + return tuple(map(int, arg.split())) diff --git a/main.py b/main.py old mode 100644 new mode 100755 index c99a8a0..d6e49be --- a/main.py +++ b/main.py @@ -17,5 +17,7 @@ limitations under the License. """ +from cryptoim.cli import CryptoShell + if __name__ == "__main__": - print("Not Yet Implemented!"); + CryptoShell().cmdloop() From ecfc5e406ce39fcf60792a1c755989ddb2c5b38a Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 14 Jan 2014 10:39:31 +0100 Subject: [PATCH 12/95] Added comments --- cryptoim/cli.py | 3 ++- cryptoim/xmpp.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 3d72fb4..3629fdf 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -23,7 +23,7 @@ class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' - # ----- basic commands ----- + # -- basic commands -- def do_exit(self, arg): 'Quit CryptoIM' @@ -35,6 +35,7 @@ def do_exit(self, arg): def emptyline(self): return + # -- xmpp commands -- def parse(arg): 'Convert a series of zero or more numbers to an argument tuple' diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index ac26980..04be179 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -15,9 +15,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -""" -""" +Original LICENSE: + SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. From f9421502b466b42981cb1dec129d6f12c3adb166 Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 15 Jan 2014 20:13:06 +0100 Subject: [PATCH 13/95] test commit --- cryptoim/encryptor_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptoim/encryptor_core.py b/cryptoim/encryptor_core.py index fbb4b88..bfc5266 100644 --- a/cryptoim/encryptor_core.py +++ b/cryptoim/encryptor_core.py @@ -65,7 +65,7 @@ def __split_message(plaintext): message_chunks.append(message_chunk) message_chunk = '' if i == (len(plaintext)-1) and len(message_chunk) < 16: - message_chunk += (16-len(message_chunk))*"\x00" + message_chunk += (16-len(message_chunk)) * "\x00" message_chunks.append(message_chunk) message_chunk = '' messages = [] From af746b50fd492799558f8cea033edff3a439bb45 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Wed, 15 Jan 2014 23:38:38 +0100 Subject: [PATCH 14/95] Added basic xmpp chat functionality --- cryptoim/__init__.py | 4 ++-- cryptoim/cli.py | 52 +++++++++++++++++++++++++++++++++++++++++--- cryptoim/xmpp.py | 28 +++++++++++++++--------- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/cryptoim/__init__.py b/cryptoim/__init__.py index 8879f68..efcf547 100644 --- a/cryptoim/__init__.py +++ b/cryptoim/__init__.py @@ -14,6 +14,6 @@ limitations under the License. """ -from cryptoim import decryptor_core, encryptor_core, const, common, xmpp +from cryptoim import decryptor_core, encryptor_core, const, common, xmpp, cli -__all__ = ["decryptor_core", "encryptor_core", "const", "common", "xmpp", ] +__all__ = ["decryptor_core", "encryptor_core", "const", "common", "xmpp", "cli", ] diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 3629fdf..496f044 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -19,14 +19,19 @@ import cmd +import cryptoim.xmpp + class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' + xmpp_client = None + # -- basic commands -- def do_exit(self, arg): 'Quit CryptoIM' + self.do_disconnect(arg) print('Thank you for using CryptoIM!') quit() @@ -35,8 +40,49 @@ def do_exit(self, arg): def emptyline(self): return + # -- xmpp commands -- + def do_connect(self, arg): + 'connect JID PASSWORD' + + if self.xmpp_client and self.xmpp_client.is_connected(): + self.print_cmd('Already connected!') + return + + splitted = arg.split(' ') + self.xmpp_client = cryptoim.xmpp.XMPPClient(splitted[0], splitted[1], self) + self.xmpp_client.connect_server() + + def do_disconnect(self, arg): + 'disconnect' + if not self.xmpp_client or not self.xmpp_client.is_connected(): + self.print_cmd('Already disconnected!') + return + + self.xmpp_client.disconnect_server() + + def do_send(self, arg): + 'send toJID msg' + if not self.xmpp_client or not self.xmpp_client.is_in_session(): + self.print_cmd('Connect first!') + return -def parse(arg): - 'Convert a series of zero or more numbers to an argument tuple' - return tuple(map(int, arg.split())) + splitted = arg.split(' ') + self.xmpp_client.send_message(splitted[0], splitted[1]) + + # TODO fix the jid part + self.print_msg(self.xmpp_client.xmpp.jid, splitted[1]) + + + # -- tools -- + + def print_cmd(self, string): + print(string) + + def print_msg(self, jid, msg): + # TODO interface with cmd in a normal way + self.print_cmd(jid + ': ' + msg) + + def print_debug(self, msg): + #self.print_cmd('DEBUG: ' + msg) + return diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 04be179..2de8e86 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -28,6 +28,9 @@ import logging import sleekxmpp +from cryptoim.cli import CryptoShell + + # Python versions before 3.0 do not use UTF-8 encoding # by default. To ensure that Unicode is handled properly # throughout SleekXMPP, we will set the default encoding @@ -40,15 +43,16 @@ raw_input = input """ -class CryptoXMPP(sleekxmpp.ClientXMPP): +class CryptoXMPP(sleekxmpp.ClientXMPP, CryptoShell): """ A simple SleekXMPP client. """ in_session = False is_connected = False + parent = None - def __init__(self, jid, password): + def __init__(self, jid, password, parent): sleekxmpp.ClientXMPP.__init__(self, jid, password) # The session_start event will be triggered when @@ -67,6 +71,8 @@ def __init__(self, jid, password): self.add_event_handler('connected', self.connected) self.add_event_handler('disconnected', self.disconnected) + self.parent = parent + def connected(self, event): """ Process the connected event. @@ -104,6 +110,7 @@ def start(self, event): self.send_presence() self.get_roster() self.in_session = True + self.parent.print_debug('Session started!') def message(self, msg): """ @@ -120,9 +127,11 @@ def message(self, msg): # TODO Implement a queue here: http://docs.python.org/3.3/library/queue.html - if msg['type'] in ('chat', 'normal'): - msg.reply('Thanks for sending\n%(body)s' % msg).send() - print('DEBUG: MSG: %(body)s' % msg) + self.parent.print_msg(msg['from'].bare, msg['body']) + + #if msg['type'] in ('chat', 'normal'): + #msg.reply('Thanks for sending\n%(body)s' % msg).send() + #print('DEBUG: MSG: %(body)s' % msg) class XMPPClient(object): @@ -130,7 +139,9 @@ class XMPPClient(object): The XMPP client object, used as a wrapper for the SleekXMPP client. """ - def __init__(self, jid, password, loglevel=logging.DEBUG): + xmpp = None + + def __init__(self, jid, password, parent, loglevel=logging.CRITICAL): """ Initializes the ClientXMPP, logging, etc """ @@ -142,7 +153,7 @@ def __init__(self, jid, password, loglevel=logging.DEBUG): # Setup the ClientXMPP and register plugins. Note that while plugins may # have interdependencies, the order in which you register them does # not matter. - self.xmpp = CryptoXMPP(jid, password) + self.xmpp = CryptoXMPP(jid, password, parent) self.xmpp.register_plugin('xep_0030') # Service Discovery self.xmpp.register_plugin('xep_0004') # Data Forms self.xmpp.register_plugin('xep_0060') # PubSub @@ -164,9 +175,6 @@ def connect_server(self, should_block=False, should_reattempt=True): # if xmpp.connect(('talk.google.com', 5222)): # ... self.xmpp.process(block=should_block) - print('Connected.') - else: - print('Unable to connect.') def disconnect_server(self): """ From 034d0571c7ed3bb32f09e396f10a7e3d0745ddbc Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 15:44:48 +0100 Subject: [PATCH 15/95] Quick commit --- cryptoim/cli.py | 41 +++++++++++++++++++++++++++++++++++------ cryptoim/xmpp.py | 13 ------------- main.cfg | 13 +++++++++++++ main.py | 2 +- 4 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 main.cfg diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 496f044..4407894 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -17,7 +17,8 @@ limitations under the License. """ -import cmd +import cmd, sys +import configparser as configparser import cryptoim.xmpp @@ -25,8 +26,14 @@ class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' xmpp_client = None + config = None + def __init__(self, configfile): + super().__init__() + self.config = configparser.ConfigParser() + self.config.read(configfile) + # -- basic commands -- def do_exit(self, arg): 'Quit CryptoIM' @@ -35,24 +42,46 @@ def do_exit(self, arg): print('Thank you for using CryptoIM!') quit() + def do_q(self, arg): + self.do_exit(arg) + # -- overrides -- def emptyline(self): return - # -- xmpp commands -- def do_connect(self, arg): - 'connect JID PASSWORD' + 'connect JID PASSWORD or connect CONNECTION_NAME' + splitted = arg.split(' ') + if not len(splitted) in range(1,2): + self.print_cmd('Invalid number of arguments!') + return if self.xmpp_client and self.xmpp_client.is_connected(): self.print_cmd('Already connected!') return - splitted = arg.split(' ') - self.xmpp_client = cryptoim.xmpp.XMPPClient(splitted[0], splitted[1], self) + conn_jid = None + conn_pass = None + + if len(splitted) == 1: + if splitted[0] in self.config.sections(): + username = self.config[arg]['Username'] + host = self.config[arg]['Host'] + conn_jid = username + '@' + host + conn_pass = self.config[arg]['Password'] + else: + self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist'); + + elif len(splitted) == 2: + conn_jid = splitted[0] + conn_pass = splitted[1] + + self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() + def do_disconnect(self, arg): 'disconnect' if not self.xmpp_client or not self.xmpp_client.is_connected(): @@ -77,7 +106,7 @@ def do_send(self, arg): # -- tools -- def print_cmd(self, string): - print(string) + self.stdout.write(string+'\n') def print_msg(self, jid, msg): # TODO interface with cmd in a normal way diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 2de8e86..f81581f 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -30,19 +30,6 @@ from cryptoim.cli import CryptoShell - -# Python versions before 3.0 do not use UTF-8 encoding -# by default. To ensure that Unicode is handled properly -# throughout SleekXMPP, we will set the default encoding -# ourselves to UTF-8. -""" -if sys.version_info < (3, 0): - from sleekxmpp.util.misc_ops import setdefaultencoding - setdefaultencoding('utf8') -else: - raw_input = input -""" - class CryptoXMPP(sleekxmpp.ClientXMPP, CryptoShell): """ diff --git a/main.cfg b/main.cfg new file mode 100644 index 0000000..b85e563 --- /dev/null +++ b/main.cfg @@ -0,0 +1,13 @@ +[cryptoim1] +Username: cryptoim +Host: jabber.de +Password: crypto_test + +[cryptoim2] +Username: cryptoim2 +Host: jabber.de +Password: crypto_test2 + +[friends] +cryptoim1: cryptoim@jabber.de +cryptoim2: cryptoim2@jabber.de diff --git a/main.py b/main.py index d6e49be..3a0c1de 100755 --- a/main.py +++ b/main.py @@ -20,4 +20,4 @@ from cryptoim.cli import CryptoShell if __name__ == "__main__": - CryptoShell().cmdloop() + CryptoShell('main.cfg').cmdloop() From 4ab57bebaac6e2793672acbdd09f6735a567ea51 Mon Sep 17 00:00:00 2001 From: mators11 Date: Fri, 17 Jan 2014 21:12:47 +0100 Subject: [PATCH 16/95] Added encryption and decryption of messages --- cryptoim/cli.py | 2 +- cryptoim/xmpp.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 4407894..00d36ea 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -48,7 +48,7 @@ def do_q(self, arg): # -- overrides -- def emptyline(self): - return + pass # -- xmpp commands -- def do_connect(self, arg): diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index f81581f..73f6d25 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -28,8 +28,12 @@ import logging import sleekxmpp +import cryptoim.encryptor_core as encryptor +import cryptoim.decryptor_core as decryptor + from cryptoim.cli import CryptoShell + class CryptoXMPP(sleekxmpp.ClientXMPP, CryptoShell): """ @@ -112,9 +116,9 @@ def message(self, msg): how it may be used. """ - # TODO Implement a queue here: http://docs.python.org/3.3/library/queue.html - - self.parent.print_msg(msg['from'].bare, msg['body']) + ciphertext = msg['body'] + decrypted_message = decryptor.decrypt(ciphertext, 'This is a secret key') + self.parent.print_msg(msg['from'].bare, decrypted_message) #if msg['type'] in ('chat', 'normal'): #msg.reply('Thanks for sending\n%(body)s' % msg).send() @@ -188,5 +192,6 @@ def send_message(self, recipient, msg): """ Sends a chat message to the designated recipient. """ - - self.xmpp.send_message(mto = recipient, mbody = msg, mtype = 'chat') + plaintext = msg + plaintext = encryptor.encrypt(plaintext, 'This is a secret key') + self.xmpp.send_message(mto = recipient, mbody = plaintext, mtype = 'chat') From 9a159f0d97cc2760a486165d29bf6b5d5f94fb4c Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 21:14:29 +0100 Subject: [PATCH 17/95] Fixed python2 compatibility --- cryptoim/cli.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 4407894..90d656b 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -17,11 +17,16 @@ limitations under the License. """ -import cmd, sys -import configparser as configparser +import cmd, sys, copy import cryptoim.xmpp +if sys.version_info < (3, 0): + import ConfigParser as configparser +else: + import configparser as configparser + + class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' @@ -30,7 +35,8 @@ class CryptoShell(cmd.Cmd): def __init__(self, configfile): - super().__init__() + # super().__init__() # Python 3 only + cmd.Cmd.__init__(self) self.config = configparser.ConfigParser() self.config.read(configfile) @@ -39,7 +45,7 @@ def do_exit(self, arg): 'Quit CryptoIM' self.do_disconnect(arg) - print('Thank you for using CryptoIM!') + self.print_cmd('Thank you for using CryptoIM!') quit() def do_q(self, arg): @@ -54,7 +60,7 @@ def emptyline(self): def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') - if not len(splitted) in range(1,2): + if not arg or (not len(splitted) == 1 and not len(splitted) == 2): self.print_cmd('Invalid number of arguments!') return @@ -67,10 +73,10 @@ def do_connect(self, arg): if len(splitted) == 1: if splitted[0] in self.config.sections(): - username = self.config[arg]['Username'] - host = self.config[arg]['Host'] + username = self.config.get(arg, 'Username') # self.config[arg]['Username'] + host = self.config.get(arg, 'Host') # self.config[arg]['Host'] conn_jid = username + '@' + host - conn_pass = self.config[arg]['Password'] + conn_pass = self.config.get(arg, 'Password') # self.config[arg]['Password'] else: self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist'); @@ -106,6 +112,10 @@ def do_send(self, arg): # -- tools -- def print_cmd(self, string): + #backup = copy(string) + #for i in range(len(string)): + + self.stdout.write(string+'\n') def print_msg(self, jid, msg): From e426e1db24d8867ef94d324a835067a74272940b Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 22:12:22 +0100 Subject: [PATCH 18/95] Pseudo-fixed command line prompt overwriting --- cryptoim/cli.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 90d656b..4ec460b 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -106,22 +106,27 @@ def do_send(self, arg): self.xmpp_client.send_message(splitted[0], splitted[1]) # TODO fix the jid part - self.print_msg(self.xmpp_client.xmpp.jid, splitted[1]) + self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, splitted[1])) # -- tools -- def print_cmd(self, string): - #backup = copy(string) - #for i in range(len(string)): + self.stdout.write(string + '\n') + self.stdout.flush() - - self.stdout.write(string+'\n') + def address_format(self, jid, msg): + return jid + ': ' + msg def print_msg(self, jid, msg): # TODO interface with cmd in a normal way - self.print_cmd(jid + ': ' + msg) + backup = copy.copy(self.prompt) + self.stdout.write('\r \r') + self.stdout.flush() + self.print_cmd(self.address_format(jid, msg)) + self.stdout.write(backup) + self.stdout.flush() def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) - return + pass From f018a027999a74fc7ad35946a24dbf5bfda016bb Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 22:15:00 +0100 Subject: [PATCH 19/95] Fixes issue #8 --- cryptoim/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 4ec460b..87723a8 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -84,6 +84,7 @@ def do_connect(self, arg): conn_jid = splitted[0] conn_pass = splitted[1] + conn_jid += '/cryptoim' # Adds a static resource self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() From 2641e78ab032a1b9925cb31472e8e8fb6b2c1846 Mon Sep 17 00:00:00 2001 From: mators11 Date: Fri, 17 Jan 2014 22:18:07 +0100 Subject: [PATCH 20/95] Started working on friendlist --- cryptoim/cli.py | 16 ++++++++++++++-- main.cfg | 3 +-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 00d36ea..4952c8e 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -97,10 +97,22 @@ def do_send(self, arg): return splitted = arg.split(' ') - self.xmpp_client.send_message(splitted[0], splitted[1]) + recipient = splitted[0] + message = ''.join(splitted[1:]) + self.xmpp_client.send_message(recipient, message) # TODO fix the jid part - self.print_msg(self.xmpp_client.xmpp.jid, splitted[1]) + self.print_msg(self.xmpp_client.xmpp.jid, message) + + def do_addfriend(self, arg): + splitted = arg.split(' ') + Friends = self.config['friends'] + Friends[splitted[0]] = splitted[1] + return + + + + # -- tools -- diff --git a/main.cfg b/main.cfg index b85e563..495b565 100644 --- a/main.cfg +++ b/main.cfg @@ -9,5 +9,4 @@ Host: jabber.de Password: crypto_test2 [friends] -cryptoim1: cryptoim@jabber.de -cryptoim2: cryptoim2@jabber.de +cryptoim1: cryptoim1@jabber.de From c41aec0b30434db48c68622c06b724850512038f Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 22:50:34 +0100 Subject: [PATCH 21/95] Kinda fixed #4 --- cryptoim/cli.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 87723a8..baa48a4 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -106,7 +106,6 @@ def do_send(self, arg): splitted = arg.split(' ') self.xmpp_client.send_message(splitted[0], splitted[1]) - # TODO fix the jid part self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, splitted[1])) @@ -120,9 +119,9 @@ def address_format(self, jid, msg): return jid + ': ' + msg def print_msg(self, jid, msg): - # TODO interface with cmd in a normal way + # TODO implement backup backup = copy.copy(self.prompt) - self.stdout.write('\r \r') + self.stdout.write('\r') self.stdout.flush() self.print_cmd(self.address_format(jid, msg)) self.stdout.write(backup) From 595454594ca9cc2678c3cc23876bd1f25d43c8bd Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 22:58:55 +0100 Subject: [PATCH 22/95] Added cryptoim2 friend, fixed message joining with spaces --- cryptoim/cli.py | 2 +- main.cfg | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 4952c8e..8abf745 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -98,7 +98,7 @@ def do_send(self, arg): splitted = arg.split(' ') recipient = splitted[0] - message = ''.join(splitted[1:]) + message = ' '.join(splitted[1:]) self.xmpp_client.send_message(recipient, message) # TODO fix the jid part diff --git a/main.cfg b/main.cfg index 495b565..acf1daa 100644 --- a/main.cfg +++ b/main.cfg @@ -10,3 +10,4 @@ Password: crypto_test2 [friends] cryptoim1: cryptoim1@jabber.de +cryptoim2: cryptoim2@jabber.de From 39ce588d6901f2d919ef77e1abf81cbdf2029d59 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 23:39:40 +0100 Subject: [PATCH 23/95] Formatted and refactored --- cryptoim/cli.py | 45 +++++++++++++++++++++++++++++++++++---------- cryptoim/xmpp.py | 5 +---- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 0b05d21..f42b7d0 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -5,7 +5,7 @@ Copyright 2014 CryptoIM Development Team Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this logfile except in compliance with the License. + you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -28,6 +28,10 @@ class CryptoShell(cmd.Cmd): + """ + CryptoShell + """ + intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' xmpp_client = None @@ -35,6 +39,10 @@ class CryptoShell(cmd.Cmd): def __init__(self, configfile): + """ + CryptoShell init + """ + # super().__init__() # Python 3 only cmd.Cmd.__init__(self) self.config = configparser.ConfigParser() @@ -49,6 +57,7 @@ def do_exit(self, arg): quit() def do_q(self, arg): + 'Alias for quit' self.do_exit(arg) @@ -78,7 +87,7 @@ def do_connect(self, arg): conn_jid = username + '@' + host conn_pass = self.config.get(arg, 'Password') # self.config[arg]['Password'] else: - self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist'); + self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') elif len(splitted) == 2: conn_jid = splitted[0] @@ -107,32 +116,48 @@ def do_send(self, arg): recipient = splitted[0] message = ' '.join(splitted[1:]) self.xmpp_client.send_message(recipient, message) - self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) + self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) def do_addfriend(self, arg): + 'addfriend name jid' splitted = arg.split(' ') - Friends = self.config['friends'] - Friends[splitted[0]] = splitted[1] + friends = self.config['friends'] + friends[splitted[0]] = splitted[1] # -- tools -- def print_cmd(self, string): + """ + Prints a string to the console + """ self.stdout.write(string + '\n') self.stdout.flush() - def address_format(self, jid, msg): - return jid + ': ' + msg - def print_msg(self, jid, msg): - # TODO implement backup + """ + Prints a message (jid + msg), correctly formatted using address_format + without erasing typed content. TODO implement the erasing and backup + """ + backup = copy.copy(self.prompt) self.stdout.write('\r') self.stdout.flush() - self.print_cmd(self.address_format(jid, msg)) + self.print_cmd(address_format(jid, msg)) self.stdout.write(backup) self.stdout.flush() def print_debug(self, msg): + """ + Prints debug messages + """ #self.print_cmd('DEBUG: ' + msg) pass + +# End of class + +def address_format(jid, msg): + """ + Formats a jid and message to correctly display in the log + """ + return(jid + ': ' + msg) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 73f6d25..04a373e 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -31,10 +31,7 @@ import cryptoim.encryptor_core as encryptor import cryptoim.decryptor_core as decryptor -from cryptoim.cli import CryptoShell - - -class CryptoXMPP(sleekxmpp.ClientXMPP, CryptoShell): +class CryptoXMPP(sleekxmpp.ClientXMPP): """ A simple SleekXMPP client. From f7a4245cad82df9785b085fbe1191935d38fb26e Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 17 Jan 2014 23:39:51 +0100 Subject: [PATCH 24/95] Fixed tests and added mock --- tests/TestXMPP.py | 23 ++++++++++++++++------- tests/cli_mock.py | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 tests/cli_mock.py diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 994847a..a49f272 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -18,11 +18,15 @@ """ import cryptoim.xmpp as xmpp +from cli_mock import CryptoShell + from nose.tools import ok_, eq_, nottest import time def test_xmpp(): - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') + crypto_shell = CryptoShell(None) + + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) eq_(xmpp_cli.is_connected(), True) @@ -30,7 +34,7 @@ def test_xmpp(): yield check_connect, xmpp_cli # TODO fix this reuse - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) eq_(xmpp_cli.is_connected(), True) @@ -38,7 +42,7 @@ def test_xmpp(): yield check_send_message, xmpp_cli # TODO fix this reuse - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test') + xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) eq_(xmpp_cli.is_connected(), True) @@ -87,8 +91,10 @@ def test_not_connect(): Check for xmpp.XMPPClient.connect_server and disconnect_server """ + crypto_shell = CryptoShell(None) + # Wrong host - xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test') + xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test', crypto_shell) xmpp_client.connect_server(should_block=False, should_reattempt=False) waitForConnection(xmpp_client, False) @@ -98,7 +104,7 @@ def test_not_connect(): # Wrong pass - xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'wrong_pass') + xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'wrong_pass', crypto_shell) xmpp_client.connect_server(should_block=False, should_reattempt=False) waitForConnection(xmpp_client, False) @@ -107,7 +113,7 @@ def test_not_connect(): waitForConnection(xmpp_client, False) # Wrong name - xmpp_client = xmpp.XMPPClient('cryptoim0@jabber.de', 'crypto_test') + xmpp_client = xmpp.XMPPClient('cryptoim0@jabber.de', 'crypto_test', crypto_shell) xmpp_client.connect_server(should_block=False, should_reattempt=False) waitForConnection(xmpp_client, False) @@ -121,8 +127,11 @@ def check_receive_message(xmpp_client): Check for CryptoXMPP.message """ + crypto_shell = CryptoShell(None) + # Assert connected - xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2') + + xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell) xmpp_client2.connect_server(should_block=False) waitForConnection(xmpp_client, True) waitForConnection(xmpp_client2, True) diff --git a/tests/cli_mock.py b/tests/cli_mock.py new file mode 100644 index 0000000..b987253 --- /dev/null +++ b/tests/cli_mock.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this logfile except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +def CryptoShell(object): + msg_list = [] + + def print_msg(self, jid, msg): + self.msg_list.append(jid + '@' + msg) + + def print_debug(self, msg): + print(msg) From 5e0c9f002571ae91a5f3910c2285ee27a073c39d Mon Sep 17 00:00:00 2001 From: mators11 Date: Sat, 18 Jan 2014 00:00:37 +0100 Subject: [PATCH 25/95] Working on why it no working --- cryptoim/cli.py | 9 +++++---- cryptoim/test.cfg | 0 main.cfg | 1 - test.cfg | 0 4 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 cryptoim/test.cfg create mode 100644 test.cfg diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 0b05d21..555ed1d 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -37,8 +37,8 @@ class CryptoShell(cmd.Cmd): def __init__(self, configfile): # super().__init__() # Python 3 only cmd.Cmd.__init__(self) - self.config = configparser.ConfigParser() - self.config.read(configfile) + self.config = configparser.RawConfigParser() + self.configfile = self.config.read(configfile) # -- basic commands -- def do_exit(self, arg): @@ -111,8 +111,9 @@ def do_send(self, arg): def do_addfriend(self, arg): splitted = arg.split(' ') - Friends = self.config['friends'] - Friends[splitted[0]] = splitted[1] + self.config.set('friends',splitted[0],splitted[1]) + with open(self.configfile, 'wb') as cf: + self.config.write(cf) # -- tools -- diff --git a/cryptoim/test.cfg b/cryptoim/test.cfg new file mode 100644 index 0000000..e69de29 diff --git a/main.cfg b/main.cfg index acf1daa..495b565 100644 --- a/main.cfg +++ b/main.cfg @@ -10,4 +10,3 @@ Password: crypto_test2 [friends] cryptoim1: cryptoim1@jabber.de -cryptoim2: cryptoim2@jabber.de diff --git a/test.cfg b/test.cfg new file mode 100644 index 0000000..e69de29 From 608ee51bdb8ea5337a9d347e0c7ee4a32414c540 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sat, 18 Jan 2014 00:02:45 +0100 Subject: [PATCH 26/95] Removed test file and still working on why it no working --- cryptoim/test.cfg | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cryptoim/test.cfg diff --git a/cryptoim/test.cfg b/cryptoim/test.cfg deleted file mode 100644 index e69de29..0000000 From 5292f1a50225cda10e13ad37ba693c084efa31c1 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 18 Jan 2014 00:15:29 +0100 Subject: [PATCH 27/95] Fixed addfriend command --- cryptoim/cli.py | 14 ++++++++------ main.cfg | 16 +++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 555ed1d..b506697 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -32,13 +32,15 @@ class CryptoShell(cmd.Cmd): prompt = '(cryptoim) ' xmpp_client = None config = None + config_file = None - def __init__(self, configfile): + def __init__(self, config_file): # super().__init__() # Python 3 only cmd.Cmd.__init__(self) - self.config = configparser.RawConfigParser() - self.configfile = self.config.read(configfile) + self.config = configparser.ConfigParser() + self.config.read(config_file) + self.config_file = config_file # -- basic commands -- def do_exit(self, arg): @@ -111,9 +113,9 @@ def do_send(self, arg): def do_addfriend(self, arg): splitted = arg.split(' ') - self.config.set('friends',splitted[0],splitted[1]) - with open(self.configfile, 'wb') as cf: - self.config.write(cf) + self.config.set('friends', splitted[0], splitted[1]) + with open(self.config_file, 'w') as conf: + self.config.write(conf) # -- tools -- diff --git a/main.cfg b/main.cfg index 495b565..8f47e70 100644 --- a/main.cfg +++ b/main.cfg @@ -1,12 +1,14 @@ [cryptoim1] -Username: cryptoim -Host: jabber.de -Password: crypto_test +username = cryptoim +host = jabber.de +password = crypto_test [cryptoim2] -Username: cryptoim2 -Host: jabber.de -Password: crypto_test2 +username = cryptoim2 +host = jabber.de +password = crypto_test2 [friends] -cryptoim1: cryptoim1@jabber.de +cryptoim1 = cryptoim1@jabber.de +cryptoim2 = cryptoim2@jabber.de + From 421d94319a7f394c9980704b592a444a875e9d81 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 18 Jan 2014 00:15:58 +0100 Subject: [PATCH 28/95] Removed test config --- test.cfg | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test.cfg diff --git a/test.cfg b/test.cfg deleted file mode 100644 index e69de29..0000000 From b90a022c88fd3b3772a2db33b57d82f91a96e17f Mon Sep 17 00:00:00 2001 From: mators11 Date: Sat, 18 Jan 2014 00:34:54 +0100 Subject: [PATCH 29/95] Finished addfriend and added removefriend --- cryptoim/cli.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index b506697..97791ed 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -113,10 +113,25 @@ def do_send(self, arg): def do_addfriend(self, arg): splitted = arg.split(' ') + + if splitted[0] in self.config['friends']: + self.print_cmd('Already in your friend list.') + return + self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) + def do_removefriend(self,arg): + splitted = arg.split(' ') + + if splitted[0] not in self.config['friends']: + self.print_cmd('Not in your friend list.') + return + + self.config.remove_option('friends',splitted[0]) + with open(self.config_file, 'w') as conf: + self.config.write(conf) # -- tools -- From c940d39b57fa9f3dedcbfeb4b2ed708ad406de49 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sat, 18 Jan 2014 01:24:22 +0100 Subject: [PATCH 30/95] Chatmode --- cryptoim/cli.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 97791ed..283ac05 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -99,6 +99,9 @@ def do_disconnect(self, arg): self.xmpp_client.disconnect_server() + current_chat = None + chatmode = False + def do_send(self, arg): 'send toJID msg' if not self.xmpp_client or not self.xmpp_client.is_in_session(): @@ -106,10 +109,17 @@ def do_send(self, arg): return splitted = arg.split(' ') - recipient = splitted[0] - message = ' '.join(splitted[1:]) - self.xmpp_client.send_message(recipient, message) - self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) + + if self.chatmode == False: + recipient = splitted[0] + message = ' '.join(splitted[1:]) + self.xmpp_client.send_message(recipient, message) + self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) + if self.chatmode == True: + recipient = self.curent_chat + message = ' '.join(splitted) + self.xmpp_client.send_message(recipient, message) + self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) def do_addfriend(self, arg): splitted = arg.split(' ') @@ -122,7 +132,7 @@ def do_addfriend(self, arg): with open(self.config_file, 'w') as conf: self.config.write(conf) - def do_removefriend(self,arg): + def do_removefriend(self, arg): splitted = arg.split(' ') if splitted[0] not in self.config['friends']: @@ -133,6 +143,15 @@ def do_removefriend(self,arg): with open(self.config_file, 'w') as conf: self.config.write(conf) + def do_chat(self, arg): + splitted = arg.split(' ') + self.chatmode = True + self.current_chat = splitted[0] + + def do_stopchat(self): + self.chatmode = False + self.current_chat = None + # -- tools -- def print_cmd(self, string): From 39842b043381ad4140daec4105dd7b0dbcaec1f5 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 18 Jan 2014 01:37:34 +0100 Subject: [PATCH 31/95] Fixed chat, added s shortcut --- cryptoim/cli.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 283ac05..f32f169 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -33,6 +33,7 @@ class CryptoShell(cmd.Cmd): xmpp_client = None config = None config_file = None + current_chat = None def __init__(self, config_file): @@ -99,8 +100,9 @@ def do_disconnect(self, arg): self.xmpp_client.disconnect_server() - current_chat = None - chatmode = False + def do_s(self, arg): + 'send toJID msg' + return(self.do_send(arg)) def do_send(self, arg): 'send toJID msg' @@ -110,16 +112,16 @@ def do_send(self, arg): splitted = arg.split(' ') - if self.chatmode == False: + if self.current_chat != None: + recipient = self.current_chat + message = ' '.join(splitted) + + else: recipient = splitted[0] message = ' '.join(splitted[1:]) - self.xmpp_client.send_message(recipient, message) - self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) - if self.chatmode == True: - recipient = self.curent_chat - message = ' '.join(splitted) - self.xmpp_client.send_message(recipient, message) - self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) + + self.xmpp_client.send_message(recipient, message) + self.print_cmd(self.address_format(self.xmpp_client.xmpp.jid, message)) def do_addfriend(self, arg): splitted = arg.split(' ') @@ -144,12 +146,13 @@ def do_removefriend(self, arg): self.config.write(conf) def do_chat(self, arg): + """ + chat JID + """ splitted = arg.split(' ') - self.chatmode = True self.current_chat = splitted[0] def do_stopchat(self): - self.chatmode = False self.current_chat = None # -- tools -- From 7f52c0c2c693d5614f553d53ecbed0f1bf2c9fc4 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 20 Jan 2014 09:21:53 +0100 Subject: [PATCH 32/95] Fixed up chat and stopchat command.. fixed #10 --- cryptoim/cli.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index b869af3..1a91697 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -160,14 +160,20 @@ def do_chat(self, arg): """ chat JID """ - splitted = arg.split(' ') - self.current_chat = splitted[0] + if not arg: + return + else: + self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) + self.current_chat = arg.split(' ')[0] + self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - def do_stopchat(self): + def do_stopchat(self, arg): """ stopchat """ + self.prompt = '(cryptoim) ' self.current_chat = None + self.print_cmd('Closing chat window.') # -- tools -- From 9f281791b660aa21a5431aacc6da2c2a98c94a03 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 20 Jan 2014 09:38:14 +0100 Subject: [PATCH 33/95] added cli tests --- cryptoim/TestCli.py | 32 ++++++++++++++++++++++++++++++++ cryptoim/cli.py | 21 ++++++++++++++------- 2 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 cryptoim/TestCli.py diff --git a/cryptoim/TestCli.py b/cryptoim/TestCli.py new file mode 100644 index 0000000..8136987 --- /dev/null +++ b/cryptoim/TestCli.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +from cryptoim.cli import CryptoShell + +from nose.tools import ok_, eq_, nottest +import time + + +def test_connect_disconnect(): + + cshell = CryptoShell('main.cfg') + eq_(cshell.do_connect(''), False) + eq_(cshell.do_connect('cryptoim1'), True) + eq_(cshell.do_connect('cryptoim1'), False) + eq_(cshell.do_disconnect(''), True) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 1a91697..a0b75a4 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -74,11 +74,11 @@ def do_connect(self, arg): splitted = arg.split(' ') if not arg or (not len(splitted) == 1 and not len(splitted) == 2): self.print_cmd('Invalid number of arguments!') - return + return False if self.xmpp_client and self.xmpp_client.is_connected(): self.print_cmd('Already connected!') - return + return False conn_jid = None conn_pass = None @@ -99,15 +99,17 @@ def do_connect(self, arg): conn_jid += '/cryptoim' # Adds a static resource self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() + return True def do_disconnect(self, arg): 'disconnect' if not self.xmpp_client or not self.xmpp_client.is_connected(): self.print_cmd('Already disconnected!') - return + return False self.xmpp_client.disconnect_server() + return True def do_s(self, arg): 'send toJID msg' @@ -117,7 +119,7 @@ def do_send(self, arg): 'send toJID msg' if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') - return + return False splitted = arg.split(' ') @@ -131,6 +133,7 @@ def do_send(self, arg): self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) + return True def do_addfriend(self, arg): 'addfriend name jid' @@ -138,11 +141,12 @@ def do_addfriend(self, arg): if splitted[0] in self.config['friends']: self.print_cmd('Already in your friend list.') - return + return False self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) + return True def do_removefriend(self, arg): 'removefriend name' @@ -150,22 +154,24 @@ def do_removefriend(self, arg): if splitted[0] not in self.config['friends']: self.print_cmd('Not in your friend list.') - return + return False self.config.remove_option('friends', splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) + return True def do_chat(self, arg): """ chat JID """ if not arg: - return + return False else: self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' + return True def do_stopchat(self, arg): """ @@ -174,6 +180,7 @@ def do_stopchat(self, arg): self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') + return True # -- tools -- From ccdba2bb858b9a550a1ad23026cca6f83795ca1f Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Mon, 20 Jan 2014 23:31:34 +0100 Subject: [PATCH 34/95] Hopefully fixed weird test error --- cryptoim/cli.py | 1 + {cryptoim => tests}/TestCli.py | 1 + 2 files changed, 2 insertions(+) rename {cryptoim => tests}/TestCli.py (95%) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index a0b75a4..a1ed1d0 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -91,6 +91,7 @@ def do_connect(self, arg): conn_pass = self.config.get(arg, 'Password') # self.config[arg]['Password'] else: self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') + return False elif len(splitted) == 2: conn_jid = splitted[0] diff --git a/cryptoim/TestCli.py b/tests/TestCli.py similarity index 95% rename from cryptoim/TestCli.py rename to tests/TestCli.py index 8136987..1da4b6a 100644 --- a/cryptoim/TestCli.py +++ b/tests/TestCli.py @@ -30,3 +30,4 @@ def test_connect_disconnect(): eq_(cshell.do_connect('cryptoim1'), True) eq_(cshell.do_connect('cryptoim1'), False) eq_(cshell.do_disconnect(''), True) + eq_(cshell.do_disconnect(''), False) From c738d9e029dfc1027b1db3892f846d7e8dc0149d Mon Sep 17 00:00:00 2001 From: mators11 Date: Mon, 20 Jan 2014 23:40:23 +0100 Subject: [PATCH 35/95] Started sanitizing --- cryptoim/cli.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index a1ed1d0..6b532f2 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -72,7 +72,7 @@ def emptyline(self): def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') - if not arg or (not len(splitted) == 1 and not len(splitted) == 2): + if self.sanit_argCount(splitted,2) == False: self.print_cmd('Invalid number of arguments!') return False @@ -178,6 +178,11 @@ def do_stopchat(self, arg): """ stopchat """ + if not self.current_chat: + self.print_cmd('No open chat to close.') + return False + if arg is not None: + self.print_cmd('Usage: stopchat, not stopchat ') self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') @@ -212,6 +217,14 @@ def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) pass + def sanit_argCount(self, arg, number): + """ + Returns True, if number of arguments is equal or less to the length of args + """ + if len(arg) <= number: + return True + return False + # End of class def address_format(jid, msg): From 07b63117e67249079607c3bb063fde2756fb5513 Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 00:01:03 +0100 Subject: [PATCH 36/95] More sanitizing --- cryptoim/cli.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 6b532f2..285a4e0 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -72,7 +72,7 @@ def emptyline(self): def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') - if self.sanit_argCount(splitted,2) == False: + if self.sanit_argCount(splitted, 0, 2) == False: self.print_cmd('Invalid number of arguments!') return False @@ -83,7 +83,7 @@ def do_connect(self, arg): conn_jid = None conn_pass = None - if len(splitted) == 1: + if self.sanit_argCountExact(splitted, 1) == True: if splitted[0] in self.config.sections(): username = self.config.get(arg, 'Username') # self.config[arg]['Username'] host = self.config.get(arg, 'Host') # self.config[arg]['Host'] @@ -93,7 +93,7 @@ def do_connect(self, arg): self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') return False - elif len(splitted) == 2: + elif self.sanit_argCountExact(splitted, 2) == True: conn_jid = splitted[0] conn_pass = splitted[1] @@ -217,14 +217,20 @@ def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) pass - def sanit_argCount(self, arg, number): + def sanit_argCount(self, input_array, numberLo, numberHi): """ - Returns True, if number of arguments is equal or less to the length of args - """ - if len(arg) <= number: + Returns True, if length of input array is in + """ + if len(input_array) <= numberHi and len(array) >= numberLo: return True return False + def sanit_argCountExact(self, input_array, number): + """ + Returns True, if length of input_array is equal to number + """ + return self.sanit_argCount(input_array, number, number) + # End of class def address_format(jid, msg): From 07bb71a3a04fd165bf50d0a241982dd44917f774 Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 00:03:08 +0100 Subject: [PATCH 37/95] Fixed errors --- cryptoim/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 285a4e0..d78bdc8 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -221,7 +221,7 @@ def sanit_argCount(self, input_array, numberLo, numberHi): """ Returns True, if length of input array is in """ - if len(input_array) <= numberHi and len(array) >= numberLo: + if len(input_array) <= numberHi and len(input_array) >= numberLo: return True return False From f393543afcb14dfa8cb582488dad2a11b361506a Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 00:25:48 +0100 Subject: [PATCH 38/95] Refactored cli.py --- cryptoim/cli.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index d78bdc8..9fbd37d 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -72,7 +72,7 @@ def emptyline(self): def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') - if self.sanit_argCount(splitted, 0, 2) == False: + if sanit_arg_count(splitted, 0, 2) == False: self.print_cmd('Invalid number of arguments!') return False @@ -83,7 +83,7 @@ def do_connect(self, arg): conn_jid = None conn_pass = None - if self.sanit_argCountExact(splitted, 1) == True: + if sanit_arg_count_exact(splitted, 1) == True: if splitted[0] in self.config.sections(): username = self.config.get(arg, 'Username') # self.config[arg]['Username'] host = self.config.get(arg, 'Host') # self.config[arg]['Host'] @@ -93,7 +93,7 @@ def do_connect(self, arg): self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') return False - elif self.sanit_argCountExact(splitted, 2) == True: + elif sanit_arg_count_exact(splitted, 2) == True: conn_jid = splitted[0] conn_pass = splitted[1] @@ -109,7 +109,11 @@ def do_disconnect(self, arg): self.print_cmd('Already disconnected!') return False + if arg: # arg nonempty + self.print_cmd('Don\'t use any arguments!\tUsage: disconnect') + self.xmpp_client.disconnect_server() + self.print_cmd('Disconnected from server.') return True def do_s(self, arg): @@ -200,7 +204,7 @@ def print_cmd(self, string): def print_msg(self, jid, msg): """ Prints a message (jid + msg), correctly formatted using address_format - without erasing typed content. TODO implement the erasing and backup + without erasing typed content. """ backup = copy.copy(self.prompt) @@ -217,19 +221,19 @@ def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) pass - def sanit_argCount(self, input_array, numberLo, numberHi): - """ - Returns True, if length of input array is in - """ - if len(input_array) <= numberHi and len(input_array) >= numberLo: - return True - return False +def sanit_arg_count(input_array, number_lo, number_hi): + """ + Returns True, if length of input array is in + """ + if len(input_array) <= number_hi and len(input_array) >= number_lo: + return True + return False - def sanit_argCountExact(self, input_array, number): - """ - Returns True, if length of input_array is equal to number - """ - return self.sanit_argCount(input_array, number, number) +def sanit_arg_count_exact(input_array, number): + """ + Returns True, if length of input_array is equal to number + """ + return sanit_arg_count(input_array, number, number) # End of class From 158d7e89241141568afd1f8050a9064dc72f8973 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 01:04:57 +0100 Subject: [PATCH 39/95] Refactored xmpp tests --- cryptoim/xmpp.py | 6 ++--- tests/TestXMPP.py | 68 ++++++++++++++++++++++++----------------------- tests/cli_mock.py | 6 +++-- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 04a373e..e90b5ec 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -189,6 +189,6 @@ def send_message(self, recipient, msg): """ Sends a chat message to the designated recipient. """ - plaintext = msg - plaintext = encryptor.encrypt(plaintext, 'This is a secret key') - self.xmpp.send_message(mto = recipient, mbody = plaintext, mtype = 'chat') + ciphertext = encryptor.encrypt(msg, 'This is a secret key') + self.xmpp.send_message(mto = recipient, mbody = ciphertext, mtype = 'chat') + return ciphertext diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index a49f272..f1f0337 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -24,30 +24,29 @@ import time def test_xmpp(): - crypto_shell = CryptoShell(None) - - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) - xmpp_cli.connect_server(should_block=False) - - eq_(xmpp_cli.is_connected(), True) - + """ + Test for various xmpp methods: connect, send_message, receive message + """ + xmpp_cli = init_xmpp_cli() yield check_connect, xmpp_cli - # TODO fix this reuse - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) - xmpp_cli.connect_server(should_block=False) + xmpp_cli = init_xmpp_cli() + yield check_send_message, xmpp_cli - eq_(xmpp_cli.is_connected(), True) + xmpp_cli = init_xmpp_cli() + yield check_receive_message, xmpp_cli - yield check_send_message, xmpp_cli +def init_xmpp_cli(): + """ + Initializes the xmpp_client and connects it + """ + crypto_shell = CryptoShell() - # TODO fix this reuse xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) eq_(xmpp_cli.is_connected(), True) - - yield check_receive_message, xmpp_cli + return xmpp_cli def check_connect(xmpp_client): """ @@ -91,29 +90,25 @@ def test_not_connect(): Check for xmpp.XMPPClient.connect_server and disconnect_server """ - crypto_shell = CryptoShell(None) + crypto_shell = CryptoShell() # Wrong host xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test', crypto_shell) - xmpp_client.connect_server(should_block=False, should_reattempt=False) - - waitForConnection(xmpp_client, False) - - xmpp_client.disconnect_server() - waitForConnection(xmpp_client, False) + assertDisconnect(xmpp_client) # Wrong pass xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'wrong_pass', crypto_shell) - xmpp_client.connect_server(should_block=False, should_reattempt=False) - - waitForConnection(xmpp_client, False) - - xmpp_client.disconnect_server() - waitForConnection(xmpp_client, False) + assertDisconnect(xmpp_client) # Wrong name xmpp_client = xmpp.XMPPClient('cryptoim0@jabber.de', 'crypto_test', crypto_shell) + assertDisconnect(xmpp_client) + +def assertDisconnect(xmpp_client): + """ + Conencts, disconnects and asserts it happened + """ xmpp_client.connect_server(should_block=False, should_reattempt=False) waitForConnection(xmpp_client, False) @@ -121,13 +116,12 @@ def test_not_connect(): xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) - def check_receive_message(xmpp_client): """ Check for CryptoXMPP.message """ - crypto_shell = CryptoShell(None) + crypto_shell = CryptoShell() # Assert connected @@ -140,9 +134,8 @@ def check_receive_message(xmpp_client): time.sleep(0.1) # Send and receive message - xmpp_client.send_message(xmpp_client2.xmpp.jid, 'Hello, CryptoIM check_receive_message!') - - # TODO Assert that xmpp_client2 got it + plaintext = 'Hello, CryptoIM check_receive_message!' + ciphertext = xmpp_client.send_message(xmpp_client2.xmpp.jid, plaintext) # Disconnect xmpp_client.disconnect_server(); @@ -151,7 +144,16 @@ def check_receive_message(xmpp_client): waitForConnection(xmpp_client2, False) waitForConnection(xmpp_client, False) + # Assert that xmpp_client2 got it (it is bound to be received after disconnect if it waits) + ok_(0 != len(crypto_shell.msg_list)) + eq_(len(crypto_shell.jid_list), len(crypto_shell.msg_list)) + eq_(plaintext, crypto_shell.msg_list[-1]) + eq_(xmpp_client.xmpp.jid, crypto_shell.jid_list[-1]) + def waitForConnection(xmpp_client, should_be_connected): + """ + Waits until a connection is estabilished + """ while not xmpp_client.is_connected() == should_be_connected: time.sleep(0.1) eq_(xmpp_client.is_connected(), should_be_connected) diff --git a/tests/cli_mock.py b/tests/cli_mock.py index b987253..334a8cf 100644 --- a/tests/cli_mock.py +++ b/tests/cli_mock.py @@ -17,11 +17,13 @@ limitations under the License. """ -def CryptoShell(object): +class CryptoShell(object): + jid_list = [] msg_list = [] def print_msg(self, jid, msg): - self.msg_list.append(jid + '@' + msg) + self.jid_list.append(jid) + self.msg_list.append(msg) def print_debug(self, msg): print(msg) From c7bd2e30bdc863909e380bb46070886bdd4ede1a Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 09:18:46 +0100 Subject: [PATCH 40/95] Removed mock from tests, added quick and dirty logging to cli --- cryptoim/cli.py | 10 ++++++++++ tests/TestXMPP.py | 8 ++++---- tests/cli_mock.py | 29 ----------------------------- 3 files changed, 14 insertions(+), 33 deletions(-) delete mode 100644 tests/cli_mock.py diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 9fbd37d..ebaaf17 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -38,6 +38,8 @@ class CryptoShell(cmd.Cmd): config = None config_file = None current_chat = None + msg_list = None + jid_list = None def __init__(self, config_file): @@ -51,6 +53,10 @@ def __init__(self, config_file): self.config.read(config_file) self.config_file = config_file + # Logging + self.msg_list = [] + self.jid_list = [] + # -- basic commands -- def do_exit(self, arg): 'Quit CryptoIM' @@ -214,6 +220,10 @@ def print_msg(self, jid, msg): self.stdout.write(backup) self.stdout.flush() + # Log: + self.msg_list.append(msg) + self.jid_list.append(jid) + def print_debug(self, msg): """ Prints debug messages diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index f1f0337..4dfbf45 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -18,7 +18,7 @@ """ import cryptoim.xmpp as xmpp -from cli_mock import CryptoShell +from cryptoim.cli import CryptoShell from nose.tools import ok_, eq_, nottest import time @@ -40,7 +40,7 @@ def init_xmpp_cli(): """ Initializes the xmpp_client and connects it """ - crypto_shell = CryptoShell() + crypto_shell = CryptoShell('main.cfg') xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) @@ -90,7 +90,7 @@ def test_not_connect(): Check for xmpp.XMPPClient.connect_server and disconnect_server """ - crypto_shell = CryptoShell() + crypto_shell = CryptoShell('main.cfg') # Wrong host xmpp_client = xmpp.XMPPClient('cryptoim@jabber2.de', 'crypto_test', crypto_shell) @@ -121,7 +121,7 @@ def check_receive_message(xmpp_client): Check for CryptoXMPP.message """ - crypto_shell = CryptoShell() + crypto_shell = CryptoShell('main.cfg') # Assert connected diff --git a/tests/cli_mock.py b/tests/cli_mock.py deleted file mode 100644 index 334a8cf..0000000 --- a/tests/cli_mock.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -""" - Copyright 2014 CryptoIM Development Team - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this logfile except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -class CryptoShell(object): - jid_list = [] - msg_list = [] - - def print_msg(self, jid, msg): - self.jid_list.append(jid) - self.msg_list.append(msg) - - def print_debug(self, msg): - print(msg) From 67461b6120b0257e7421c89545c90ab9cf4dacef Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 10:27:02 +0100 Subject: [PATCH 41/95] mators11: added is_jid, config_find, fixed UX printing --- cryptoim/cli.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index ebaaf17..0c2d909 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -116,7 +116,7 @@ def do_disconnect(self, arg): return False if arg: # arg nonempty - self.print_cmd('Don\'t use any arguments!\tUsage: disconnect') + self.print_cmd('Usage: disconnect, not disconnect ') self.xmpp_client.disconnect_server() self.print_cmd('Disconnected from server.') @@ -150,7 +150,7 @@ def do_addfriend(self, arg): 'addfriend name jid' splitted = arg.split(' ') - if splitted[0] in self.config['friends']: + if self.config_find(splitted[0]): self.print_cmd('Already in your friend list.') return False @@ -231,6 +231,15 @@ def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) pass + def config_find(self, username): + """ + Finds a username in friends in config, returns the jid, or None if not found + """ + if self.config: + if username in self.config['friends']: + return self.config['friends'][username] + return None + def sanit_arg_count(input_array, number_lo, number_hi): """ Returns True, if length of input array is in @@ -245,6 +254,16 @@ def sanit_arg_count_exact(input_array, number): """ return sanit_arg_count(input_array, number, number) +def sanit_is_jid(string): + """ + returns true if the string is a JID + """ + if '@' in string: + return True + return False + + + # End of class def address_format(jid, msg): From 7b10a30ce4f388c57f079eec9cc050bb29969927 Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 20:34:28 +0100 Subject: [PATCH 42/95] Added addconnection and remove connection, added some sanitizing --- cryptoim/cli.py | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 0c2d909..40f426d 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -108,6 +108,36 @@ def do_connect(self, arg): self.xmpp_client.connect_server() return True + def do_addconnection(self, arg): + #Usage addconnection + splitted = arg.split(' ') + + if not self.sanit_arg_count_exact(splitted, 3): + self.print_cmd('Usage: addconnection ') + return False + if not self.sanit_is_jid(splitted[1]): + self.print_cmd('JID has form of username@host.') + self.print_cmd('Usage: addconnection ') + + + self.config.add_section(splitted[0]) + self.config.set(splitted[0], 'username', splitted[0]) + self.config.set(splitted[0], 'host', (splitted[1].split('@') [1]) ) + self.config.set(splitted[0], 'password', splitted[2]) + + with open(self.config_file, 'w') as conf: + self.config.write(conf) + return True + + def do_removeconnection(self, arg): + #Usage removeconnection + splitted = arg.split(' ') + + self.config.remove_section(splitted[0]) + + with open(self.config_file, 'w') as conf: + self.config.write(conf) + return True def do_disconnect(self, arg): 'disconnect' @@ -240,6 +270,9 @@ def config_find(self, username): return self.config['friends'][username] return None +# End of class + + def sanit_arg_count(input_array, number_lo, number_hi): """ Returns True, if length of input array is in @@ -254,17 +287,23 @@ def sanit_arg_count_exact(input_array, number): """ return sanit_arg_count(input_array, number, number) -def sanit_is_jid(string): +def sanit_is_jid (self, string): """ returns true if the string is a JID """ - if '@' in string: - return True - return False + if '@' not in string: + return False + + splitted = string.split('@') + for string_part in splitted: + string_part = stringpart.strip('.').strip('/') + if string_part().isalnum() == True: + return True + return False + -# End of class def address_format(jid, msg): """ From dfe12ae45dd22175987daf56ec4cfc315136e9be Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 20:44:24 +0100 Subject: [PATCH 43/95] Finished addconnection and removedconnection --- cryptoim/cli.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 40f426d..14f7c04 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -112,14 +112,17 @@ def do_addconnection(self, arg): #Usage addconnection splitted = arg.split(' ') + if self.config_find(splitted[0]): + self.print_cmd(splitted[0] + ' is already in your connection list') + return False if not self.sanit_arg_count_exact(splitted, 3): self.print_cmd('Usage: addconnection ') return False if not self.sanit_is_jid(splitted[1]): self.print_cmd('JID has form of username@host.') self.print_cmd('Usage: addconnection ') + return False - self.config.add_section(splitted[0]) self.config.set(splitted[0], 'username', splitted[0]) self.config.set(splitted[0], 'host', (splitted[1].split('@') [1]) ) @@ -132,6 +135,17 @@ def do_addconnection(self, arg): def do_removeconnection(self, arg): #Usage removeconnection splitted = arg.split(' ') + + if not self.config_find(splitted[0]): + self.print_cmd(splitted[0] + ' is not in your connection list') + return False + if not self.sanit_arg_count_exact(splitted, 1): + self.print_cmd('Usage: removeconnection ') + return False + if self.sanit_is_jid(splitted[0]): + self.print_cmd('Usage: removeconnection ') + return False + self.config.remove_section(splitted[0]) From 95241194940ced71b3deeea6b975c69860e60eb1 Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 21:42:37 +0100 Subject: [PATCH 44/95] Finished sanitizing --- cryptoim/cli.py | 66 +++++++++++++++++++++++++------------- cryptoim/encryptor_core.py | 2 +- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 14f7c04..edcdddd 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -78,10 +78,10 @@ def emptyline(self): def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') + if sanit_arg_count(splitted, 0, 2) == False: self.print_cmd('Invalid number of arguments!') return False - if self.xmpp_client and self.xmpp_client.is_connected(): self.print_cmd('Already connected!') return False @@ -108,6 +108,24 @@ def do_connect(self, arg): self.xmpp_client.connect_server() return True + + def do_disconnect(self, arg): + """ + disconnect + """ + + if not self.xmpp_client or not self.xmpp_client.is_connected(): + self.print_cmd('Already disconnected!') + return False + + if arg: # arg nonempty + self.print_cmd('Usage: disconnect, not disconnect ') + + self.xmpp_client.disconnect_server() + self.print_cmd('Disconnected from server.') + return True + + def do_addconnection(self, arg): #Usage addconnection splitted = arg.split(' ') @@ -139,13 +157,9 @@ def do_removeconnection(self, arg): if not self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') return False - if not self.sanit_arg_count_exact(splitted, 1): + if not self.sanit_arg_count_exact(splitted, 1) or self.sanit_is_jid(splitted[0]): self.print_cmd('Usage: removeconnection ') return False - if self.sanit_is_jid(splitted[0]): - self.print_cmd('Usage: removeconnection ') - return False - self.config.remove_section(splitted[0]) @@ -153,18 +167,7 @@ def do_removeconnection(self, arg): self.config.write(conf) return True - def do_disconnect(self, arg): - 'disconnect' - if not self.xmpp_client or not self.xmpp_client.is_connected(): - self.print_cmd('Already disconnected!') - return False - - if arg: # arg nonempty - self.print_cmd('Usage: disconnect, not disconnect ') - - self.xmpp_client.disconnect_server() - self.print_cmd('Disconnected from server.') - return True + def do_s(self, arg): 'send toJID msg' @@ -178,13 +181,18 @@ def do_send(self, arg): splitted = arg.split(' ') + if self.current_chat != None: recipient = self.current_chat message = ' '.join(splitted) + elif splitted[0] in self.config['friends']: + recipient = self.config_find(splitted[0]) + message = ' '.join(splitted[1:]) + else: recipient = splitted[0] - message = ' '.join(splitted[1:]) + message = ' '.join(splitted[1:]) self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) @@ -221,12 +229,25 @@ def do_chat(self, arg): chat JID """ if not arg: + self.print_cmd('Usage: chat or chat ') return False - else: + + if self.sanit_is_jid(arg): self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return True + return True + + if not self.sanit_is_jid(arg) and self.config_find(arg): + arg = self.config_find(arg) + self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) + self.current_chat = arg.split(' ')[0] + self.prompt = '(' + self.current_chat.split('@')[0] + ') ' + return True + + if not self.sanit_is_jid(arg) and not self.config_find(arg): + self.print_cmd('Unknown JID or username, please check JID or try addfriend ') + return False def do_stopchat(self, arg): """ @@ -237,6 +258,7 @@ def do_stopchat(self, arg): return False if arg is not None: self.print_cmd('Usage: stopchat, not stopchat ') + self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') @@ -317,8 +339,6 @@ def sanit_is_jid (self, string): - - def address_format(jid, msg): """ Formats a jid and message to correctly display in the log diff --git a/cryptoim/encryptor_core.py b/cryptoim/encryptor_core.py index bfc5266..f9be28a 100644 --- a/cryptoim/encryptor_core.py +++ b/cryptoim/encryptor_core.py @@ -23,7 +23,7 @@ def encrypt(plaintext, key): """ plaintext = string - key = string (256 bytes) + key = string (256 bits) """ messages = __split_message(plaintext) From a4663071ea4930f6878ee92b23518d9771094cae Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 22:24:02 +0100 Subject: [PATCH 45/95] Refactored message logging, added some decryptor/encryptor tests, fixed whitespace, fixed xmpp tests (fixed #6) --- cryptoim/cli.py | 23 ++++++++------------- cryptoim/xmpp.py | 9 ++++++++ tests/TestDecryptorCore.py | 42 +++++++++++++++++++++++++++++++++++--- tests/TestXMPP.py | 21 +++++++++++-------- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 14f7c04..e8330fb 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -35,11 +35,7 @@ class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' xmpp_client = None - config = None - config_file = None current_chat = None - msg_list = None - jid_list = None def __init__(self, config_file): @@ -54,8 +50,10 @@ def __init__(self, config_file): self.config_file = config_file # Logging - self.msg_list = [] - self.jid_list = [] + self.received_msg_list = [] + self.received_jid_list = [] + self.sent_msg_list = [] + self.sent_jid_list = [] # -- basic commands -- def do_exit(self, arg): @@ -111,7 +109,7 @@ def do_connect(self, arg): def do_addconnection(self, arg): #Usage addconnection splitted = arg.split(' ') - + if self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is already in your connection list') return False @@ -127,7 +125,7 @@ def do_addconnection(self, arg): self.config.set(splitted[0], 'username', splitted[0]) self.config.set(splitted[0], 'host', (splitted[1].split('@') [1]) ) self.config.set(splitted[0], 'password', splitted[2]) - + with open(self.config_file, 'w') as conf: self.config.write(conf) return True @@ -135,7 +133,7 @@ def do_addconnection(self, arg): def do_removeconnection(self, arg): #Usage removeconnection splitted = arg.split(' ') - + if not self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') return False @@ -148,7 +146,7 @@ def do_removeconnection(self, arg): self.config.remove_section(splitted[0]) - + with open(self.config_file, 'w') as conf: self.config.write(conf) return True @@ -188,6 +186,7 @@ def do_send(self, arg): self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) + return True def do_addfriend(self, arg): @@ -264,10 +263,6 @@ def print_msg(self, jid, msg): self.stdout.write(backup) self.stdout.flush() - # Log: - self.msg_list.append(msg) - self.jid_list.append(jid) - def print_debug(self, msg): """ Prints debug messages diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index e90b5ec..3d64d52 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -117,6 +117,10 @@ def message(self, msg): decrypted_message = decryptor.decrypt(ciphertext, 'This is a secret key') self.parent.print_msg(msg['from'].bare, decrypted_message) + # Log: + self.parent.received_jid_list.append(msg['from'].bare) + self.parent.received_msg_list.append(decrypted_message) + #if msg['type'] in ('chat', 'normal'): #msg.reply('Thanks for sending\n%(body)s' % msg).send() #print('DEBUG: MSG: %(body)s' % msg) @@ -191,4 +195,9 @@ def send_message(self, recipient, msg): """ ciphertext = encryptor.encrypt(msg, 'This is a secret key') self.xmpp.send_message(mto = recipient, mbody = ciphertext, mtype = 'chat') + + # Log: + self.xmpp.parent.sent_jid_list.append(recipient) + self.xmpp.parent.sent_msg_list.append(msg) + return ciphertext diff --git a/tests/TestDecryptorCore.py b/tests/TestDecryptorCore.py index fc4defc..646008e 100644 --- a/tests/TestDecryptorCore.py +++ b/tests/TestDecryptorCore.py @@ -20,6 +20,44 @@ import cryptoim.decryptor_core as decryptor_core import cryptoim.encryptor_core as encryptor_core from nose.tools import ok_, eq_ +import random, string + + +def random_message_range(lo, hi): + length = random.randint(lo, hi) + return ''.join(random.choice(string.printable) for _ in range(length)) + +def random_message(limit): + return random_message_range(1, limit) + +def test_random_encrypt_decrypt(): + test_count = 10 + limit = 100 + + for _ in range(test_count): + originaltext = random_message(limit) + key = random_message(limit) + ciphertext = encryptor_core.encrypt(originaltext, key) + check_decrypt(originaltext, ciphertext, key) + +def check_decrypt(originaltext, ciphertext, key): + decryptedtext = decryptor_core.decrypt(ciphertext, key) + eq_(originaltext, decryptedtext) + +def test_random_key(): + length = 100 + originaltext = 'Secret message!' + key = random_message_range(length, length) + ciphertext = encryptor_core.encrypt(originaltext, key) + check_decrypt(originaltext, ciphertext, key) + +def test_long_string(): + length = 1000 + originaltext = random_message_range(length, length) + key = 'This is a secret key!' + ciphertext = encryptor_core.encrypt(originaltext, key) + check_decrypt(originaltext, ciphertext, key) + def test_decrypt(): """ @@ -40,14 +78,12 @@ def rand_str(limit): rand += choice(ascii_letters) return rand - message = "This is a test message" + message = 'This is a test message' key = rand_str(32) ctext = encrypt(message, key) ptext = decrypt(ctext, key) eq_(message, ptext) - #TODO ok_(len(decrypt(message, key)) != 0, "Length wasn't supposed to be 0") - def test_ciphertext_fission(): """ Test for decryptor_core.__ciphertext_fission diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 4dfbf45..bfa41d5 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -76,14 +76,19 @@ def check_send_message(xmpp_client): while not xmpp_client.is_in_session(): time.sleep(0.1) - - # TODO Works, but check - xmpp_client.send_message('cryptoim2@jabber.de', 'Hello, CryptoIM check_send_message!') + msg = 'Hello, CryptoIM check_send_message!' + recipient = 'cryptoim2@jabber.de' + xmpp_client.send_message(recipient, msg) xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) - + # Assert that xmpp_client sent the message (it is bound to be sent after disconnect if it waits) + crypto_shell = xmpp_client.xmpp.parent + ok_(0 != len(crypto_shell.sent_msg_list)) + eq_(len(crypto_shell.sent_jid_list), len(crypto_shell.sent_msg_list)) + eq_(msg, crypto_shell.sent_msg_list[-1]) + eq_(recipient, crypto_shell.sent_jid_list[-1]) def test_not_connect(): """ @@ -145,10 +150,10 @@ def check_receive_message(xmpp_client): waitForConnection(xmpp_client, False) # Assert that xmpp_client2 got it (it is bound to be received after disconnect if it waits) - ok_(0 != len(crypto_shell.msg_list)) - eq_(len(crypto_shell.jid_list), len(crypto_shell.msg_list)) - eq_(plaintext, crypto_shell.msg_list[-1]) - eq_(xmpp_client.xmpp.jid, crypto_shell.jid_list[-1]) + ok_(0 != len(crypto_shell.received_msg_list)) + eq_(len(crypto_shell.received_jid_list), len(crypto_shell.received_msg_list)) + eq_(plaintext, crypto_shell.received_msg_list[-1]) + eq_(xmpp_client.xmpp.jid, crypto_shell.received_jid_list[-1]) def waitForConnection(xmpp_client, should_be_connected): """ From 66fb8189688b6fb290e55ee4c64e76aeb5629dda Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 22:28:33 +0100 Subject: [PATCH 46/95] Refactored cli --- cryptoim/cli.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index e8330fb..1bfb5bc 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -107,17 +107,19 @@ def do_connect(self, arg): return True def do_addconnection(self, arg): - #Usage addconnection + """ + Usage: addconnection + """ splitted = arg.split(' ') if self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is already in your connection list') return False - if not self.sanit_arg_count_exact(splitted, 3): + if not sanit_arg_count_exact(splitted, 3): self.print_cmd('Usage: addconnection ') return False - if not self.sanit_is_jid(splitted[1]): - self.print_cmd('JID has form of username@host.') + if not sanit_is_jid(splitted[1]): + self.print_cmd('JID has form of username@host.') self.print_cmd('Usage: addconnection ') return False @@ -131,16 +133,18 @@ def do_addconnection(self, arg): return True def do_removeconnection(self, arg): - #Usage removeconnection + """ + Usage removeconnection + """ splitted = arg.split(' ') if not self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') return False - if not self.sanit_arg_count_exact(splitted, 1): + if not sanit_arg_count_exact(splitted, 1): self.print_cmd('Usage: removeconnection ') return False - if self.sanit_is_jid(splitted[0]): + if sanit_is_jid(splitted[0]): self.print_cmd('Usage: removeconnection ') return False @@ -296,7 +300,7 @@ def sanit_arg_count_exact(input_array, number): """ return sanit_arg_count(input_array, number, number) -def sanit_is_jid (self, string): +def sanit_is_jid (string): """ returns true if the string is a JID """ @@ -305,15 +309,11 @@ def sanit_is_jid (self, string): splitted = string.split('@') for string_part in splitted: - string_part = stringpart.strip('.').strip('/') + string_part = string_part.strip('.').strip('/') if string_part().isalnum() == True: return True return False - - - - def address_format(jid, msg): """ Formats a jid and message to correctly display in the log From 6a2acfd1bdb342d5cdf2f8ea0afa1e149082a865 Mon Sep 17 00:00:00 2001 From: mators11 Date: Tue, 21 Jan 2014 22:37:51 +0100 Subject: [PATCH 47/95] Not working cli test --- cryptoim/cli.py | 22 ++++++++++++++++++---- main.cfg | 1 - tests/TestCli.py | 11 ++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index edcdddd..fe363c1 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -170,30 +170,44 @@ def do_removeconnection(self, arg): def do_s(self, arg): - 'send toJID msg' + 'send toJID or username msg' return(self.do_send(arg)) def do_send(self, arg): - 'send toJID msg' + 'send toJID or username msg' if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') return False splitted = arg.split(' ') + if self.current_chat == None and splitted[0] not in self.config['friends'] or not self.sanit_is_jid(splitted[0]): + #input: send blablabla message (username not defined, jid isnt jid, chatmode off) + self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') + self.print_cmd('Usage: send or send ') + return False + + if self.current_chat == None and self.sanit_arg_count_exact(splitted, 0): + #input: send (empty argument, chatmode off) + self.print_cmd('Usage: send or send ') + return False if self.current_chat != None: recipient = self.current_chat message = ' '.join(splitted) - elif splitted[0] in self.config['friends']: - recipient = self.config_find(splitted[0]) + if self.current_chat == None and splitted[0] in self.config['friends']: + recipient = self.config['friends'][splitted[0]] message = ' '.join(splitted[1:]) else: recipient = splitted[0] message = ' '.join(splitted[1:]) + if len(message) == 0: + self.print_cmd('Please enter your message.') + return False + self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) return True diff --git a/main.cfg b/main.cfg index 8f47e70..beb69ad 100644 --- a/main.cfg +++ b/main.cfg @@ -11,4 +11,3 @@ password = crypto_test2 [friends] cryptoim1 = cryptoim1@jabber.de cryptoim2 = cryptoim2@jabber.de - diff --git a/tests/TestCli.py b/tests/TestCli.py index 1da4b6a..ae7e299 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -22,12 +22,21 @@ from nose.tools import ok_, eq_, nottest import time +cshell = CryptoShell('main.cfg') def test_connect_disconnect(): - cshell = CryptoShell('main.cfg') eq_(cshell.do_connect(''), False) eq_(cshell.do_connect('cryptoim1'), True) eq_(cshell.do_connect('cryptoim1'), False) eq_(cshell.do_disconnect(''), True) eq_(cshell.do_disconnect(''), False) + +def test_send(): + + cshell.do_connect('cryptoim2') + eq_(cshell.do_send(''), False) + eq_(cshell.do_send('shouldntwork message'), False) + eq_(cshell.do_send('cryptoim1 message'), True) + eq_(cshell.do_send('cryptoim1'), False) + cshell.do_disconnect('') From fb03a024022dcdb64fc1a9f6828b4bcbb5ed96cb Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Tue, 21 Jan 2014 23:37:56 +0100 Subject: [PATCH 48/95] Fixed up cli logic, fixed cli tests, refactored --- cryptoim/cli.py | 62 +++++++++++++++++++++++------------------------ tests/TestCli.py | 11 +++++---- tests/TestXMPP.py | 18 +++++++++----- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 26ed281..d3af44c 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -160,7 +160,7 @@ def do_removeconnection(self, arg): self.print_cmd(splitted[0] + ' is not in your connection list') return False - if not self.sanit_arg_count_exact(splitted, 1) or self.sanit_is_jid(splitted[0]): + if not sanit_arg_count_exact(splitted, 1) or sanit_is_jid(splitted[0]): self.print_cmd('Usage: removeconnection ') return False @@ -182,32 +182,32 @@ def do_send(self, arg): splitted = arg.split(' ') - if self.current_chat == None and splitted[0] not in self.config['friends'] or not self.sanit_is_jid(splitted[0]): - #input: send blablabla message (username not defined, jid isnt jid, chatmode off) - self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') - self.print_cmd('Usage: send or send ') - return False - - if self.current_chat == None and self.sanit_arg_count_exact(splitted, 0): - #input: send (empty argument, chatmode off) - self.print_cmd('Usage: send or send ') - return False - - if self.current_chat != None: + if self.current_chat: # if chat mode + if len(arg)==0: + self.print_cmd('Please enter your message.') + return False recipient = self.current_chat message = ' '.join(splitted) - if self.current_chat == None and splitted[0] in self.config['friends']: - recipient = self.config['friends'][splitted[0]] - message = ' '.join(splitted[1:]) + else: # if chat mode off + if sanit_arg_count_exact(splitted, 0): + #input: send (empty argument) + self.print_cmd('Usage: send or send ') + return False - else: - recipient = splitted[0] - message = ' '.join(splitted[1:]) + if self.config_find(splitted[0]): # if sending to friend + recipient = self.config_find(splitted[0]) + elif sanit_is_jid(splitted[0]): # if sending to jid + recipient = splitted[0] + else: # error: username not defined or jid isnt jid + self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') + self.print_cmd('Usage: send or send ') + return False - if len(message) == 0: - self.print_cmd('Please enter your message.') - return False + message = ' '.join(splitted[1:]) + if len(message) == 0: + self.print_cmd('Please enter your message.') + return False self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) @@ -231,7 +231,7 @@ def do_removefriend(self, arg): 'removefriend name' splitted = arg.split(' ') - if splitted[0] not in self.config['friends']: + if self.config_find(splitted[0]): self.print_cmd('Not in your friend list.') return False @@ -248,20 +248,20 @@ def do_chat(self, arg): self.print_cmd('Usage: chat or chat ') return False - if self.sanit_is_jid(arg): + if sanit_is_jid(arg): self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' return True - if not self.sanit_is_jid(arg) and self.config_find(arg): + if not sanit_is_jid(arg) and self.config_find(arg): arg = self.config_find(arg) self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' return True - if not self.sanit_is_jid(arg) and not self.config_find(arg): + if not sanit_is_jid(arg) and not self.config_find(arg): self.print_cmd('Unknown JID or username, please check JID or try addfriend ') return False @@ -309,14 +309,14 @@ def print_debug(self, msg): #self.print_cmd('DEBUG: ' + msg) pass - def config_find(self, username): + def config_find(self, param, section='friends'): """ - Finds a username in friends in config, returns the jid, or None if not found + Finds a parameter in section in config, returns the value, or None if not found """ if self.config: - if username in self.config['friends']: - return self.config['friends'][username] - return None + if self.config.has_option(section, param): + return self.config.get(section, param) + return None # End of class diff --git a/tests/TestCli.py b/tests/TestCli.py index ae7e299..1cb3761 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -18,14 +18,13 @@ """ from cryptoim.cli import CryptoShell +import TestXMPP -from nose.tools import ok_, eq_, nottest -import time - -cshell = CryptoShell('main.cfg') +from nose.tools import ok_, eq_ def test_connect_disconnect(): + cshell = CryptoShell('main.cfg') eq_(cshell.do_connect(''), False) eq_(cshell.do_connect('cryptoim1'), True) eq_(cshell.do_connect('cryptoim1'), False) @@ -34,7 +33,9 @@ def test_connect_disconnect(): def test_send(): - cshell.do_connect('cryptoim2') + cshell = CryptoShell('main.cfg') + eq_(cshell.do_connect('cryptoim2'), True) + TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send(''), False) eq_(cshell.do_send('shouldntwork message'), False) eq_(cshell.do_send('cryptoim1 message'), True) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index bfa41d5..999f547 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -73,9 +73,7 @@ def check_send_message(xmpp_client): """ waitForConnection(xmpp_client, True) - - while not xmpp_client.is_in_session(): - time.sleep(0.1) + waitForSession(xmpp_client, True) msg = 'Hello, CryptoIM check_send_message!' recipient = 'cryptoim2@jabber.de' xmpp_client.send_message(recipient, msg) @@ -132,11 +130,11 @@ def check_receive_message(xmpp_client): xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell) xmpp_client2.connect_server(should_block=False) + waitForConnection(xmpp_client, True) waitForConnection(xmpp_client2, True) - - while not (xmpp_client.is_in_session() and xmpp_client2.is_in_session()): - time.sleep(0.1) + waitForSession(xmpp_client, True) + waitForSession(xmpp_client2, True) # Send and receive message plaintext = 'Hello, CryptoIM check_receive_message!' @@ -163,3 +161,11 @@ def waitForConnection(xmpp_client, should_be_connected): time.sleep(0.1) eq_(xmpp_client.is_connected(), should_be_connected) +def waitForSession(xmpp_client, should_be_in_session): + """ + Waits until a session is estabilished + """ + while not xmpp_client.is_in_session() == should_be_in_session: + time.sleep(0.1) + eq_(xmpp_client.is_in_session(), should_be_in_session) + From 6da480f49f9af3716455d9da4106b269dad39bf4 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Wed, 22 Jan 2014 00:01:49 +0100 Subject: [PATCH 49/95] Broke all cli tests, because returning values from do_ methods in cli breaks cmdloop() --- cryptoim/cli.py | 61 ++++++++++++++++++++++++------------------------ tests/TestCli.py | 35 +++++++++++++++++++-------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index d3af44c..1362652 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -79,10 +79,10 @@ def do_connect(self, arg): if sanit_arg_count(splitted, 0, 2) == False: self.print_cmd('Invalid number of arguments!') - return False + return #False if self.xmpp_client and self.xmpp_client.is_connected(): self.print_cmd('Already connected!') - return False + return #False conn_jid = None conn_pass = None @@ -95,7 +95,7 @@ def do_connect(self, arg): conn_pass = self.config.get(arg, 'Password') # self.config[arg]['Password'] else: self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') - return False + return #False elif sanit_arg_count_exact(splitted, 2) == True: conn_jid = splitted[0] @@ -104,7 +104,7 @@ def do_connect(self, arg): conn_jid += '/cryptoim' # Adds a static resource self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() - return True + return #True def do_disconnect(self, arg): @@ -114,14 +114,14 @@ def do_disconnect(self, arg): if not self.xmpp_client or not self.xmpp_client.is_connected(): self.print_cmd('Already disconnected!') - return False + return #False if arg: # arg nonempty self.print_cmd('Usage: disconnect, not disconnect ') self.xmpp_client.disconnect_server() self.print_cmd('Disconnected from server.') - return True + return #True def do_addconnection(self, arg): @@ -132,14 +132,14 @@ def do_addconnection(self, arg): if self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is already in your connection list') - return False + return #False if not sanit_arg_count_exact(splitted, 3): self.print_cmd('Usage: addconnection ') - return False + return #False if not sanit_is_jid(splitted[1]): self.print_cmd('JID has form of username@host.') self.print_cmd('Usage: addconnection ') - return False + return #False self.config.add_section(splitted[0]) self.config.set(splitted[0], 'username', splitted[0]) @@ -148,7 +148,7 @@ def do_addconnection(self, arg): with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + #return True def do_removeconnection(self, arg): """ @@ -158,34 +158,35 @@ def do_removeconnection(self, arg): if not self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') - return False + return #False if not sanit_arg_count_exact(splitted, 1) or sanit_is_jid(splitted[0]): self.print_cmd('Usage: removeconnection ') - return False + return #False self.config.remove_section(splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return #True def do_s(self, arg): 'send toJID or username msg' - return(self.do_send(arg)) + self.do_send(arg) + def do_send(self, arg): 'send toJID or username msg' if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') - return False + return #False splitted = arg.split(' ') if self.current_chat: # if chat mode if len(arg)==0: self.print_cmd('Please enter your message.') - return False + return #False recipient = self.current_chat message = ' '.join(splitted) @@ -193,7 +194,7 @@ def do_send(self, arg): if sanit_arg_count_exact(splitted, 0): #input: send (empty argument) self.print_cmd('Usage: send or send ') - return False + return #False if self.config_find(splitted[0]): # if sending to friend recipient = self.config_find(splitted[0]) @@ -202,17 +203,17 @@ def do_send(self, arg): else: # error: username not defined or jid isnt jid self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') self.print_cmd('Usage: send or send ') - return False + return #False message = ' '.join(splitted[1:]) if len(message) == 0: self.print_cmd('Please enter your message.') - return False + return #False self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) - return True + return #True def do_addfriend(self, arg): 'addfriend name jid' @@ -220,12 +221,12 @@ def do_addfriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Already in your friend list.') - return False + return #False self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return #True def do_removefriend(self, arg): 'removefriend name' @@ -233,12 +234,12 @@ def do_removefriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Not in your friend list.') - return False + return #False self.config.remove_option('friends', splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return #True def do_chat(self, arg): """ @@ -246,24 +247,24 @@ def do_chat(self, arg): """ if not arg: self.print_cmd('Usage: chat or chat ') - return False + return #False if sanit_is_jid(arg): self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return True + return #True if not sanit_is_jid(arg) and self.config_find(arg): arg = self.config_find(arg) self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return True + return #True if not sanit_is_jid(arg) and not self.config_find(arg): self.print_cmd('Unknown JID or username, please check JID or try addfriend ') - return False + return #False def do_stopchat(self, arg): """ @@ -271,14 +272,14 @@ def do_stopchat(self, arg): """ if not self.current_chat: self.print_cmd('No open chat to close.') - return False + return #False if arg is not None: self.print_cmd('Usage: stopchat, not stopchat ') self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') - return True + return #True # -- tools -- diff --git a/tests/TestCli.py b/tests/TestCli.py index 1cb3761..c9d5815 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -22,22 +22,37 @@ from nose.tools import ok_, eq_ +# TODO redo cli tests without returns + def test_connect_disconnect(): cshell = CryptoShell('main.cfg') - eq_(cshell.do_connect(''), False) - eq_(cshell.do_connect('cryptoim1'), True) - eq_(cshell.do_connect('cryptoim1'), False) - eq_(cshell.do_disconnect(''), True) - eq_(cshell.do_disconnect(''), False) + + cshell.do_connect('') + #eq_(False, cshell.xmpp_client.is_connected()) + + cshell.do_connect('cryptoim1') + eq_(True, cshell.xmpp_client.is_connected()) + + cshell.do_connect('cryptoim1') + eq_(True, cshell.xmpp_client.is_connected()) + + cshell.do_disconnect('') + eq_(False, cshell.xmpp_client.is_connected()) + + cshell.do_disconnect('') + eq_(False, cshell.xmpp_client.is_connected()) def test_send(): cshell = CryptoShell('main.cfg') - eq_(cshell.do_connect('cryptoim2'), True) + cshell.do_connect('cryptoim2') + eq_(True, cshell.xmpp_client.is_connected()) TestXMPP.waitForSession(cshell.xmpp_client, True) - eq_(cshell.do_send(''), False) - eq_(cshell.do_send('shouldntwork message'), False) - eq_(cshell.do_send('cryptoim1 message'), True) - eq_(cshell.do_send('cryptoim1'), False) + eq_(True, cshell.xmpp_client.is_in_session()) + #eq_(cshell.do_send(''), False) + #eq_(cshell.do_send('shouldntwork message'), False) + #eq_(cshell.do_send('cryptoim1 message'), True) + #eq_(cshell.do_send('cryptoim1'), False) cshell.do_disconnect('') + eq_(False, cshell.xmpp_client.is_connected()) From 8d88f901dbf5ccfcafec7bd11d85a51ac33027c2 Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 22 Jan 2014 18:08:54 +0100 Subject: [PATCH 50/95] Fixed tests for cli and closed issue --- cryptoim/cli.py | 71 +++++++++++++++++++++++++------------------ tests/TestCli.py | 2 ++ tests/test_config.cfg | 0 3 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 tests/test_config.cfg diff --git a/cryptoim/cli.py b/cryptoim/cli.py index d3af44c..49e90db 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -36,6 +36,7 @@ class CryptoShell(cmd.Cmd): prompt = '(cryptoim) ' xmpp_client = None current_chat = None + test_mode = False def __init__(self, config_file): @@ -79,10 +80,11 @@ def do_connect(self, arg): if sanit_arg_count(splitted, 0, 2) == False: self.print_cmd('Invalid number of arguments!') - return False + return self.return_cli(False) + if self.xmpp_client and self.xmpp_client.is_connected(): self.print_cmd('Already connected!') - return False + return self.return_cli(False) conn_jid = None conn_pass = None @@ -95,7 +97,7 @@ def do_connect(self, arg): conn_pass = self.config.get(arg, 'Password') # self.config[arg]['Password'] else: self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') - return False + return self.return_cli(False) elif sanit_arg_count_exact(splitted, 2) == True: conn_jid = splitted[0] @@ -104,7 +106,7 @@ def do_connect(self, arg): conn_jid += '/cryptoim' # Adds a static resource self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() - return True + return self.return_cli(True) def do_disconnect(self, arg): @@ -114,14 +116,14 @@ def do_disconnect(self, arg): if not self.xmpp_client or not self.xmpp_client.is_connected(): self.print_cmd('Already disconnected!') - return False + return self.return_cli(False) if arg: # arg nonempty self.print_cmd('Usage: disconnect, not disconnect ') self.xmpp_client.disconnect_server() self.print_cmd('Disconnected from server.') - return True + return self.return_cli(True) def do_addconnection(self, arg): @@ -132,14 +134,14 @@ def do_addconnection(self, arg): if self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is already in your connection list') - return False + return self.return_cli(False) if not sanit_arg_count_exact(splitted, 3): self.print_cmd('Usage: addconnection ') - return False + return self.return_cli(False) if not sanit_is_jid(splitted[1]): self.print_cmd('JID has form of username@host.') self.print_cmd('Usage: addconnection ') - return False + return self.return_cli(False) self.config.add_section(splitted[0]) self.config.set(splitted[0], 'username', splitted[0]) @@ -148,7 +150,7 @@ def do_addconnection(self, arg): with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return self.return_cli(True) def do_removeconnection(self, arg): """ @@ -158,17 +160,17 @@ def do_removeconnection(self, arg): if not self.config_find(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') - return False + return self.return_cli(False) if not sanit_arg_count_exact(splitted, 1) or sanit_is_jid(splitted[0]): self.print_cmd('Usage: removeconnection ') - return False + return self.return_cli(False) self.config.remove_section(splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return self.return_cli(True) def do_s(self, arg): 'send toJID or username msg' @@ -178,14 +180,14 @@ def do_send(self, arg): 'send toJID or username msg' if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') - return False + return self.return_cli(False) splitted = arg.split(' ') if self.current_chat: # if chat mode if len(arg)==0: self.print_cmd('Please enter your message.') - return False + return self.return_cli(False) recipient = self.current_chat message = ' '.join(splitted) @@ -193,7 +195,7 @@ def do_send(self, arg): if sanit_arg_count_exact(splitted, 0): #input: send (empty argument) self.print_cmd('Usage: send or send ') - return False + return self.return_cli(False) if self.config_find(splitted[0]): # if sending to friend recipient = self.config_find(splitted[0]) @@ -202,17 +204,17 @@ def do_send(self, arg): else: # error: username not defined or jid isnt jid self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') self.print_cmd('Usage: send or send ') - return False + return self.return_cli(False) message = ' '.join(splitted[1:]) if len(message) == 0: self.print_cmd('Please enter your message.') - return False + return self.return_cli(False) self.xmpp_client.send_message(recipient, message) self.print_cmd(address_format(self.xmpp_client.xmpp.jid, message)) - return True + return self.return_cli(True) def do_addfriend(self, arg): 'addfriend name jid' @@ -220,12 +222,12 @@ def do_addfriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Already in your friend list.') - return False + return self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return def do_removefriend(self, arg): 'removefriend name' @@ -233,12 +235,12 @@ def do_removefriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Not in your friend list.') - return False + return self.config.remove_option('friends', splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return True + return def do_chat(self, arg): """ @@ -246,24 +248,24 @@ def do_chat(self, arg): """ if not arg: self.print_cmd('Usage: chat or chat ') - return False + return if sanit_is_jid(arg): self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return True + return if not sanit_is_jid(arg) and self.config_find(arg): arg = self.config_find(arg) self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return True + return if not sanit_is_jid(arg) and not self.config_find(arg): self.print_cmd('Unknown JID or username, please check JID or try addfriend ') - return False + return def do_stopchat(self, arg): """ @@ -271,14 +273,14 @@ def do_stopchat(self, arg): """ if not self.current_chat: self.print_cmd('No open chat to close.') - return False + return if arg is not None: self.print_cmd('Usage: stopchat, not stopchat ') self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') - return True + return # -- tools -- @@ -318,6 +320,12 @@ def config_find(self, param, section='friends'): return self.config.get(section, param) return None + def return_cli(self, value): + if self.test_mode: + return value + else: + return + # End of class @@ -354,3 +362,8 @@ def address_format(jid, msg): Formats a jid and message to correctly display in the log """ return(jid + ': ' + msg) + +def test_cli(parameter): + if parameter == 'true': + return True + return False diff --git a/tests/TestCli.py b/tests/TestCli.py index 1cb3761..52ac3e5 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -25,6 +25,7 @@ def test_connect_disconnect(): cshell = CryptoShell('main.cfg') + cshell.test_mode = True eq_(cshell.do_connect(''), False) eq_(cshell.do_connect('cryptoim1'), True) eq_(cshell.do_connect('cryptoim1'), False) @@ -34,6 +35,7 @@ def test_connect_disconnect(): def test_send(): cshell = CryptoShell('main.cfg') + cshell.test_mode = True eq_(cshell.do_connect('cryptoim2'), True) TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send(''), False) diff --git a/tests/test_config.cfg b/tests/test_config.cfg new file mode 100644 index 0000000..e69de29 From 6777b2b749f827ed9754b6acc75b102ecac85971 Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 22 Jan 2014 20:06:50 +0100 Subject: [PATCH 51/95] Added test for do_chat --- cryptoim/cli.py | 10 +++++----- tests/TestCli.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 49e90db..2f44d8b 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -248,24 +248,24 @@ def do_chat(self, arg): """ if not arg: self.print_cmd('Usage: chat or chat ') - return + return self.return_cli(False) if sanit_is_jid(arg): self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return + return self.return_cli(True) if not sanit_is_jid(arg) and self.config_find(arg): arg = self.config_find(arg) self.print_cmd('Opening chat window with: ' + arg.split(' ')[0]) self.current_chat = arg.split(' ')[0] self.prompt = '(' + self.current_chat.split('@')[0] + ') ' - return + return self.return_cli(True) if not sanit_is_jid(arg) and not self.config_find(arg): self.print_cmd('Unknown JID or username, please check JID or try addfriend ') - return + return self.return_cli(False) def do_stopchat(self, arg): """ @@ -353,7 +353,7 @@ def sanit_is_jid (string): splitted = string.split('@') for string_part in splitted: string_part = string_part.strip('.').strip('/') - if string_part().isalnum() == True: + if string_part.isalnum() == True: return True return False diff --git a/tests/TestCli.py b/tests/TestCli.py index 52ac3e5..320a88e 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -43,3 +43,19 @@ def test_send(): eq_(cshell.do_send('cryptoim1 message'), True) eq_(cshell.do_send('cryptoim1'), False) cshell.do_disconnect('') + +def test_chat(): + + cshell = CryptoShell('main.cfg') + cshell.test_mode = True + eq_(cshell.do_chat(''), False) + eq_(cshell.do_chat('cryptoim1@jabber.de'), True) + eq_(cshell.do_chat('cryptoim1'), True) + eq_(cshell.do_chat('shouldntwork'), False) + eq_(cshell.do_connect('cryptoim2'), True) + TestXMPP.waitForSession(cshell.xmpp_client, True) + eq_(cshell.do_send('Test message'), True) + eq_(cshell.do_s('Test message for short version'), True) + cshell.do_disconnect('') + + From 9910044751b11cd597d16a92561f5449037580ca Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 22 Jan 2014 20:13:35 +0100 Subject: [PATCH 52/95] Added stopchat tests --- cryptoim/cli.py | 4 ++-- tests/TestCli.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 2f44d8b..c400936 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -273,14 +273,14 @@ def do_stopchat(self, arg): """ if not self.current_chat: self.print_cmd('No open chat to close.') - return + return self.return_cli(False) if arg is not None: self.print_cmd('Usage: stopchat, not stopchat ') self.prompt = '(cryptoim) ' self.current_chat = None self.print_cmd('Closing chat window.') - return + return self.return_cli(True) # -- tools -- diff --git a/tests/TestCli.py b/tests/TestCli.py index 320a88e..1c357cc 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -44,7 +44,7 @@ def test_send(): eq_(cshell.do_send('cryptoim1'), False) cshell.do_disconnect('') -def test_chat(): +def test_chat_stopchat(): cshell = CryptoShell('main.cfg') cshell.test_mode = True @@ -56,6 +56,10 @@ def test_chat(): TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send('Test message'), True) eq_(cshell.do_s('Test message for short version'), True) + eq_(cshell.do_stopchat(''), True) + eq_(cshell.do_stopchat(''), False) + eq_(cshell.do_send('Test message after stopchat'), False) + eq_(cshell.do_s('Alsto testing the short version'), False) cshell.do_disconnect('') From 672e479b6ca6ed744fadfe447234181ba752a5c8 Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 22 Jan 2014 21:00:39 +0100 Subject: [PATCH 53/95] Added 'not' working test for exit --- tests/TestCli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index 1c357cc..bed2349 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -44,7 +44,7 @@ def test_send(): eq_(cshell.do_send('cryptoim1'), False) cshell.do_disconnect('') -def test_chat_stopchat(): +def test_chat_stopchat_exit(): cshell = CryptoShell('main.cfg') cshell.test_mode = True @@ -61,5 +61,6 @@ def test_chat_stopchat(): eq_(cshell.do_send('Test message after stopchat'), False) eq_(cshell.do_s('Alsto testing the short version'), False) cshell.do_disconnect('') + #cshell.do_exit('') From e6ccabbd90dded92edd3ccf491f4a33e795b6181 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Wed, 22 Jan 2014 21:35:40 +0100 Subject: [PATCH 54/95] Fixed exit test --- cryptoim/cli.py | 25 ++++++++++++------------- tests/TestCli.py | 11 ++++++++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index c400936..0645b3f 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -62,7 +62,7 @@ def do_exit(self, arg): self.do_disconnect(arg) self.print_cmd('Thank you for using CryptoIM!') - quit() + sys.exit(0) def do_q(self, arg): 'Alias for quit' @@ -141,7 +141,7 @@ def do_addconnection(self, arg): if not sanit_is_jid(splitted[1]): self.print_cmd('JID has form of username@host.') self.print_cmd('Usage: addconnection ') - return self.return_cli(False) + return self.return_cli(False) self.config.add_section(splitted[0]) self.config.set(splitted[0], 'username', splitted[0]) @@ -170,7 +170,7 @@ def do_removeconnection(self, arg): with open(self.config_file, 'w') as conf: self.config.write(conf) - return self.return_cli(True) + return self.return_cli(True) def do_s(self, arg): 'send toJID or username msg' @@ -222,12 +222,12 @@ def do_addfriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Already in your friend list.') - return + return self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return + return def do_removefriend(self, arg): 'removefriend name' @@ -235,12 +235,12 @@ def do_removefriend(self, arg): if self.config_find(splitted[0]): self.print_cmd('Not in your friend list.') - return + return self.config.remove_option('friends', splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return + return def do_chat(self, arg): """ @@ -321,10 +321,14 @@ def config_find(self, param, section='friends'): return None def return_cli(self, value): + """ + If in test mode, return value from param + """ + if self.test_mode: return value else: - return + return # End of class @@ -362,8 +366,3 @@ def address_format(jid, msg): Formats a jid and message to correctly display in the log """ return(jid + ': ' + msg) - -def test_cli(parameter): - if parameter == 'true': - return True - return False diff --git a/tests/TestCli.py b/tests/TestCli.py index bed2349..79521ce 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -61,6 +61,11 @@ def test_chat_stopchat_exit(): eq_(cshell.do_send('Test message after stopchat'), False) eq_(cshell.do_s('Alsto testing the short version'), False) cshell.do_disconnect('') - #cshell.do_exit('') - - + + exit_code = -1 + try: + cshell.do_exit('') + except SystemExit: + exit_code = 0 + eq_(0, exit_code) + From e22479bce67200090f2a270ac9ab9e7481561f2f Mon Sep 17 00:00:00 2001 From: mators11 Date: Wed, 22 Jan 2014 23:53:39 +0100 Subject: [PATCH 55/95] added tests for addfriend and removefriend --- cryptoim/cli.py | 18 +++++++++++++----- main.cfg | 1 + tests/TestCli.py | 15 +++++++++++++++ tests/test_config.cfg | 7 +++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 0645b3f..76e94b7 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -220,27 +220,35 @@ def do_addfriend(self, arg): 'addfriend name jid' splitted = arg.split(' ') + if not sanit_arg_count_exact(splitted, 2): + self.print_cmd('Usage: addfriend ') + return self.return_cli(False) + if self.config_find(splitted[0]): self.print_cmd('Already in your friend list.') - return + return self.return_cli(False) self.config.set('friends', splitted[0], splitted[1]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return + return self.return_cli(True) def do_removefriend(self, arg): 'removefriend name' splitted = arg.split(' ') - if self.config_find(splitted[0]): + if not sanit_arg_count_exact(splitted, 1): + self.print_cmd('Usage: removefriend ') + return self.return_cli(False) + + if not self.config_find(splitted[0]): self.print_cmd('Not in your friend list.') - return + return self.return_cli(False) self.config.remove_option('friends', splitted[0]) with open(self.config_file, 'w') as conf: self.config.write(conf) - return + return self.return_cli(True) def do_chat(self, arg): """ diff --git a/main.cfg b/main.cfg index beb69ad..8f47e70 100644 --- a/main.cfg +++ b/main.cfg @@ -11,3 +11,4 @@ password = crypto_test2 [friends] cryptoim1 = cryptoim1@jabber.de cryptoim2 = cryptoim2@jabber.de + diff --git a/tests/TestCli.py b/tests/TestCli.py index 79521ce..62d2bae 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -69,3 +69,18 @@ def test_chat_stopchat_exit(): exit_code = 0 eq_(0, exit_code) + +def test_addfriend_removefriend(): + + cshell = CryptoShell('tests/test_config.cfg') + cshell.test_mode = True + + eq_(cshell.do_addfriend('testfriend testfriend@jabber.de'), True) + eq_(cshell.do_addfriend('testfriend testfriend@jabber.de'), False) + eq_(cshell.do_addfriend(''), False) + eq_(cshell.do_removefriend('testfriend'), True) + eq_(cshell.do_removefriend(''), False) + eq_(cshell.do_removefriend('testfriend'), False) + + + diff --git a/tests/test_config.cfg b/tests/test_config.cfg index e69de29..f1940c7 100644 --- a/tests/test_config.cfg +++ b/tests/test_config.cfg @@ -0,0 +1,7 @@ +[testuser1] +username = test +host = jabber.de +password = crypto_test + +[friends] + From dc67ba2b9829a01a6a239f1d4ac675cfba7c99dd Mon Sep 17 00:00:00 2001 From: mators11 Date: Thu, 23 Jan 2014 00:28:46 +0100 Subject: [PATCH 56/95] Added friendlist and tests for addconnection and removeconnection --- cryptoim/cli.py | 12 ++++++++++-- tests/TestCli.py | 15 +++++++++++++++ tests/test_config.cfg | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 76e94b7..e66978c 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -132,7 +132,7 @@ def do_addconnection(self, arg): """ splitted = arg.split(' ') - if self.config_find(splitted[0]): + if self.config.has_section(splitted[0]): self.print_cmd(splitted[0] + ' is already in your connection list') return self.return_cli(False) if not sanit_arg_count_exact(splitted, 3): @@ -158,7 +158,7 @@ def do_removeconnection(self, arg): """ splitted = arg.split(' ') - if not self.config_find(splitted[0]): + if not self.config.has_section(splitted[0]): self.print_cmd(splitted[0] + ' is not in your connection list') return self.return_cli(False) @@ -275,6 +275,14 @@ def do_chat(self, arg): self.print_cmd('Unknown JID or username, please check JID or try addfriend ') return self.return_cli(False) + def do_friendlist(self, arg): + """ + Displays all friends in main.cfg ['friends'] section + """ + for friend in self.config['friends']: + self.print_cmd(friend) + + def do_stopchat(self, arg): """ stopchat diff --git a/tests/TestCli.py b/tests/TestCli.py index 62d2bae..40c0c3f 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -82,5 +82,20 @@ def test_addfriend_removefriend(): eq_(cshell.do_removefriend(''), False) eq_(cshell.do_removefriend('testfriend'), False) +def test_addconnection_removeconnection(): + + cshell = CryptoShell('tests/test_config.cfg') + cshell.test_mode = True + + eq_(cshell.do_addconnection('testuser2 testuser2@jabber.de testpass'), True) + eq_(cshell.do_addconnection('testuser2 testuser2@jabber.de testpass'), False) + eq_(cshell.do_addconnection('testuser2'), False) + eq_(cshell.do_addconnection('testuser2 thisisnotajid testpass'), False) + eq_(cshell.do_removeconnection('testuser3'), False) + eq_(cshell.do_removeconnection('testuser2 testuser3@jabber.de'), False) + eq_(cshell.do_removeconnection('testuser2@jabber.de'), False) + eq_(cshell.do_removeconnection('testuser2'), True) + + diff --git a/tests/test_config.cfg b/tests/test_config.cfg index f1940c7..e7d52c0 100644 --- a/tests/test_config.cfg +++ b/tests/test_config.cfg @@ -1,5 +1,5 @@ [testuser1] -username = test +username = testuser1 host = jabber.de password = crypto_test From 89f362efbe750a144fdadd9dee8ec8efac3262d6 Mon Sep 17 00:00:00 2001 From: mators11 Date: Thu, 23 Jan 2014 00:51:43 +0100 Subject: [PATCH 57/95] Coverage enhancer --- tests/TestCli.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index 40c0c3f..f9e265c 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -31,11 +31,15 @@ def test_connect_disconnect(): eq_(cshell.do_connect('cryptoim1'), False) eq_(cshell.do_disconnect(''), True) eq_(cshell.do_disconnect(''), False) + eq_(cshell.do_connect('cryptoim1@jabber.de crypto_test'), True) + eq_(cshell.do_disconnect(''), True) + eq_(cshell.do_disconnect(''), False) def test_send(): cshell = CryptoShell('main.cfg') cshell.test_mode = True + eq_(cshell.do_send('message before connection'), False) eq_(cshell.do_connect('cryptoim2'), True) TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send(''), False) @@ -64,7 +68,7 @@ def test_chat_stopchat_exit(): exit_code = -1 try: - cshell.do_exit('') + cshell.do_q('') except SystemExit: exit_code = 0 eq_(0, exit_code) @@ -79,6 +83,7 @@ def test_addfriend_removefriend(): eq_(cshell.do_addfriend('testfriend testfriend@jabber.de'), False) eq_(cshell.do_addfriend(''), False) eq_(cshell.do_removefriend('testfriend'), True) + eq_(cshell.do_removefriend('testfriend another few lines'), False) eq_(cshell.do_removefriend(''), False) eq_(cshell.do_removefriend('testfriend'), False) From 3c75017a583229c9c10cda7d04ddecb8a96ed4ea Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 01:06:56 +0100 Subject: [PATCH 58/95] Fixed some random bugs and added some missing test cases to cli --- cryptoim/cli.py | 14 +++++++------- tests/TestCli.py | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index e66978c..8d2b678 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -78,7 +78,7 @@ def do_connect(self, arg): 'connect JID PASSWORD or connect CONNECTION_NAME' splitted = arg.split(' ') - if sanit_arg_count(splitted, 0, 2) == False: + if not sanit_arg_count(splitted, 0, 2): self.print_cmd('Invalid number of arguments!') return self.return_cli(False) @@ -89,7 +89,7 @@ def do_connect(self, arg): conn_jid = None conn_pass = None - if sanit_arg_count_exact(splitted, 1) == True: + if sanit_arg_count_exact(splitted, 1): if splitted[0] in self.config.sections(): username = self.config.get(arg, 'Username') # self.config[arg]['Username'] host = self.config.get(arg, 'Host') # self.config[arg]['Host'] @@ -99,7 +99,7 @@ def do_connect(self, arg): self.print_cmd('Connection ' + splitted[0] + ' doesn\'t exist') return self.return_cli(False) - elif sanit_arg_count_exact(splitted, 2) == True: + elif sanit_arg_count_exact(splitted, 2): conn_jid = splitted[0] conn_pass = splitted[1] @@ -237,7 +237,7 @@ def do_removefriend(self, arg): 'removefriend name' splitted = arg.split(' ') - if not sanit_arg_count_exact(splitted, 1): + if not arg: self.print_cmd('Usage: removefriend ') return self.return_cli(False) @@ -279,9 +279,9 @@ def do_friendlist(self, arg): """ Displays all friends in main.cfg ['friends'] section """ - for friend in self.config['friends']: - self.print_cmd(friend) - + for friend in self.config.items('friends'): + self.print_cmd(' - '.join(friend)) + def do_stopchat(self, arg): """ diff --git a/tests/TestCli.py b/tests/TestCli.py index 40c0c3f..3ea5bc6 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -27,20 +27,39 @@ def test_connect_disconnect(): cshell = CryptoShell('main.cfg') cshell.test_mode = True eq_(cshell.do_connect(''), False) + eq_(cshell.do_connect('invalid number of arguments'), False) eq_(cshell.do_connect('cryptoim1'), True) eq_(cshell.do_connect('cryptoim1'), False) - eq_(cshell.do_disconnect(''), True) + eq_(cshell.do_disconnect('random_string'), True) # branch coverage eq_(cshell.do_disconnect(''), False) + exit_code = -1 + try: + cshell.do_q('') + except SystemExit: + exit_code = 0 + eq_(0, exit_code) + + +def test_connect_disconnect_jid(): + + cshell = CryptoShell('main.cfg') + cshell.test_mode = True + eq_(cshell.do_connect('cryptoim@jabber.de crypto_test'), True) + eq_(cshell.do_disconnect(''), True) + def test_send(): cshell = CryptoShell('main.cfg') cshell.test_mode = True + eq_(cshell.do_send('cryptoim1 message'), False) eq_(cshell.do_connect('cryptoim2'), True) TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send(''), False) + eq_(cshell.onecmd(''), None) # just empty line command - emptyline() test eq_(cshell.do_send('shouldntwork message'), False) eq_(cshell.do_send('cryptoim1 message'), True) + eq_(cshell.do_send('cryptoim2@jabber.de message'), True) eq_(cshell.do_send('cryptoim1'), False) cshell.do_disconnect('') @@ -56,6 +75,7 @@ def test_chat_stopchat_exit(): TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send('Test message'), True) eq_(cshell.do_s('Test message for short version'), True) + eq_(cshell.do_send(''), False) eq_(cshell.do_stopchat(''), True) eq_(cshell.do_stopchat(''), False) eq_(cshell.do_send('Test message after stopchat'), False) @@ -83,7 +103,7 @@ def test_addfriend_removefriend(): eq_(cshell.do_removefriend('testfriend'), False) def test_addconnection_removeconnection(): - + cshell = CryptoShell('tests/test_config.cfg') cshell.test_mode = True @@ -96,6 +116,25 @@ def test_addconnection_removeconnection(): eq_(cshell.do_removeconnection('testuser2@jabber.de'), False) eq_(cshell.do_removeconnection('testuser2'), True) +def test_friendlist(): + cshell = CryptoShell('main.cfg') + cshell.test_mode = True + eq_(cshell.do_friendlist(''), None) + eq_(cshell.do_friendlist('whatever string'), None) +def test_return_cli(): + cshell = CryptoShell('tests/test_config.cfg') + cshell.test_mode = True + eq_(cshell.return_cli(False), False) + eq_(cshell.return_cli(True), True) + eq_(cshell.return_cli('test'), 'test') + eq_(cshell.return_cli(123), 123) + cshell.test_mode = False + eq_(cshell.return_cli(False), None) + eq_(cshell.return_cli(True), None) + eq_(cshell.return_cli('test'), None) + eq_(cshell.return_cli(123), None) + +# TODO test tools From 9c925ff0077d73490bc8d1d9adec212c6691474c Mon Sep 17 00:00:00 2001 From: mators11 Date: Thu, 23 Jan 2014 09:14:25 +0100 Subject: [PATCH 59/95] fixed addconnection tests --- tests/TestCli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index a9001cc..fd4b368 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -112,7 +112,8 @@ def test_addconnection_removeconnection(): eq_(cshell.do_addconnection('testuser2 testuser2@jabber.de testpass'), True) eq_(cshell.do_addconnection('testuser2 testuser2@jabber.de testpass'), False) eq_(cshell.do_addconnection('testuser2'), False) - eq_(cshell.do_addconnection('testuser2 thisisnotajid testpass'), False) + eq_(cshell.do_addconnection('testuser3'), False) + eq_(cshell.do_addconnection('testuser3 thisisnotajid testpass'), False) eq_(cshell.do_removeconnection('testuser3'), False) eq_(cshell.do_removeconnection('testuser2 testuser3@jabber.de'), False) eq_(cshell.do_removeconnection('testuser2@jabber.de'), False) From 6139c7d91eb4e883337c13281cd6ff881457d672 Mon Sep 17 00:00:00 2001 From: mators11 Date: Thu, 23 Jan 2014 09:16:32 +0100 Subject: [PATCH 60/95] fixed random bugs --- cryptoim/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 8d2b678..7123067 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -192,7 +192,7 @@ def do_send(self, arg): message = ' '.join(splitted) else: # if chat mode off - if sanit_arg_count_exact(splitted, 0): + if not sanit_arg_count(splitted, 1, 2): #input: send (empty argument) self.print_cmd('Usage: send or send ') return self.return_cli(False) From a7f3ee9a5aa71d6e7d5f69006cef5fb7d4674b26 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 15:57:10 +0100 Subject: [PATCH 61/95] Fixed some pre-release stuff and config file handling --- cryptoim/cli.py | 7 +++++++ setup.py | 1 + 2 files changed, 8 insertions(+) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 8d2b678..5e4a60f 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -48,6 +48,13 @@ def __init__(self, config_file): cmd.Cmd.__init__(self) self.config = configparser.ConfigParser() self.config.read(config_file) + + import os + if not os.path.exists(config_file): + self.config.add_section('friends') + with open(config_file, 'w') as c_file: + self.config.write(c_file) + self.config_file = config_file # Logging diff --git a/setup.py b/setup.py index bb08a93..bcdcf2a 100755 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ author = "CryptoIM Development Team", author_email = "skopekondrej@gmail.com", packages = find_packages(exclude=["tests"]), + scripts = ['main.py'], url = "http://pypi.python.org/pypi/CryptoIM/", license = "Apache License 2.0", description = "Crypto Instant Messenger", From 8bfe97f9fe8c006d3cd0a3d4459d46f7dde47130 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 21:05:23 +0100 Subject: [PATCH 62/95] Fixed #15 --- README | 22 ++++++++++++++++++---- README.rst | 22 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/README b/README index da919ce..ac9e2ac 100644 --- a/README +++ b/README @@ -34,13 +34,27 @@ CryptoIM uses `semantic versioning `_ and branching model si Building ======== -* **Build**: ``python setup.py build`` and ``sudo python setup.py install`` +1. **Build**: ``python setup.py build`` and ``sudo python setup.py install`` -* To **run**: ``python main.py`` +2. To **run**: ``python main.py`` -* To run **unit tests**: ``python setup.py nosetests`` +3. To run **unit tests**: ``python setup.py nosetests`` -* To **clean**, run: ``python setup.py clean --all`` +4. To **clean**, run: ``python setup.py clean --all`` + +Building on Linux +================= + +* Make sure to **install** these packages using your package manager: ``python`` and ``python-setuptools`` + +* Follow steps 1. and 2. from **Building** + +Building on Windows +=================== + +* **Install** `Python `_ and `Setuptools `_. + +* Follow steps 1. and 2. from **Building** Contributing ============ diff --git a/README.rst b/README.rst index da919ce..ac9e2ac 100644 --- a/README.rst +++ b/README.rst @@ -34,13 +34,27 @@ CryptoIM uses `semantic versioning `_ and branching model si Building ======== -* **Build**: ``python setup.py build`` and ``sudo python setup.py install`` +1. **Build**: ``python setup.py build`` and ``sudo python setup.py install`` -* To **run**: ``python main.py`` +2. To **run**: ``python main.py`` -* To run **unit tests**: ``python setup.py nosetests`` +3. To run **unit tests**: ``python setup.py nosetests`` -* To **clean**, run: ``python setup.py clean --all`` +4. To **clean**, run: ``python setup.py clean --all`` + +Building on Linux +================= + +* Make sure to **install** these packages using your package manager: ``python`` and ``python-setuptools`` + +* Follow steps 1. and 2. from **Building** + +Building on Windows +=================== + +* **Install** `Python `_ and `Setuptools `_. + +* Follow steps 1. and 2. from **Building** Contributing ============ From 0198e955df1011c3d92a4b625066431efbf0f93b Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 21:24:26 +0100 Subject: [PATCH 63/95] Added create config test --- tests/TestCli.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/TestCli.py b/tests/TestCli.py index fd4b368..c8a88fa 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -140,4 +140,11 @@ def test_return_cli(): eq_(cshell.return_cli('test'), None) eq_(cshell.return_cli(123), None) +def test_create_config(): + config_file = 'tests/test_config_nonexistant.cfg' + cshell = CryptoShell(config_file) + import os + os.remove(config_file) + + # TODO test tools From 70dee2b59f9e0e2e577601133aaed295931ba241 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 22:50:12 +0100 Subject: [PATCH 64/95] Added sanit_is_jid test and fixed the method --- cryptoim/cli.py | 30 +++++++++++++++++++++--------- tests/TestCli.py | 21 ++++++++++++++++++++- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index f0ab551..0156ac2 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -331,8 +331,8 @@ def print_debug(self, msg): """ Prints debug messages """ - #self.print_cmd('DEBUG: ' + msg) - pass + if self.test_mode: + self.print_cmd('DEBUG: ' + msg) def config_find(self, param, section='friends'): """ @@ -370,19 +370,31 @@ def sanit_arg_count_exact(input_array, number): """ return sanit_arg_count(input_array, number, number) -def sanit_is_jid (string): +def sanit_is_jid(string): """ - returns true if the string is a JID + Returns true if the string is a JID """ - if '@' not in string: + if string.count('@') != 1 or string.count('/') > 1: return False splitted = string.split('@') - for string_part in splitted: - string_part = string_part.strip('.').strip('/') - if string_part.isalnum() == True: - return True + username = splitted[0] + + host = splitted[1] + if host.count('.') > 1: return False + host = host.replace('.', '') + + if '/' in host: + host_resource = host.split('/') + host = host_resource[0] + resource = host_resource[1] + + # Test resource: + if not resource.isalnum(): + return False + + return username.isalnum() and host.isalnum() def address_format(jid, msg): """ diff --git a/tests/TestCli.py b/tests/TestCli.py index c8a88fa..cb6cd76 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -18,6 +18,7 @@ """ from cryptoim.cli import CryptoShell +import cryptoim.cli as cli import TestXMPP from nose.tools import ok_, eq_ @@ -147,4 +148,22 @@ def test_create_config(): os.remove(config_file) -# TODO test tools +# Test tools + +def test_sanit_is_jid(): + is_jid = cli.sanit_is_jid + eq_(True, is_jid('test@jabber.de')) + eq_(True, is_jid('test@jabber.de/resourceHere123')) + eq_(True, is_jid('test@localhost')) + eq_(True, is_jid('tes1234tBigSmall@jabber.DE')) + + eq_(False, is_jid('testjabber.de')) + eq_(False, is_jid('test/jabber@de')) + eq_(False, is_jid('test&jabber.de')) + eq_(False, is_jid('test@jabber&de')) + eq_(False, is_jid('te@st@jabber.de')) + eq_(False, is_jid('test@jabber..de')) + eq_(False, is_jid('te.st@jabber.de')) + eq_(False, is_jid('te&st@jabber.de')) + eq_(False, is_jid('test@jabber.de/resourceHere.123')) + eq_(False, is_jid('test@jabber.de/resource&&Here123')) From fbc278049aba429fe329d2f867b5c4fdb178daaf Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Thu, 23 Jan 2014 22:55:24 +0100 Subject: [PATCH 65/95] Fixed some pylint warnings --- cryptoim/cli.py | 9 ++++----- cryptoim/encryptor_core.py | 2 -- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 0156ac2..ae45ab9 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -34,11 +34,8 @@ class CryptoShell(cmd.Cmd): intro = 'Welcome to CryptoIM! Type help or ? to list commands.\n' prompt = '(cryptoim) ' - xmpp_client = None - current_chat = None test_mode = False - def __init__(self, config_file): """ CryptoShell init @@ -53,10 +50,13 @@ def __init__(self, config_file): if not os.path.exists(config_file): self.config.add_section('friends') with open(config_file, 'w') as c_file: - self.config.write(c_file) + self.config.write(c_file) self.config_file = config_file + self.xmpp_client = None + self.current_chat = None + # Logging self.received_msg_list = [] self.received_jid_list = [] @@ -355,7 +355,6 @@ def return_cli(self, value): # End of class - def sanit_arg_count(input_array, number_lo, number_hi): """ Returns True, if length of input array is in diff --git a/cryptoim/encryptor_core.py b/cryptoim/encryptor_core.py index f9be28a..008804f 100644 --- a/cryptoim/encryptor_core.py +++ b/cryptoim/encryptor_core.py @@ -80,7 +80,6 @@ def __split_message(plaintext): messages.append(matrix) return messages - # TODO: Check if this works as expected def __sub_bytes(message): """ @@ -91,7 +90,6 @@ def __sub_bytes(message): hexadecimal = __convert_char_hex(message[i][j]) message[i][j] = const.SBOX[int(hexadecimal[0], 16)][int(hexadecimal[1], 16)] return message - # TODO: Check if returns in decimal or hexadecimal def __shift_rows(message): """ From 405b7c2840704882aa5b19279fd9537552d7da1d Mon Sep 17 00:00:00 2001 From: mators11 Date: Fri, 24 Jan 2014 19:21:32 +0100 Subject: [PATCH 66/95] Added key exchange methods --- cryptoim/key_exchange.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 cryptoim/key_exchange.py diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py new file mode 100644 index 0000000..dfc75a1 --- /dev/null +++ b/cryptoim/key_exchange.py @@ -0,0 +1,24 @@ +import random +from const import PRIMES + +random = random.SystemRandom() +#Random generator useable for cryptography + +def generate_random(limit_lo, limit_hi): + return random.randint(limit_lo, limit_hi) + +def prime_pick(): + rnd = generate_random(0, len(PRIMES)) + return PRIMES[rnd] + +def base_pick(): + rnd = generate_random(1, 15) + return rnd + +def make_public_key(prime, base, p_number): + pub_key = (base ** rnumber) % prime + return pub_key + +def make_private_key(prime, pub_key, p_number): + private_key = (pub_key ** p_number) % prime + return private_key From f9ba10d27465105d429fa02ce2eaa82a0b985041 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 24 Jan 2014 22:17:23 +0100 Subject: [PATCH 67/95] Attempt at fixing #19, added messages on fail, removed yields, fixed some random stuff --- tests/TestXMPP.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 999f547..f6373a5 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -28,13 +28,13 @@ def test_xmpp(): Test for various xmpp methods: connect, send_message, receive message """ xmpp_cli = init_xmpp_cli() - yield check_connect, xmpp_cli + check_connect(xmpp_cli) xmpp_cli = init_xmpp_cli() - yield check_send_message, xmpp_cli + check_send_message(xmpp_cli) xmpp_cli = init_xmpp_cli() - yield check_receive_message, xmpp_cli + check_receive_message(xmpp_cli) def init_xmpp_cli(): """ @@ -45,7 +45,7 @@ def init_xmpp_cli(): xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) xmpp_cli.connect_server(should_block=False) - eq_(xmpp_cli.is_connected(), True) + waitForConnection(xmpp_cli, True) return xmpp_cli def check_connect(xmpp_client): @@ -53,7 +53,7 @@ def check_connect(xmpp_client): Check for xmpp.XMPPClient.connect_server and disconnect_server """ - waitForConnection(xmpp_client, True) + eq_(xmpp_client.is_connected(), True) xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) @@ -124,11 +124,11 @@ def check_receive_message(xmpp_client): Check for CryptoXMPP.message """ - crypto_shell = CryptoShell('main.cfg') + crypto_shell2 = CryptoShell('main.cfg') # Assert connected - xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell) + xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell2) xmpp_client2.connect_server(should_block=False) waitForConnection(xmpp_client, True) @@ -141,17 +141,18 @@ def check_receive_message(xmpp_client): ciphertext = xmpp_client.send_message(xmpp_client2.xmpp.jid, plaintext) # Disconnect - xmpp_client.disconnect_server(); + xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) xmpp_client2.disconnect_server() waitForConnection(xmpp_client2, False) - waitForConnection(xmpp_client, False) # Assert that xmpp_client2 got it (it is bound to be received after disconnect if it waits) - ok_(0 != len(crypto_shell.received_msg_list)) - eq_(len(crypto_shell.received_jid_list), len(crypto_shell.received_msg_list)) - eq_(plaintext, crypto_shell.received_msg_list[-1]) - eq_(xmpp_client.xmpp.jid, crypto_shell.received_jid_list[-1]) + ok_(0 != len(crypto_shell2.received_msg_list)) + eq_(len(crypto_shell2.received_jid_list), len(crypto_shell2.received_msg_list)) + print('Received msg list: ', crypto_shell2.received_msg_list) + print('Received jid list: ', crypto_shell2.received_jid_list) + eq_(plaintext, crypto_shell2.received_msg_list[-1], msg='If this test fails, rerun, probably a network/server error.') + eq_(xmpp_client.xmpp.jid, crypto_shell2.received_jid_list[-1], msg='If this test fails, rerun, probably a network/server error.') def waitForConnection(xmpp_client, should_be_connected): """ From 3aedfd2fc48d3f32225a30c0fbff37c25e0c91c3 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 24 Jan 2014 22:19:10 +0100 Subject: [PATCH 68/95] Fixed README typo --- README | 4 ++-- README.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index ac9e2ac..e2e21e1 100644 --- a/README +++ b/README @@ -71,13 +71,13 @@ Here are some ways *you* can contribute: * by writing specifications * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) * by refactoring code -* by closing `issues `_ +* by closing `issues `_ * by reviewing patches Submitting an Issue =================== -We use the `GitHub issue tracker `_ to track bugs and features. Before +We use the `GitHub issue tracker `_ to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. When submitting a bug report, please include a `Gist `_ that includes a stack trace and any details that may be necessary to reproduce diff --git a/README.rst b/README.rst index ac9e2ac..e2e21e1 100644 --- a/README.rst +++ b/README.rst @@ -71,13 +71,13 @@ Here are some ways *you* can contribute: * by writing specifications * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) * by refactoring code -* by closing `issues `_ +* by closing `issues `_ * by reviewing patches Submitting an Issue =================== -We use the `GitHub issue tracker `_ to track bugs and features. Before +We use the `GitHub issue tracker `_ to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. When submitting a bug report, please include a `Gist `_ that includes a stack trace and any details that may be necessary to reproduce From bd9e4515e5db2ac95e7b61fd2cde394523f82a04 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 24 Jan 2014 22:24:46 +0100 Subject: [PATCH 69/95] Added a timeout for checking of received msg --- tests/TestXMPP.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index f6373a5..d2f5207 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -140,6 +140,9 @@ def check_receive_message(xmpp_client): plaintext = 'Hello, CryptoIM check_receive_message!' ciphertext = xmpp_client.send_message(xmpp_client2.xmpp.jid, plaintext) + while len(crypto_shell2.received_msg_list) < 1: + time.sleep(0.1) + # Disconnect xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) @@ -147,12 +150,13 @@ def check_receive_message(xmpp_client): waitForConnection(xmpp_client2, False) # Assert that xmpp_client2 got it (it is bound to be received after disconnect if it waits) - ok_(0 != len(crypto_shell2.received_msg_list)) - eq_(len(crypto_shell2.received_jid_list), len(crypto_shell2.received_msg_list)) print('Received msg list: ', crypto_shell2.received_msg_list) print('Received jid list: ', crypto_shell2.received_jid_list) - eq_(plaintext, crypto_shell2.received_msg_list[-1], msg='If this test fails, rerun, probably a network/server error.') - eq_(xmpp_client.xmpp.jid, crypto_shell2.received_jid_list[-1], msg='If this test fails, rerun, probably a network/server error.') + + ok_(0 != len(crypto_shell2.received_msg_list)) + eq_(len(crypto_shell2.received_jid_list), len(crypto_shell2.received_msg_list)) + eq_(plaintext, crypto_shell2.received_msg_list[-1]) + eq_(xmpp_client.xmpp.jid, crypto_shell2.received_jid_list[-1]) def waitForConnection(xmpp_client, should_be_connected): """ From f291e1df4b96fe46e89876bd2efba244dcc37309 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Fri, 24 Jan 2014 22:29:20 +0100 Subject: [PATCH 70/95] Some more changes for #19 --- cryptoim/xmpp.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 3d64d52..d9ce822 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -36,9 +36,6 @@ class CryptoXMPP(sleekxmpp.ClientXMPP): """ A simple SleekXMPP client. """ - in_session = False - is_connected = False - parent = None def __init__(self, jid, password, parent): sleekxmpp.ClientXMPP.__init__(self, jid, password) @@ -60,6 +57,8 @@ def __init__(self, jid, password, parent): self.add_event_handler('disconnected', self.disconnected) self.parent = parent + self.in_session = False + self.is_connected = False def connected(self, event): """ From d33b6859586343dd0615e10c4a450344e8b730a0 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 25 Jan 2014 00:38:21 +0100 Subject: [PATCH 71/95] Updated setup.py [skip ci] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bcdcf2a..4d65b1b 100755 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ keywords = "crypto instant messenger", test_suite = "nose.collector", classifiers = [ - "Development Status :: 1 - Planning", + "Development Status :: 4 - Beta", "Environment :: Console", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", From a6630e387e600f87a5e96f0386fa766e1f754456 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 25 Jan 2014 11:11:10 +0100 Subject: [PATCH 72/95] Refactored before release --- cryptoim/__init__.py | 4 +-- cryptoim/cli.py | 38 ++++++++++++++------ cryptoim/const.py | 72 ++++++++++++++++++++++++++++++++++++++ cryptoim/encryptor_core.py | 4 +-- cryptoim/key_exchange.py | 48 +++++++++++++++++++++---- main.py | 2 +- setup.py | 62 ++++++++++++++++---------------- tests/TestDecryptorCore.py | 2 +- tests/TestEncryptorCore.py | 16 ++++----- 9 files changed, 186 insertions(+), 62 deletions(-) diff --git a/cryptoim/__init__.py b/cryptoim/__init__.py index efcf547..7997d59 100644 --- a/cryptoim/__init__.py +++ b/cryptoim/__init__.py @@ -14,6 +14,6 @@ limitations under the License. """ -from cryptoim import decryptor_core, encryptor_core, const, common, xmpp, cli +from cryptoim import decryptor_core, encryptor_core, const, common, xmpp, cli, key_exchange -__all__ = ["decryptor_core", "encryptor_core", "const", "common", "xmpp", "cli", ] +__all__ = ['decryptor_core', 'encryptor_core', 'const', 'common', 'xmpp', 'cli', 'key_exchange', ] diff --git a/cryptoim/cli.py b/cryptoim/cli.py index ae45ab9..de4ae10 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -65,14 +65,18 @@ def __init__(self, config_file): # -- basic commands -- def do_exit(self, arg): - 'Quit CryptoIM' + """ + Quit CryptoIM + """ self.do_disconnect(arg) self.print_cmd('Thank you for using CryptoIM!') sys.exit(0) def do_q(self, arg): - 'Alias for quit' + """ + Alias for quit + """ self.do_exit(arg) @@ -82,7 +86,9 @@ def emptyline(self): # -- xmpp commands -- def do_connect(self, arg): - 'connect JID PASSWORD or connect CONNECTION_NAME' + """ + connect JID PASSWORD or connect CONNECTION_NAME + """ splitted = arg.split(' ') if not sanit_arg_count(splitted, 0, 2): @@ -118,7 +124,7 @@ def do_connect(self, arg): def do_disconnect(self, arg): """ - disconnect + Disconnect """ if not self.xmpp_client or not self.xmpp_client.is_connected(): @@ -180,11 +186,15 @@ def do_removeconnection(self, arg): return self.return_cli(True) def do_s(self, arg): - 'send toJID or username msg' + """ + send alias + """ return(self.do_send(arg)) def do_send(self, arg): - 'send toJID or username msg' + """ + send toJID or username msg + """ if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') return self.return_cli(False) @@ -224,7 +234,9 @@ def do_send(self, arg): return self.return_cli(True) def do_addfriend(self, arg): - 'addfriend name jid' + """ + addfriend name jid + """ splitted = arg.split(' ') if not sanit_arg_count_exact(splitted, 2): @@ -241,7 +253,9 @@ def do_addfriend(self, arg): return self.return_cli(True) def do_removefriend(self, arg): - 'removefriend name' + """ + removefriend name + """ splitted = arg.split(' ') if not arg: @@ -284,8 +298,12 @@ def do_chat(self, arg): def do_friendlist(self, arg): """ - Displays all friends in main.cfg ['friends'] section + Displays all friends from config file friends section """ + + if not arg: + self.print_cmd('Usage: friendlist, not friendlist ') + for friend in self.config.items('friends'): self.print_cmd(' - '.join(friend)) @@ -297,7 +315,7 @@ def do_stopchat(self, arg): if not self.current_chat: self.print_cmd('No open chat to close.') return self.return_cli(False) - if arg is not None: + if not arg: self.print_cmd('Usage: stopchat, not stopchat ') self.prompt = '(cryptoim) ' diff --git a/cryptoim/const.py b/cryptoim/const.py index e7dde9a..06928b0 100644 --- a/cryptoim/const.py +++ b/cryptoim/const.py @@ -141,3 +141,75 @@ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] + +PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, + 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, + 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, + 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, + 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, + 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, + 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, + 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, + 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, + 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, + 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, + 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, + 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, + 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, + 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, + 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, + 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, + 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, + 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, + 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, + 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, + 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, + 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, + 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, + 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, + 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, + 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, + 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, + 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, + 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, + 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, + 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, + 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, + 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, + 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, + 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, + 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, + 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, + 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, + 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, + 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, + 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, + 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, + 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, + 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, + 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, + 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, + 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, + 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, + 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, + 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, + 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, + 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, + 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, + 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, + 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, + 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, + 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, + 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, + 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, + 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, + 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, + 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, + 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, + 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, + 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, + 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973] diff --git a/cryptoim/encryptor_core.py b/cryptoim/encryptor_core.py index 008804f..53f427f 100644 --- a/cryptoim/encryptor_core.py +++ b/cryptoim/encryptor_core.py @@ -35,7 +35,7 @@ def encrypt_round(messages, roundkeys): """ encrypt_round """ - ciphertext = "" + ciphertext = '' for msg in messages: msg = __add_roundkey(msg, roundkeys[14]) for i in range(14): @@ -65,7 +65,7 @@ def __split_message(plaintext): message_chunks.append(message_chunk) message_chunk = '' if i == (len(plaintext)-1) and len(message_chunk) < 16: - message_chunk += (16-len(message_chunk)) * "\x00" + message_chunk += (16-len(message_chunk)) * '\x00' message_chunks.append(message_chunk) message_chunk = '' messages = [] diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index dfc75a1..9cc4e4b 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -1,24 +1,58 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + import random -from const import PRIMES +from cryptoim.const import PRIMES -random = random.SystemRandom() -#Random generator useable for cryptography +# Random generator useable for cryptography +RAND = random.SystemRandom() def generate_random(limit_lo, limit_hi): - return random.randint(limit_lo, limit_hi) + """ + Returns a random integer inside the (limit_lo, limit_hi) interval + """ + return RAND.randint(limit_lo, limit_hi) def prime_pick(): + """ + Returns a random number from the const.PRIMES array + """ rnd = generate_random(0, len(PRIMES)) return PRIMES[rnd] def base_pick(): - rnd = generate_random(1, 15) + """ + Returns a random number from the const.PRIMES array from indexes interval (0, 15) + """ + rnd = generate_random(0, 15) return rnd -def make_public_key(prime, base, p_number): +def make_public_key(prime, base, rnumber): + """ + Returns (base^number) mod prime, the public key used for the key exchange + """ pub_key = (base ** rnumber) % prime return pub_key -def make_private_key(prime, pub_key, p_number): +def make_final_key(prime, pub_key, p_number): + """ + Returns (pub_key^p_number) mod prime, the key used for encryption + """ private_key = (pub_key ** p_number) % prime return private_key diff --git a/main.py b/main.py index 3a0c1de..6fa9b46 100755 --- a/main.py +++ b/main.py @@ -19,5 +19,5 @@ from cryptoim.cli import CryptoShell -if __name__ == "__main__": +if __name__ == '__main__': CryptoShell('main.cfg').cmdloop() diff --git a/setup.py b/setup.py index 4d65b1b..0b30442 100755 --- a/setup.py +++ b/setup.py @@ -2,48 +2,48 @@ # encoding: utf-8 """ - Copyright 2013-2014 CryptoIM Development Team + Copyright 2014 CryptoIM Development Team - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. """ from setuptools import setup, find_packages setup( - name = "CryptoIM", - version = "0.1.0dev", - author = "CryptoIM Development Team", - author_email = "skopekondrej@gmail.com", - packages = find_packages(exclude=["tests"]), + name = 'CryptoIM', + version = '0.1.0dev', + author = 'CryptoIM Development Team', + author_email = 'skopekondrej@gmail.com', + packages = find_packages(exclude=['tests']), scripts = ['main.py'], - url = "http://pypi.python.org/pypi/CryptoIM/", - license = "Apache License 2.0", - description = "Crypto Instant Messenger", - keywords = "crypto instant messenger", - test_suite = "nose.collector", + url = 'http://pypi.python.org/pypi/CryptoIM/', + license = 'Apache License 2.0', + description = 'Crypto Instant Messenger', + keywords = 'crypto instant messenger', + test_suite = 'nose.collector', classifiers = [ - "Development Status :: 4 - Beta", - "Environment :: Console", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Programming Language :: Python", - "Topic :: Communications :: Chat", - "Topic :: Security :: Cryptography", + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Programming Language :: Python', + 'Topic :: Communications :: Chat', + 'Topic :: Security :: Cryptography', ], - long_description = open("README").read(), + long_description = open('README').read(), install_requires = [ - "nose >= 1.3.0", - "python-coveralls >= 2.4.2", - "sleekxmpp >= 1.1.11" + 'nose >= 1.3.0', + 'python-coveralls >= 2.4.2', + 'sleekxmpp >= 1.1.11' ], ) diff --git a/tests/TestDecryptorCore.py b/tests/TestDecryptorCore.py index 646008e..1657076 100644 --- a/tests/TestDecryptorCore.py +++ b/tests/TestDecryptorCore.py @@ -73,7 +73,7 @@ def rand_str(limit): from string import ascii_letters from random import choice - rand = "" + rand = '' for _ in range(limit): rand += choice(ascii_letters) return rand diff --git a/tests/TestEncryptorCore.py b/tests/TestEncryptorCore.py index c993f7e..e5b0a00 100644 --- a/tests/TestEncryptorCore.py +++ b/tests/TestEncryptorCore.py @@ -25,7 +25,7 @@ def test_encrypt(): Test for encryptor_core.encrypt """ encrypt = encryptor_core.encrypt - message = "This is a test message!" + message = 'This is a test message!' def rand_str(limit): """ @@ -44,12 +44,12 @@ def rand_str(limit): encrypted_str = encrypt(message, key) print(encrypted_str) - ok_(len(encrypted_str) >= 0, "Length wasn't supposed to be 0") + ok_(len(encrypted_str) >= 0, 'Length wasn\'t supposed to be 0') - encrypted1 = encrypt("014730f80ac625fe84f026c60bfd547d", "0000000000000000000000000000000000000000000000000000000000000000") + encrypted1 = encrypt('014730f80ac625fe84f026c60bfd547d', '0000000000000000000000000000000000000000000000000000000000000000') print(encrypted1) - #expected1 = "5c9d844ed46f9885085e5d6a4f94c7d7" - ok_(len(encrypted1) >= 0, "Length wasn't supposed to be 0") + #expected1 = '5c9d844ed46f9885085e5d6a4f94c7d7' + ok_(len(encrypted1) >= 0, 'Length wasn\'t supposed to be 0') # TODO eq_(encrypted1, expected1) @@ -96,8 +96,8 @@ def test_message_fusion(): [0, 0, 0, 0], [0, 0, 0, 0]] - ok_(type(message_fusion(input_mat)) == str, "Not a string!") - ok_(type(message_fusion(input_mat_zeros)) == str, "Zeros - Not a string!") + ok_(type(message_fusion(input_mat)) == str, 'Not a string!') + ok_(type(message_fusion(input_mat_zeros)) == str, 'Zeros - Not a string!') eq_(len(message_fusion(input_mat)), 32) eq_(len(message_fusion(input_mat_zeros)), 32) @@ -115,7 +115,7 @@ def rand_str(limit): from string import ascii_letters from random import choice - rand = "" + rand = '' for _ in range(limit): rand += choice(ascii_letters) return rand From 6cf93c36a8c25c2b0a265305512a6d9717361fa8 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sat, 25 Jan 2014 14:12:54 +0100 Subject: [PATCH 73/95] Updated version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0b30442..2b1a39e 100755 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup( name = 'CryptoIM', - version = '0.1.0dev', + version = '0.1.0', author = 'CryptoIM Development Team', author_email = 'skopekondrej@gmail.com', packages = find_packages(exclude=['tests']), From 15cb573a6d56ca7dc1fe65d3afafbd479d58e5cd Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 15:02:25 +0100 Subject: [PATCH 74/95] Probably fixed message bug --- tests/TestXMPP.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index d2f5207..a45f80f 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -71,18 +71,21 @@ def check_send_message(xmpp_client): """ Check for xmpp.XMPPClient.send_message """ - + + crypto_shell = xmpp_client.xmpp.parent waitForConnection(xmpp_client, True) waitForSession(xmpp_client, True) msg = 'Hello, CryptoIM check_send_message!' recipient = 'cryptoim2@jabber.de' xmpp_client.send_message(recipient, msg) + while len(crypto_shell.sent_msg_list) < 1: + time.sleep(0.1) + xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) - # Assert that xmpp_client sent the message (it is bound to be sent after disconnect if it waits) - crypto_shell = xmpp_client.xmpp.parent + # Assert that xmpp_client sent the message (it is bound to be sent after disconnect if it waits) ok_(0 != len(crypto_shell.sent_msg_list)) eq_(len(crypto_shell.sent_jid_list), len(crypto_shell.sent_msg_list)) eq_(msg, crypto_shell.sent_msg_list[-1]) From ce23ac9a2764352e81dd0831d39d7fcb6d6a86e7 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 16:09:53 +0100 Subject: [PATCH 75/95] Wrote tests for key_exchange --- cryptoim/key_exchange.py | 2 +- tests/TestKeyExchange.py | 92 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tests/TestKeyExchange.py diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index 9cc4e4b..a34e7ea 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -40,7 +40,7 @@ def base_pick(): """ Returns a random number from the const.PRIMES array from indexes interval (0, 15) """ - rnd = generate_random(0, 15) + rnd = generate_random(1, 15) return rnd def make_public_key(prime, base, rnumber): diff --git a/tests/TestKeyExchange.py b/tests/TestKeyExchange.py new file mode 100644 index 0000000..c860ae1 --- /dev/null +++ b/tests/TestKeyExchange.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" + Copyright 2014 CryptoIM Development Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import cryptoim.key_exchange as k_ex +from nose.tools import ok_, eq_ + +def test_generate_random(): + """ + Test for key_exchange.generate_random + """ + generate_random = k_ex.generate_random + + random_numero = generate_random(1, 100) + eq_(type(random_numero), int) + ok_(random_numero >= 1 and random_numero <= 100) + +def test_prime_pick(): + """ + Test for key_exchange.prime_prick + """ + prime_pick = k_ex.prime_pick + + prime = prime_pick() + eq_(type(prime), int) + +def test_base_pick(): + """ + Test for key_exchange.base_pick + """ + base_pick = k_ex.base_pick + + base = base_pick() + eq_(type(base), int) + +def test_make_public_key(): + """ + Test for key_exchange.make_public_key + """ + make_public_key = k_ex.make_public_key + prime_pick = k_ex.prime_pick + generate_random = k_ex.generate_random + base_pick = k_ex.base_pick + + prime = prime_pick() + base = base_pick() + rnumber = generate_random(1, 100) + + public_key = make_public_key(prime, base, rnumber) + manual_public_key = (base**rnumber)%prime + + eq_(type(public_key), int) + eq_(public_key, manual_public_key) + +def test_make_final_key(): + """ + Test for key_exchange.make_final_key + """ + make_public_key = k_ex.make_public_key + prime_pick = k_ex.prime_pick + generate_random = k_ex.generate_random + base_pick = k_ex.base_pick + make_final_key = k_ex.make_final_key + + for i in range(100): + a = generate_random(1, 100) + b = generate_random(1, 100) + p = prime_pick() + g = base_pick() + + A = make_public_key(p, g, a) + B = make_public_key(p, g, b) + + eq_(type(make_final_key(p, B, a)), int) + eq_(type(make_final_key(p, A, b)), int) + eq_(make_final_key(p, B, a), make_final_key(p, A, b)) + From d663db973169e9fa4daf0de0b18abaeb9f67c8d6 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 16:14:17 +0100 Subject: [PATCH 76/95] Fixed 'long' assertion error --- tests/TestKeyExchange.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/TestKeyExchange.py b/tests/TestKeyExchange.py index c860ae1..5faad47 100644 --- a/tests/TestKeyExchange.py +++ b/tests/TestKeyExchange.py @@ -27,7 +27,7 @@ def test_generate_random(): generate_random = k_ex.generate_random random_numero = generate_random(1, 100) - eq_(type(random_numero), int) + eq_(type(random_numero), int or long) ok_(random_numero >= 1 and random_numero <= 100) def test_prime_pick(): @@ -37,7 +37,7 @@ def test_prime_pick(): prime_pick = k_ex.prime_pick prime = prime_pick() - eq_(type(prime), int) + eq_(type(prime), int or long) def test_base_pick(): """ @@ -46,7 +46,7 @@ def test_base_pick(): base_pick = k_ex.base_pick base = base_pick() - eq_(type(base), int) + eq_(type(base), int or long) def test_make_public_key(): """ @@ -64,7 +64,7 @@ def test_make_public_key(): public_key = make_public_key(prime, base, rnumber) manual_public_key = (base**rnumber)%prime - eq_(type(public_key), int) + eq_(type(public_key), int or long) eq_(public_key, manual_public_key) def test_make_final_key(): @@ -86,7 +86,7 @@ def test_make_final_key(): A = make_public_key(p, g, a) B = make_public_key(p, g, b) - eq_(type(make_final_key(p, B, a)), int) - eq_(type(make_final_key(p, A, b)), int) + eq_(type(make_final_key(p, B, a)), int or long) + eq_(type(make_final_key(p, A, b)), int or long) eq_(make_final_key(p, B, a), make_final_key(p, A, b)) From bdfd73789189b8e872ee19e2bea6ab5d3194442c Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 16:21:04 +0100 Subject: [PATCH 77/95] First draft of key exchange --- cryptoim/key_exchange.py | 36 +++++++++++++++++++-- cryptoim/xmpp.py | 67 ++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index a34e7ea..47c5619 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -50,9 +50,39 @@ def make_public_key(prime, base, rnumber): pub_key = (base ** rnumber) % prime return pub_key -def make_final_key(prime, pub_key, p_number): +def make_final_key(prime, public, private): """ Returns (pub_key^p_number) mod prime, the key used for encryption """ - private_key = (pub_key ** p_number) % prime - return private_key + key = (public ** private) % prime + return key + +def encode_syn(prime, base, A): + """ + Encodes the numbers in a standardized format + """ + return 'SYN;%i;%i;%i' % (prime, base, A) + +def decode_syn(msg): + """ + Decodes the numbers in a standardized format + """ + cut = msg[5:] # Omit the first 4 chars ('SYN;') + spl = cut.split(';') + prime = int(spl[0]) + base = int(spl[1]) + A = int(spl[2]) + return prime, base, A + +def encode_ack(B): + """ + Encodes the number in a standardized format + """ + return 'ACK;%i' % (B) + +def decode_ack(msg): + """ + Decodes the numbers in a standardized format + """ + cut = msg[5:] # Omit the first 4 chars ('SYN;') + return int(cut) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index d9ce822..6917f92 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -27,9 +27,11 @@ import logging import sleekxmpp +import random import cryptoim.encryptor_core as encryptor import cryptoim.decryptor_core as decryptor +import cryptoim.key_exchange as keyex class CryptoXMPP(sleekxmpp.ClientXMPP): @@ -111,18 +113,49 @@ def message(self, msg): for stanza objects and the Message stanza to see how it may be used. """ + sender = msg['from'].bare - ciphertext = msg['body'] - decrypted_message = decryptor.decrypt(ciphertext, 'This is a secret key') - self.parent.print_msg(msg['from'].bare, decrypted_message) + if msg['type'] == 'SYN': # receiving + prime, base, A = keyex.decode_syn(msg['body']) + b = keyex.generate_random(2, 100) + B = keyex.make_public_key(prime, base, b) + key = keyex.make_final_key(prime, b, A) - # Log: - self.parent.received_jid_list.append(msg['from'].bare) - self.parent.received_msg_list.append(decrypted_message) + self.send_message(mto = sender, mbody = keyex.encode_ack(B), mtype = 'ACK') + self.key_queue[sender] = key - #if msg['type'] in ('chat', 'normal'): - #msg.reply('Thanks for sending\n%(body)s' % msg).send() - #print('DEBUG: MSG: %(body)s' % msg) + elif msg['type'] == 'ACK': # sending + q_entry = self.msg_queue[sender] + msg = q_entry[0] + prime = q_entry[1] + a = q_entry[2] + B = keyex.decode_ack(msg['body']) + key = keyex.make_final_key(prime, B, a) + + ciphertext = encryptor.encrypt(msg, key) + self.xmpp.send_message(mto = sender, mbody = ciphertext, mtype = 'chat') + + del q_entry # TODO check if it actually gets removed + + # Log: + self.xmpp.parent.sent_jid_list.append(sender) + self.xmpp.parent.sent_msg_list.append(msg) + + else: + ciphertext = msg['body'] + key = self.key_queue[sender] + decrypted_message = decryptor.decrypt(ciphertext, key) + self.parent.print_msg(sender, decrypted_message) + + del key # TODO check if it actually gets removed + + # Log: + self.parent.received_jid_list.append(sender) + self.parent.received_msg_list.append(decrypted_message) + + #if msg['type'] in ('chat', 'normal'): + #msg.reply('Thanks for sending\n%(body)s' % msg).send() + #print('DEBUG: MSG: %(body)s' % msg) class XMPPClient(object): @@ -150,6 +183,9 @@ def __init__(self, jid, password, parent, loglevel=logging.CRITICAL): self.xmpp.register_plugin('xep_0060') # PubSub self.xmpp.register_plugin('xep_0199') # XMPP Ping + self.msg_queue = dict() + self.key_queue = dict() + def connect_server(self, should_block=False, should_reattempt=True): """ @@ -192,11 +228,10 @@ def send_message(self, recipient, msg): """ Sends a chat message to the designated recipient. """ - ciphertext = encryptor.encrypt(msg, 'This is a secret key') - self.xmpp.send_message(mto = recipient, mbody = ciphertext, mtype = 'chat') - - # Log: - self.xmpp.parent.sent_jid_list.append(recipient) - self.xmpp.parent.sent_msg_list.append(msg) + prime = keyex.prime_pick() + base = keyex.base_pick() + a = keyex.generate_random(2, 100) + A = keyex.make_public_key(prime, base, a) - return ciphertext + self.xmpp.send_message(mto = recipient, mbody = keyex.encode_syn(prime, base, A), mtype = 'SYN') + self.msg_queue[recipient] = (msg, prime, a) From c2c88373ad0fb9c4a0361f67017b1a82eebbd5ab Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 16:24:37 +0100 Subject: [PATCH 78/95] Finally fixed 'long' error also for 2.6 and 2.7 --- cryptoim/key_exchange.py | 2 +- tests/TestKeyExchange.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index 47c5619..7e762a1 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -33,7 +33,7 @@ def prime_pick(): """ Returns a random number from the const.PRIMES array """ - rnd = generate_random(0, len(PRIMES)) + rnd = generate_random(0, len(PRIMES) - 1) return PRIMES[rnd] def base_pick(): diff --git a/tests/TestKeyExchange.py b/tests/TestKeyExchange.py index 5faad47..a4fde57 100644 --- a/tests/TestKeyExchange.py +++ b/tests/TestKeyExchange.py @@ -37,7 +37,7 @@ def test_prime_pick(): prime_pick = k_ex.prime_pick prime = prime_pick() - eq_(type(prime), int or long) + eq_(type(prime), int) def test_base_pick(): """ @@ -46,7 +46,7 @@ def test_base_pick(): base_pick = k_ex.base_pick base = base_pick() - eq_(type(base), int or long) + eq_(type(base), int) def test_make_public_key(): """ @@ -64,7 +64,7 @@ def test_make_public_key(): public_key = make_public_key(prime, base, rnumber) manual_public_key = (base**rnumber)%prime - eq_(type(public_key), int or long) + ok_(type(public_key) == int or type(public_key) == long) eq_(public_key, manual_public_key) def test_make_final_key(): @@ -86,7 +86,7 @@ def test_make_final_key(): A = make_public_key(p, g, a) B = make_public_key(p, g, b) - eq_(type(make_final_key(p, B, a)), int or long) - eq_(type(make_final_key(p, A, b)), int or long) + ok_(type(make_final_key(p, B, a)) == int or type(make_final_key(p, B, a)) == long) + ok_(type(make_final_key(p, A, b)) == int or type(make_final_key(p, A, b)) == long) eq_(make_final_key(p, B, a), make_final_key(p, A, b)) From 1434b4bade12ab0ff1489d63ebac7f771597e7ae Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 17:32:21 +0100 Subject: [PATCH 79/95] fixed base_pick --- cryptoim/key_exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index 7e762a1..d32316b 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -40,7 +40,7 @@ def base_pick(): """ Returns a random number from the const.PRIMES array from indexes interval (0, 15) """ - rnd = generate_random(1, 15) + rnd = generate_random(2, 15) return rnd def make_public_key(prime, base, rnumber): From e1d3644dc295ed4ce05d043d4e5518da6581c2c5 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 17:40:30 +0100 Subject: [PATCH 80/95] Fixed some stuff relating to key exchange --- cryptoim/xmpp.py | 49 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 6917f92..daf79bf 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -62,6 +62,9 @@ def __init__(self, jid, password, parent): self.in_session = False self.is_connected = False + self.msg_queue = dict() + self.key_queue = dict() + def connected(self, event): """ Process the connected event. @@ -114,44 +117,51 @@ def message(self, msg): how it may be used. """ sender = msg['from'].bare + text = msg['body'] - if msg['type'] == 'SYN': # receiving + if text.startswith('SYN;'): # receiving prime, base, A = keyex.decode_syn(msg['body']) + print('prime: ', prime) + print('base: ', base) + print('A: ', A) b = keyex.generate_random(2, 100) B = keyex.make_public_key(prime, base, b) - key = keyex.make_final_key(prime, b, A) + key = str(keyex.make_final_key(prime, b, A)) - self.send_message(mto = sender, mbody = keyex.encode_ack(B), mtype = 'ACK') + self.send_message(mto = sender, mbody = keyex.encode_ack(B), mtype = 'chat') self.key_queue[sender] = key - elif msg['type'] == 'ACK': # sending + elif text.startswith('ACK;'): # sending q_entry = self.msg_queue[sender] - msg = q_entry[0] + msg_text = q_entry[0] prime = q_entry[1] a = q_entry[2] + print('msg: ', msg_text) + print('prime: ', prime) + print('a: ', a) B = keyex.decode_ack(msg['body']) - key = keyex.make_final_key(prime, B, a) - - ciphertext = encryptor.encrypt(msg, key) - self.xmpp.send_message(mto = sender, mbody = ciphertext, mtype = 'chat') + key = str(keyex.make_final_key(prime, B, a)) + print('key: ', key) + ciphertext = encryptor.encrypt(msg_text, key) + self.send_message(mto = sender, mbody = ciphertext, mtype = 'chat') del q_entry # TODO check if it actually gets removed # Log: - self.xmpp.parent.sent_jid_list.append(sender) - self.xmpp.parent.sent_msg_list.append(msg) + self.parent.sent_jid_list.append(sender) + self.parent.sent_msg_list.append(msg_text) else: - ciphertext = msg['body'] + ciphertext = text key = self.key_queue[sender] decrypted_message = decryptor.decrypt(ciphertext, key) - self.parent.print_msg(sender, decrypted_message) + self.print_msg(sender, decrypted_message) del key # TODO check if it actually gets removed # Log: - self.parent.received_jid_list.append(sender) - self.parent.received_msg_list.append(decrypted_message) + self.received_jid_list.append(sender) + self.received_msg_list.append(decrypted_message) #if msg['type'] in ('chat', 'normal'): #msg.reply('Thanks for sending\n%(body)s' % msg).send() @@ -165,7 +175,7 @@ class XMPPClient(object): xmpp = None - def __init__(self, jid, password, parent, loglevel=logging.CRITICAL): + def __init__(self, jid, password, parent, loglevel=logging.DEBUG): """ Initializes the ClientXMPP, logging, etc """ @@ -183,9 +193,6 @@ def __init__(self, jid, password, parent, loglevel=logging.CRITICAL): self.xmpp.register_plugin('xep_0060') # PubSub self.xmpp.register_plugin('xep_0199') # XMPP Ping - self.msg_queue = dict() - self.key_queue = dict() - def connect_server(self, should_block=False, should_reattempt=True): """ @@ -233,5 +240,5 @@ def send_message(self, recipient, msg): a = keyex.generate_random(2, 100) A = keyex.make_public_key(prime, base, a) - self.xmpp.send_message(mto = recipient, mbody = keyex.encode_syn(prime, base, A), mtype = 'SYN') - self.msg_queue[recipient] = (msg, prime, a) + self.xmpp.send_message(mto = recipient, mbody = keyex.encode_syn(prime, base, A), mtype = 'chat') + self.xmpp.msg_queue[recipient] = (msg, prime, a) From 369dd85c09eb7349bdb1eb312cbc791913a4cbf0 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 20:43:35 +0100 Subject: [PATCH 81/95] Refactored tests --- tests/TestCli.py | 4 --- tests/TestKeyExchange.py | 26 +++++++++-------- tests/TestXMPP.py | 61 ++++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index cb6cd76..96e869d 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -41,7 +41,6 @@ def test_connect_disconnect(): exit_code = 0 eq_(0, exit_code) - def test_connect_disconnect_jid(): cshell = CryptoShell('main.cfg') @@ -91,7 +90,6 @@ def test_chat_stopchat_exit(): exit_code = 0 eq_(0, exit_code) - def test_addfriend_removefriend(): cshell = CryptoShell('tests/test_config.cfg') @@ -147,9 +145,7 @@ def test_create_config(): import os os.remove(config_file) - # Test tools - def test_sanit_is_jid(): is_jid = cli.sanit_is_jid eq_(True, is_jid('test@jabber.de')) diff --git a/tests/TestKeyExchange.py b/tests/TestKeyExchange.py index a4fde57..b8040b2 100644 --- a/tests/TestKeyExchange.py +++ b/tests/TestKeyExchange.py @@ -25,7 +25,7 @@ def test_generate_random(): Test for key_exchange.generate_random """ generate_random = k_ex.generate_random - + random_numero = generate_random(1, 100) eq_(type(random_numero), int or long) ok_(random_numero >= 1 and random_numero <= 100) @@ -56,14 +56,14 @@ def test_make_public_key(): prime_pick = k_ex.prime_pick generate_random = k_ex.generate_random base_pick = k_ex.base_pick - + prime = prime_pick() base = base_pick() rnumber = generate_random(1, 100) - + public_key = make_public_key(prime, base, rnumber) manual_public_key = (base**rnumber)%prime - + ok_(type(public_key) == int or type(public_key) == long) eq_(public_key, manual_public_key) @@ -77,16 +77,18 @@ def test_make_final_key(): base_pick = k_ex.base_pick make_final_key = k_ex.make_final_key - for i in range(100): - a = generate_random(1, 100) - b = generate_random(1, 100) + for i in range(10): + a = generate_random(2, 100) + b = generate_random(2, 100) p = prime_pick() g = base_pick() - + A = make_public_key(p, g, a) B = make_public_key(p, g, b) - - ok_(type(make_final_key(p, B, a)) == int or type(make_final_key(p, B, a)) == long) - ok_(type(make_final_key(p, A, b)) == int or type(make_final_key(p, A, b)) == long) - eq_(make_final_key(p, B, a), make_final_key(p, A, b)) + keyA = make_final_key(p, B, a) + keyB = make_final_key(p, A, b) + + ok_(type(keyA) == int or type(keyA) == long) + ok_(type(keyB) == int or type(keyB) == long) + eq_(keyA, keyB) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index a45f80f..d03c6a8 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -27,63 +27,66 @@ def test_xmpp(): """ Test for various xmpp methods: connect, send_message, receive message """ - xmpp_cli = init_xmpp_cli() - check_connect(xmpp_cli) + xmpp_client, xmpp_client2 = init_xmpp_clients() + check_connect(xmpp_client, xmpp_client2) - xmpp_cli = init_xmpp_cli() - check_send_message(xmpp_cli) + xmpp_client, xmpp_client2 = init_xmpp_clients() + check_send_message(xmpp_client, xmpp_client2) - xmpp_cli = init_xmpp_cli() - check_receive_message(xmpp_cli) + xmpp_client, xmpp_client2 = init_xmpp_clients() + check_receive_message(xmpp_client, xmpp_client2) -def init_xmpp_cli(): +def init_xmpp_clients(): """ - Initializes the xmpp_client and connects it + Initializes the xmpp_clients and connects them """ crypto_shell = CryptoShell('main.cfg') - xmpp_cli = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) - xmpp_cli.connect_server(should_block=False) + xmpp_client = xmpp.XMPPClient('cryptoim@jabber.de', 'crypto_test', crypto_shell) + xmpp_client.connect_server(should_block=False) - waitForConnection(xmpp_cli, True) - return xmpp_cli + crypto_shell2 = CryptoShell('main.cfg') + xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell2) + xmpp_client2.connect_server(should_block=False) + + waitForConnection(xmpp_client, True) + waitForConnection(xmpp_client2, True) + return xmpp_client, xmpp_client2 -def check_connect(xmpp_client): +def check_connect(xmpp_client, xmpp_client2): """ Check for xmpp.XMPPClient.connect_server and disconnect_server """ eq_(xmpp_client.is_connected(), True) + eq_(xmpp_client2.is_connected(), True) xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) + xmpp_client2.disconnect_server() + waitForConnection(xmpp_client2, False) - # Uncomment the following to enable a second check -- note, will require a ~10s timeout - """ - xmpp_client.connect_server(should_block=False) - waitForConnection(xmpp_client, True) - - xmpp_client.disconnect_server() - waitForConnection(xmpp_client, False) - """ - -def check_send_message(xmpp_client): +def check_send_message(xmpp_client, xmpp_client2): """ Check for xmpp.XMPPClient.send_message """ - + crypto_shell = xmpp_client.xmpp.parent waitForConnection(xmpp_client, True) + waitForConnection(xmpp_client2, True) waitForSession(xmpp_client, True) + waitForSession(xmpp_client2, True) msg = 'Hello, CryptoIM check_send_message!' - recipient = 'cryptoim2@jabber.de' + recipient = xmpp_client2.xmpp.jid xmpp_client.send_message(recipient, msg) while len(crypto_shell.sent_msg_list) < 1: time.sleep(0.1) xmpp_client.disconnect_server() + xmpp_client2.disconnect_server() waitForConnection(xmpp_client, False) + waitForConnection(xmpp_client2, False) # Assert that xmpp_client sent the message (it is bound to be sent after disconnect if it waits) ok_(0 != len(crypto_shell.sent_msg_list)) @@ -122,18 +125,14 @@ def assertDisconnect(xmpp_client): xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) -def check_receive_message(xmpp_client): +def check_receive_message(xmpp_client, xmpp_client2): """ Check for CryptoXMPP.message """ - crypto_shell2 = CryptoShell('main.cfg') + crypto_shell2 = xmpp_client2.xmpp.parent # Assert connected - - xmpp_client2 = xmpp.XMPPClient('cryptoim2@jabber.de', 'crypto_test2', crypto_shell2) - xmpp_client2.connect_server(should_block=False) - waitForConnection(xmpp_client, True) waitForConnection(xmpp_client2, True) waitForSession(xmpp_client, True) From e80014c8e758f006eb012fcefad2f7561cff44dc Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 20:44:14 +0100 Subject: [PATCH 82/95] Fixed splicing error --- cryptoim/key_exchange.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cryptoim/key_exchange.py b/cryptoim/key_exchange.py index d32316b..34af5c1 100644 --- a/cryptoim/key_exchange.py +++ b/cryptoim/key_exchange.py @@ -67,7 +67,7 @@ def decode_syn(msg): """ Decodes the numbers in a standardized format """ - cut = msg[5:] # Omit the first 4 chars ('SYN;') + cut = msg[4:] # Omit the first 4 chars ('SYN;') spl = cut.split(';') prime = int(spl[0]) base = int(spl[1]) @@ -82,7 +82,7 @@ def encode_ack(B): def decode_ack(msg): """ - Decodes the numbers in a standardized format + Decodes the number in a standardized format """ - cut = msg[5:] # Omit the first 4 chars ('SYN;') + cut = msg[4:] # Omit the first 4 chars ('ACK;') return int(cut) From 0e9caa306d63e4b65bbebf8cedd1639c3906b173 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 20:45:11 +0100 Subject: [PATCH 83/95] Fixed key exchange, fixed jid resource suffix on tests, removed debugging prints --- cryptoim/cli.py | 1 - cryptoim/xmpp.py | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index de4ae10..9b1bd00 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -116,7 +116,6 @@ def do_connect(self, arg): conn_jid = splitted[0] conn_pass = splitted[1] - conn_jid += '/cryptoim' # Adds a static resource self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() return self.return_cli(True) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index daf79bf..c3fd258 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -40,6 +40,11 @@ class CryptoXMPP(sleekxmpp.ClientXMPP): """ def __init__(self, jid, password, parent): + # Add a static resource + if '/' in jid: + jid = jid[:jid.index('/')] + jid += '/cryptoim' + print('JID: ', jid) sleekxmpp.ClientXMPP.__init__(self, jid, password) # The session_start event will be triggered when @@ -116,17 +121,20 @@ def message(self, msg): for stanza objects and the Message stanza to see how it may be used. """ + + if msg['type'] not in ('chat', 'normal'): + return # Ignore nonchat messages + sender = msg['from'].bare text = msg['body'] + # DH key exchange: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Explanation_including_encryption_mathematics + if text.startswith('SYN;'): # receiving prime, base, A = keyex.decode_syn(msg['body']) - print('prime: ', prime) - print('base: ', base) - print('A: ', A) b = keyex.generate_random(2, 100) B = keyex.make_public_key(prime, base, b) - key = str(keyex.make_final_key(prime, b, A)) + key = str(keyex.make_final_key(prime, A, b)) self.send_message(mto = sender, mbody = keyex.encode_ack(B), mtype = 'chat') self.key_queue[sender] = key @@ -136,12 +144,8 @@ def message(self, msg): msg_text = q_entry[0] prime = q_entry[1] a = q_entry[2] - print('msg: ', msg_text) - print('prime: ', prime) - print('a: ', a) B = keyex.decode_ack(msg['body']) key = str(keyex.make_final_key(prime, B, a)) - print('key: ', key) ciphertext = encryptor.encrypt(msg_text, key) self.send_message(mto = sender, mbody = ciphertext, mtype = 'chat') @@ -155,17 +159,13 @@ def message(self, msg): ciphertext = text key = self.key_queue[sender] decrypted_message = decryptor.decrypt(ciphertext, key) - self.print_msg(sender, decrypted_message) + self.parent.print_msg(sender, decrypted_message) del key # TODO check if it actually gets removed # Log: - self.received_jid_list.append(sender) - self.received_msg_list.append(decrypted_message) - - #if msg['type'] in ('chat', 'normal'): - #msg.reply('Thanks for sending\n%(body)s' % msg).send() - #print('DEBUG: MSG: %(body)s' % msg) + self.parent.received_jid_list.append(sender) + self.parent.received_msg_list.append(decrypted_message) class XMPPClient(object): From b92dc2aff79d8ca40fd399385099c3dfc3ca66e6 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 20:51:43 +0100 Subject: [PATCH 84/95] Updated verbosity on nosetests --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index a2ec557..215100c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,8 @@ [nosetests] +verbosity=3 with-coverage=1 cover-package=cryptoim cover-tests=0 cover-erase=1 cover-branches=1 +#with-timer=1 From 86d8b7e06cf94bf09411e67656ffc2f03432fdd5 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 20:58:21 +0100 Subject: [PATCH 85/95] Adding edge-cases to tests --- tests/TestCli.py | 2 +- tests/TestXMPP.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index 96e869d..8cd08c5 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -45,7 +45,7 @@ def test_connect_disconnect_jid(): cshell = CryptoShell('main.cfg') cshell.test_mode = True - eq_(cshell.do_connect('cryptoim@jabber.de crypto_test'), True) + eq_(cshell.do_connect('cryptoim@jabber.de/random_resource_gets_stripped crypto_test'), True) eq_(cshell.do_disconnect(''), True) eq_(cshell.do_disconnect(''), False) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index d03c6a8..836fc71 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -78,6 +78,7 @@ def check_send_message(xmpp_client, xmpp_client2): waitForSession(xmpp_client2, True) msg = 'Hello, CryptoIM check_send_message!' recipient = xmpp_client2.xmpp.jid + xmpp_client.xmpp.send_message(mto = recipient, mbody = 'test', mtype = 'error') # Test for dropping non-chat messages xmpp_client.send_message(recipient, msg) while len(crypto_shell.sent_msg_list) < 1: @@ -89,7 +90,7 @@ def check_send_message(xmpp_client, xmpp_client2): waitForConnection(xmpp_client2, False) # Assert that xmpp_client sent the message (it is bound to be sent after disconnect if it waits) - ok_(0 != len(crypto_shell.sent_msg_list)) + ok_(1 == len(crypto_shell.sent_msg_list)) eq_(len(crypto_shell.sent_jid_list), len(crypto_shell.sent_msg_list)) eq_(msg, crypto_shell.sent_msg_list[-1]) eq_(recipient, crypto_shell.sent_jid_list[-1]) @@ -155,7 +156,7 @@ def check_receive_message(xmpp_client, xmpp_client2): print('Received msg list: ', crypto_shell2.received_msg_list) print('Received jid list: ', crypto_shell2.received_jid_list) - ok_(0 != len(crypto_shell2.received_msg_list)) + ok_(1 == len(crypto_shell2.received_msg_list)) eq_(len(crypto_shell2.received_jid_list), len(crypto_shell2.received_msg_list)) eq_(plaintext, crypto_shell2.received_msg_list[-1]) eq_(xmpp_client.xmpp.jid, crypto_shell2.received_jid_list[-1]) From 090e1a3e4ed5b39e9e4d77427b5deba22699549b Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 21:19:57 +0100 Subject: [PATCH 86/95] Quick travis workaround --- tests/TestXMPP.py | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 836fc71..5698fa4 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -23,19 +23,6 @@ from nose.tools import ok_, eq_, nottest import time -def test_xmpp(): - """ - Test for various xmpp methods: connect, send_message, receive message - """ - xmpp_client, xmpp_client2 = init_xmpp_clients() - check_connect(xmpp_client, xmpp_client2) - - xmpp_client, xmpp_client2 = init_xmpp_clients() - check_send_message(xmpp_client, xmpp_client2) - - xmpp_client, xmpp_client2 = init_xmpp_clients() - check_receive_message(xmpp_client, xmpp_client2) - def init_xmpp_clients(): """ Initializes the xmpp_clients and connects them @@ -53,11 +40,11 @@ def init_xmpp_clients(): waitForConnection(xmpp_client2, True) return xmpp_client, xmpp_client2 -def check_connect(xmpp_client, xmpp_client2): +def test_connect(): """ - Check for xmpp.XMPPClient.connect_server and disconnect_server + Test for xmpp.XMPPClient.connect_server and disconnect_server """ - + xmpp_client, xmpp_client2 = init_xmpp_clients() eq_(xmpp_client.is_connected(), True) eq_(xmpp_client2.is_connected(), True) @@ -66,11 +53,11 @@ def check_connect(xmpp_client, xmpp_client2): xmpp_client2.disconnect_server() waitForConnection(xmpp_client2, False) -def check_send_message(xmpp_client, xmpp_client2): +def test_send_message(): """ - Check for xmpp.XMPPClient.send_message + Test for xmpp.XMPPClient.send_message """ - + xmpp_client, xmpp_client2 = init_xmpp_clients() crypto_shell = xmpp_client.xmpp.parent waitForConnection(xmpp_client, True) waitForConnection(xmpp_client2, True) @@ -126,11 +113,11 @@ def assertDisconnect(xmpp_client): xmpp_client.disconnect_server() waitForConnection(xmpp_client, False) -def check_receive_message(xmpp_client, xmpp_client2): +def test_receive_message(): """ - Check for CryptoXMPP.message + Test for CryptoXMPP.message (receive message) """ - + xmpp_client, xmpp_client2 = init_xmpp_clients() crypto_shell2 = xmpp_client2.xmpp.parent # Assert connected From a56644f8aded52d329e2424b6ad6d10d0d92782c Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 21:27:12 +0100 Subject: [PATCH 87/95] Removed left-over debugging [skip ci] --- cryptoim/xmpp.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index c3fd258..c7ec8cf 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -44,7 +44,6 @@ def __init__(self, jid, password, parent): if '/' in jid: jid = jid[:jid.index('/')] jid += '/cryptoim' - print('JID: ', jid) sleekxmpp.ClientXMPP.__init__(self, jid, password) # The session_start event will be triggered when @@ -175,7 +174,7 @@ class XMPPClient(object): xmpp = None - def __init__(self, jid, password, parent, loglevel=logging.DEBUG): + def __init__(self, jid, password, parent, loglevel=logging.CRITICAL): """ Initializes the ClientXMPP, logging, etc """ From e8232bfd981f561a7b57e095b5ad1d9ceaaa6303 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 21:36:48 +0100 Subject: [PATCH 88/95] Edited command documentation --- cryptoim/cli.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 9b1bd00..ece3f54 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -75,7 +75,7 @@ def do_exit(self, arg): def do_q(self, arg): """ - Alias for quit + Usage: q (Exit) """ self.do_exit(arg) @@ -87,7 +87,8 @@ def emptyline(self): # -- xmpp commands -- def do_connect(self, arg): """ - connect JID PASSWORD or connect CONNECTION_NAME + Usage: connect or connect + (Connects to your JID, if you dont have connection use addconnection) """ splitted = arg.split(' ') @@ -123,7 +124,7 @@ def do_connect(self, arg): def do_disconnect(self, arg): """ - Disconnect + Usage: Disconnect """ if not self.xmpp_client or not self.xmpp_client.is_connected(): @@ -166,7 +167,7 @@ def do_addconnection(self, arg): def do_removeconnection(self, arg): """ - Usage removeconnection + Usage: removeconnection """ splitted = arg.split(' ') @@ -186,13 +187,14 @@ def do_removeconnection(self, arg): def do_s(self, arg): """ - send alias + Usage: s or s + (Shorthand for send) """ return(self.do_send(arg)) def do_send(self, arg): """ - send toJID or username msg + Usage: send or send """ if not self.xmpp_client or not self.xmpp_client.is_in_session(): self.print_cmd('Connect first!') @@ -234,7 +236,7 @@ def do_send(self, arg): def do_addfriend(self, arg): """ - addfriend name jid + Usage: addfriend """ splitted = arg.split(' ') @@ -253,7 +255,7 @@ def do_addfriend(self, arg): def do_removefriend(self, arg): """ - removefriend name + Usage: removefriend """ splitted = arg.split(' ') @@ -272,7 +274,7 @@ def do_removefriend(self, arg): def do_chat(self, arg): """ - chat JID + Usage: chat """ if not arg: self.print_cmd('Usage: chat or chat ') @@ -309,7 +311,7 @@ def do_friendlist(self, arg): def do_stopchat(self, arg): """ - stopchat + Usage: stopchat (Stops current chat) """ if not self.current_chat: self.print_cmd('No open chat to close.') From 468e478d24e9f1194a227f017840d57b920805e7 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 21:43:04 +0100 Subject: [PATCH 89/95] Fixed up README --- README | 16 +++++++++------- README.rst | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README b/README index e2e21e1..248eec7 100644 --- a/README +++ b/README @@ -26,11 +26,6 @@ A secure* instant messenger written in Python out of sheer fun. \* not really secure (at least not yet) -Info -==== - -CryptoIM uses `semantic versioning `_ and branching model similar to `this `_. - Building ======== @@ -42,19 +37,21 @@ Building 4. To **clean**, run: ``python setup.py clean --all`` +5. To **edit** connection options, edit the ``main.cfg`` file. + Building on Linux ================= * Make sure to **install** these packages using your package manager: ``python`` and ``python-setuptools`` -* Follow steps 1. and 2. from **Building** +* Follow steps 1., 2. and 5. from **Building** Building on Windows =================== * **Install** `Python `_ and `Setuptools `_. -* Follow steps 1. and 2. from **Building** +* Follow steps 1., 2. and 5. from **Building** Contributing ============ @@ -74,6 +71,11 @@ Here are some ways *you* can contribute: * by closing `issues `_ * by reviewing patches +Info +==== + +CryptoIM uses `semantic versioning `_ and branching model similar to `this `_. + Submitting an Issue =================== diff --git a/README.rst b/README.rst index e2e21e1..248eec7 100644 --- a/README.rst +++ b/README.rst @@ -26,11 +26,6 @@ A secure* instant messenger written in Python out of sheer fun. \* not really secure (at least not yet) -Info -==== - -CryptoIM uses `semantic versioning `_ and branching model similar to `this `_. - Building ======== @@ -42,19 +37,21 @@ Building 4. To **clean**, run: ``python setup.py clean --all`` +5. To **edit** connection options, edit the ``main.cfg`` file. + Building on Linux ================= * Make sure to **install** these packages using your package manager: ``python`` and ``python-setuptools`` -* Follow steps 1. and 2. from **Building** +* Follow steps 1., 2. and 5. from **Building** Building on Windows =================== * **Install** `Python `_ and `Setuptools `_. -* Follow steps 1. and 2. from **Building** +* Follow steps 1., 2. and 5. from **Building** Contributing ============ @@ -74,6 +71,11 @@ Here are some ways *you* can contribute: * by closing `issues `_ * by reviewing patches +Info +==== + +CryptoIM uses `semantic versioning `_ and branching model similar to `this `_. + Submitting an Issue =================== From 80e5f4e0822b155501394d698ef684520d400b3d Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 21:44:08 +0100 Subject: [PATCH 90/95] typo --- cryptoim/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index ece3f54..b38e50b 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -124,7 +124,7 @@ def do_connect(self, arg): def do_disconnect(self, arg): """ - Usage: Disconnect + Usage: disconnect """ if not self.xmpp_client or not self.xmpp_client.is_connected(): From efd12742a05bd9e109379c730e7ad6475c1d5f78 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 21:58:41 +0100 Subject: [PATCH 91/95] Pre release bugs --- cryptoim/cli.py | 1 + cryptoim/xmpp.py | 2 +- main.cfg | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index b38e50b..50f6f77 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -119,6 +119,7 @@ def do_connect(self, arg): self.xmpp_client = cryptoim.xmpp.XMPPClient(conn_jid, conn_pass, self) self.xmpp_client.connect_server() + self.print_cmd('Connecting...') return self.return_cli(True) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index c7ec8cf..79baf64 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -106,7 +106,7 @@ def start(self, event): self.send_presence() self.get_roster() self.in_session = True - self.parent.print_debug('Session started!') + self.parent.print_cmd('Connected!') def message(self, msg): """ diff --git a/main.cfg b/main.cfg index 8f47e70..c33a720 100644 --- a/main.cfg +++ b/main.cfg @@ -1,4 +1,4 @@ -[cryptoim1] +[cryptoim] username = cryptoim host = jabber.de password = crypto_test @@ -9,6 +9,6 @@ host = jabber.de password = crypto_test2 [friends] -cryptoim1 = cryptoim1@jabber.de +cryptoim = cryptoim@jabber.de cryptoim2 = cryptoim2@jabber.de From 210f5fc18b631612fa606d55b5365be5817a3732 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 22:05:07 +0100 Subject: [PATCH 92/95] Minor refactoring --- cryptoim/cli.py | 8 ++++---- cryptoim/xmpp.py | 1 - tests/TestXMPP.py | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 50f6f77..27fd955 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -87,7 +87,7 @@ def emptyline(self): # -- xmpp commands -- def do_connect(self, arg): """ - Usage: connect or connect + Usage: connect or connect (Connects to your JID, if you dont have connection use addconnection) """ splitted = arg.split(' ') @@ -125,7 +125,7 @@ def do_connect(self, arg): def do_disconnect(self, arg): """ - Usage: disconnect + Usage: disconnect """ if not self.xmpp_client or not self.xmpp_client.is_connected(): @@ -188,8 +188,8 @@ def do_removeconnection(self, arg): def do_s(self, arg): """ - Usage: s or s - (Shorthand for send) + Usage: s or s + (Shorthand for send) """ return(self.do_send(arg)) diff --git a/cryptoim/xmpp.py b/cryptoim/xmpp.py index 79baf64..dfbb588 100644 --- a/cryptoim/xmpp.py +++ b/cryptoim/xmpp.py @@ -27,7 +27,6 @@ import logging import sleekxmpp -import random import cryptoim.encryptor_core as encryptor import cryptoim.decryptor_core as decryptor diff --git a/tests/TestXMPP.py b/tests/TestXMPP.py index 5698fa4..81ef6b7 100644 --- a/tests/TestXMPP.py +++ b/tests/TestXMPP.py @@ -84,7 +84,7 @@ def test_send_message(): def test_not_connect(): """ - Check for xmpp.XMPPClient.connect_server and disconnect_server + Failproofing test for xmpp.XMPPClient.connect_server and disconnect_server """ crypto_shell = CryptoShell('main.cfg') From 999a5ef18b88ea0f4279ce4e0b0f4a3407458551 Mon Sep 17 00:00:00 2001 From: mators11 Date: Sun, 26 Jan 2014 22:10:36 +0100 Subject: [PATCH 93/95] Fixing stuff before release --- cryptoim/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index 27fd955..a9d271d 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -211,7 +211,7 @@ def do_send(self, arg): message = ' '.join(splitted) else: # if chat mode off - if not sanit_arg_count(splitted, 1, 2): + if sanit_arg_count_exact(splitted, 0): #input: send (empty argument) self.print_cmd('Usage: send or send ') return self.return_cli(False) @@ -275,7 +275,7 @@ def do_removefriend(self, arg): def do_chat(self, arg): """ - Usage: chat + Usage: chat or chat """ if not arg: self.print_cmd('Usage: chat or chat ') From 4b198c636cb83df87a67580c9cbe511e12a12869 Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 22:17:25 +0100 Subject: [PATCH 94/95] Fixed tests after config file change --- tests/TestCli.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/TestCli.py b/tests/TestCli.py index 8cd08c5..7d5917e 100644 --- a/tests/TestCli.py +++ b/tests/TestCli.py @@ -29,8 +29,8 @@ def test_connect_disconnect(): cshell.test_mode = True eq_(cshell.do_connect(''), False) eq_(cshell.do_connect('invalid number of arguments'), False) - eq_(cshell.do_connect('cryptoim1'), True) - eq_(cshell.do_connect('cryptoim1'), False) + eq_(cshell.do_connect('cryptoim'), True) + eq_(cshell.do_connect('cryptoim'), False) eq_(cshell.do_disconnect('random_string'), True) # branch coverage eq_(cshell.do_disconnect(''), False) @@ -53,15 +53,15 @@ def test_send(): cshell = CryptoShell('main.cfg') cshell.test_mode = True - eq_(cshell.do_send('cryptoim1 message before connection'), False) + eq_(cshell.do_send('cryptoim message before connection'), False) eq_(cshell.do_connect('cryptoim2'), True) TestXMPP.waitForSession(cshell.xmpp_client, True) eq_(cshell.do_send(''), False) eq_(cshell.onecmd(''), None) # just empty line command - emptyline() test eq_(cshell.do_send('shouldntwork message'), False) - eq_(cshell.do_send('cryptoim1 message'), True) + eq_(cshell.do_send('cryptoim message'), True) eq_(cshell.do_send('cryptoim2@jabber.de message'), True) - eq_(cshell.do_send('cryptoim1'), False) + eq_(cshell.do_send('cryptoim'), False) cshell.do_disconnect('') def test_chat_stopchat_exit(): @@ -69,8 +69,8 @@ def test_chat_stopchat_exit(): cshell = CryptoShell('main.cfg') cshell.test_mode = True eq_(cshell.do_chat(''), False) - eq_(cshell.do_chat('cryptoim1@jabber.de'), True) - eq_(cshell.do_chat('cryptoim1'), True) + eq_(cshell.do_chat('cryptoim@jabber.de'), True) + eq_(cshell.do_chat('cryptoim'), True) eq_(cshell.do_chat('shouldntwork'), False) eq_(cshell.do_connect('cryptoim2'), True) TestXMPP.waitForSession(cshell.xmpp_client, True) From 1e07af15f1845ffd438c9bdc4ddfe7f464c58c6f Mon Sep 17 00:00:00 2001 From: Ondrej Skopek Date: Sun, 26 Jan 2014 22:29:06 +0100 Subject: [PATCH 95/95] Minor logical fix --- cryptoim/cli.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cryptoim/cli.py b/cryptoim/cli.py index a9d271d..e0c9f0a 100644 --- a/cryptoim/cli.py +++ b/cryptoim/cli.py @@ -211,17 +211,14 @@ def do_send(self, arg): message = ' '.join(splitted) else: # if chat mode off - if sanit_arg_count_exact(splitted, 0): - #input: send (empty argument) - self.print_cmd('Usage: send or send ') - return self.return_cli(False) if self.config_find(splitted[0]): # if sending to friend recipient = self.config_find(splitted[0]) elif sanit_is_jid(splitted[0]): # if sending to jid recipient = splitted[0] else: # error: username not defined or jid isnt jid - self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') + if splitted[0]: + self.print_cmd(splitted[0] + ' is not recognized. Please enter valid JID or username.') self.print_cmd('Usage: send or send ') return self.return_cli(False)