Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation is nonexistant or difficult to find #33

Open
louist87 opened this issue Jun 11, 2013 · 18 comments
Open

Documentation is nonexistant or difficult to find #33

louist87 opened this issue Jun 11, 2013 · 18 comments

Comments

@louist87
Copy link

I'm hoping to be able to use this module, but I'm having trouble finding documentation. It would be nice to provide links to relevant documentation, improve the docstrings of functions and modules, and also provide a few simple "getting started" examples in the README.

@afflux
Copy link
Contributor

afflux commented Jun 11, 2013

It's nonexistent really. I'm fairly busy currently, so don't expect this to change in the next few months. Sorry about that.

@louist87
Copy link
Author

@afflux, I totally understand, so no need to apologize! Do you perhaps have some snippets or examples I could sift through?

@afflux
Copy link
Contributor

afflux commented Jun 11, 2013

There are two implementations: my own gajim-otr and mmb's/koolfy's weechat-otr. I believe both are not too difficult to get into.

@jcea
Copy link

jcea commented Jun 18, 2013

I have the same issue. Evaluating this library and no documentation at all :-(.

@darrikmazey
Copy link

@afflux i just used your library in my own chat client, and successfully got it working. i will put up a tutorial in the next few days, if you want to link to it and it helps people out. i also found the lack of docs difficult to navigate, but your gajim implementation and a bunch of NotImplemented exceptions saw me through.

@louist87
Copy link
Author

@darrikmazey That would be awesome if you could post a tutorial. I took a look at afflux's gajim-otr and the weechat-otr examples he posted, but I'm far too unfamiliar with XMPP/OTR to navigate them by myself.

If you do write a tutorial, I would greatly appreciate it if you posted a link in this comment thread! Thanks in advance! In return, I'd be happy to add some docstrings as soon as I get the general gist of what's going on!

@darrikmazey
Copy link

I hope this is somewhat useful. Feel free to message me directly if you have any questions or if I can help explain any of it. Just don't mistake my getting this functioning for any actual expertise. ;)

http://blog.darmasoft.net/2013/06/30/using-pure-python-otr.html

@afflux
Copy link
Contributor

afflux commented Jun 30, 2013

@darrikmazey, I had a quick look and didn't catch any obvious issues. Thanks a lot, this should provide some very useful leads for others.

@louist87
Copy link
Author

@darrikmazey Awesome! I'll probably look at this tomorrow. I'll be sure to let you know if anything is unclear =)

@mathieui
Copy link
Contributor

mathieui commented Jul 3, 2013

FYI, I am in the process of writing an OTR plugin for the poezio XMPP client, and @darrikmazey’s post and the gajim plugin were a great help. I currently have the basic features working (start/refresh/end session and send/receive messages) and will publish the code when I have everything I want (that’ll be one more example to look at). Hopefully, I will also have time to write a bit of documentation and comments :).

@louist87
Copy link
Author

louist87 commented Jul 4, 2013

@MatthieuI, Great! I look forward to it!

On Wed 03 Jul 2013 11:47:29 PM CEST, mathieui wrote:

FYI, I am in the process of writing an OTR plugin for the poezio XMPP
client, and @darrikmazey https://github.com/darrikmazey’s post and
the gajim plugin were a great help. I currently have the basic
features working (start/refresh/end session and send/receive messages)
and will publish the code when I have everything I want (that’ll be
one more example to look at). Hopefully, I will also have time to
write a bit of documentation and comments :).


Reply to this email directly or view it on GitHub
#33 (comment).

@louist87
Copy link
Author

louist87 commented Jul 7, 2013

@darrikmazey I'm struggling to get your example running and i was wondering if you or @afflux could give me any hints.

Do I have to do anything in particular to initiate a private conversation? I'm testing this with pidgin-OTR, and when I try to start a conversation it just sort of hangs at the request. I ran pdb to take a look at the state of the context and noticed that potr.context.STATE_ENCRYPTED is never set.

I tried explicitly calling the setState method, to no avail. What am I missing?

@darrikmazey, your code appears to be much more bare-bones than the gajim-otr plugin. Would you mind posting a full, working example if it's not too much trouble? I'm really struggling, here =/

@mathieui
Copy link
Contributor

mathieui commented Jul 7, 2013

@louist87 the example is a start, it doesn’t cover session initiation from what I saw. To start/refresh a session you have to get the body to send with context.sendMessage(0, b'?OTRv?') and then send the value returned with your XMPP lib. At least that’s what the gajim plugin does, and it seems to work.

Ending a session, however, is a simple context.disconnect().

A good read is also http://www.cypherpunks.ca/otr/Protocol-v3-4.0.0.html (starting from the part “The Protocol State Machine”), it helps for mapping the potr exceptions to what happens, among other things.

@louist87
Copy link
Author

louist87 commented Jul 7, 2013

@mathieui, thanks for the additional resources -- this is finally starting to make sense.

@afflux, @mathieui, From my own reading of gajim-otr's otrmodule.py, I got the sense that the appdata kwarg in Context.sendMessage was intended as a means to reference external resources from within Context.inject. I tried passing my XMPP library's message sending function through the appdata parameter, but every time inject is executed, appdata always contains a NoneType. Could somebody please explain what's going on?

Thanks, and again, sorry for my slow learning rate =)

@louist87
Copy link
Author

louist87 commented Jul 7, 2013

Alright, I'm making slow progress, but I think it might be helpful if I provided some code. At this point, I'm getting POTR to exchange OTR protocol messages with my pidgin client, but after a dozen or so exchanges, I get an InvalidParameter error. For clarity, I'm not exchanging encrypted communications but protocol state information prefixed with ?OTR. I can't get beyond the ensuing error.

My example is a simple echo bot using Twisted/wokkel. The plaintext echo works well, but that's it.
Below is the onMessage callback, which executes every time the wokkel client receives a stanza:

    def onMessage(self, msg):
        contxt = self.context_manager[unicode(msg['from'])]
        encrypted = True
        try:
            # attempt to pass the message through *potr.context.Context.receiveMessage*
            # there are a couple of possible cases
            res = contxt.receiveMessage(unicode(msg.body))
        except potr.context.UnencryptedMessage, message:
            # potr raises an UnencryptedMessage exception when a message is unencrypted but the context is encrypted
            # this indicates a plaintext message came through a supposedly encrypted channel
            # it is appropriate here to warn your user!
            encrypted = False

        if encrypted == False:
            if msg['type'] in ('chat', 'normal'):
                # here is where you handle plain text messages
                resp = "[PLAINTEXT]  Echo:  {0}".format(unicode(msg.body))
                self.reply(to=msg['from'], body=resp)  # echo
        else:
            print "****ENCRYPTED*****"
            # import pdb; pdb.set_trace()
            if res[0] is not None:
                print "***have res***"
                # here is where you handle decrypted messages.
                # receiveMessage() will return a tuple, the first part of which
                # will be the decrypted message

                resp = "[ENCRYPTED]  Echo:  {0}".format(res[0])
                qstr = context.sendMessage(0, resp)  # echo
            else:
                # initialization request (?)
                print "no res...", msg['from'], msg.body
                # import pdb; pdb.set_trace()
                qstr = contxt.sendMessage(0, b'?OTRv23?')
                self.reply(to=msg['from'], body=qstr)

This is clearly buggy code because I'm always sending b'?OTRv23?' whenever I receive an OTR message, but I'm not sure how I should be doing things. @mathieui had mentioned that I should do tihs once in order to then send the return value of the sendMessage(0, b'?OTRv23?') call to the peer (see last two lines).

But then what? Should I expect a change in contxt.state? I don't observe any.

Also, here is a partial traceback, which may be somewhat useful:

File "/home/louist/Desktop/potr_test/protocol.py", line 32, in onMessage
        res = contxt.receiveMessage(unicode(msg.body))
      File "/home/louist/.local/lib/python2.7/site-packages/potr/context.py", line 204, in receiveMessage
        self.crypto.handleAKE(message, appdata=appdata)
      File "/home/louist/.local/lib/python2.7/site-packages/potr/crypt.py", line 282, in handleAKE
        outMsg = self.ake.handleRevealSig(inMsg)
      File "/home/louist/.local/lib/python2.7/site-packages/potr/crypt.py", line 412, in handleRevealSig
        raise InvalidParameterError
    potr.crypt.InvalidParameterError: 

I apologize for being dense, but even after reading through mathieui's code, the gajim-otr code and the OTR protocol overview, this API remains very cryptic. I suspect I'm overlooking some simple but fundamental concept, here...

@afflux
Copy link
Contributor

afflux commented Jul 7, 2013

As for the appdata, you should make sure that you add that parameter to receiveMessage(), sendMessage(), disconnect(), and smp*() if you use it.

Also, don't pass unicode objects in the lib. It operates only on (byte-) strings, the encoding is defined to be UTF-8.

In general: as soon as a protocol message (such as for the AKE) is received in receiveMessage, the lib automatically injects the appropriate response, no need for your application to respond to that. receiveMessage will return (None, ...) if the incoming message is to be ignored. In this case, don't send anything. Responding with b"OTRv23" will lead to problems, since you initiate another AKE in between a running one. (However, it should simply lead to a loop of AKEs, not crash. If it crashes, it's almost certainly bug.)

For further debugging, set your loglevel higher. Add this to your application's initialization:

import logging
logging.getLogger('potr').setLevel(logging.DEBUG)

@louist87
Copy link
Author

louist87 commented Jul 7, 2013

@afflux, okay I got it to work! Thank you for your help! I have no idea what I did wrong the first few times, as @mathieui's tutorial is pretty much spot-on. I'll continue playing with it and then start adding docstrings.

Expect a pull request over the next few weeks ;-)

Many thanks, guys!

@mikegogulski
Copy link

Thanks to Kjell and the other commenters for their work here.

For more documentation-via-code-samples, see https://github.com/mikegogulski/python-xmpplogginghandler

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants