Ejemplo n.º 1
0
def introduction_cmd(parsed_args, buf):
    account = accounts.get_my_account()

    # Prepare the metadata
    server = util.get_local_server(buf)

    # If a nick is provided, introduce to that nick. Otherwise, check if we are
    # currently having a private conversation with another nick, and if so
    # introduce to that nick.
    if len(parsed_args) >= 2:
        target_nick = parsed_args[1]
    else:
        if otrlib.buffer_is_private(buf):
            target_nick = util.get_local_channel(buf)
        else:
            util.control_msg(
                "Bad introduction command! Can't introduce yourself to a channel!"
            )
            raise flute.FluteCommandError

    introduction.send_introduction(account, target_nick, server, buf)

    util.flute_channel_msg(buf,
                           "[Introduced ourselves to %s.]" % target_nick,
                           color="green")
Ejemplo n.º 2
0
Archivo: flute.py Proyecto: h1r00/flute
def user_got_kicked(irc_msg, server):
    """A user got kicked from a channel we are in. Remove them from the member list."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    channel = parsed['channel']
    command = parsed['command']
    target = parsed['target']

    assert(command.upper() == "KICK")

    util.debug("%s got kicked from %s by %s." % (target, channel, nick))

    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No flute room at %s. Sending plaintext." % channel)
        return

    try:
        flute_room.remove_member_and_rekey(target)
    except room.NoSuchMember:
        util.control_msg("A non-existent nick left the room. WTF.") # XXX i think this also catches ourselves
Ejemplo n.º 3
0
Archivo: flute.py Proyecto: h1r00/flute
def send_key_transport_packet(flute_room):
    util.debug("I'm captain in %s: Membership changed. Refreshing message key." % flute_room.name)

    account = accounts.get_my_account()
    channel = flute_room.name
    server = flute_room.server

    assert(flute_room.i_am_captain) # Only captains should be here!

    # Prepare necessary packet fields.
    captain_identity_key = account.get_identity_pubkey()
    captain_transport_key = flute_room.get_room_participant_pubkey() # XXX maybe special func for captain's key?

    # XXX get_message_key_array also *generates* a new key. rename.
    message_key_array, key_transport_counter = flute_room.get_message_key_array_and_counter()
    # our array must be a multiple of 72 bytes
    assert(len(message_key_array) % MESSAGE_KEY_ARRAY_CELL_LEN == 0)
    # Encode new key id as big endian unsigned integer
    new_message_key_counter = struct.pack('>I', key_transport_counter)

    # Format the packet and sign it.
    packet_fields = captain_identity_key + captain_transport_key + new_message_key_counter + \
                    message_key_array
    packet_signed = account.sign_msg_with_identity_key(packet_fields)

    payload_b64 = base64.b64encode(packet_signed)

    flute_room.status = "bootstrapping"
    util.debug("Sending KEY_TRANSPORT in %s!" % channel)

    msg_type = KEY_TRANSPORT_OPCODE
    msg = msg_type + payload_b64
    transport.send_flute_privmsg(server, channel, msg)

    flute_room.status = "done"
Ejemplo n.º 4
0
Archivo: flute.py Proyecto: h1r00/flute
def user_left_channel(irc_msg, server):
    """A user left a channel we are in. Remove them from the channel if we are captain."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    channel = parsed['channel']
    command = parsed['command']

    assert(command.upper() == "PART")

    util.debug("Received %s from %s in channel %s." % (command, nick, channel))

    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No flute room at %s. Sending plaintext." % channel)
        return

    try:
        flute_room.remove_member_and_rekey(nick)
    except room.NoSuchMember:
        util.control_msg("A non-existent nick left the room. WTF.") # XXX i think this also catches ourselves
        return
Ejemplo n.º 5
0
Archivo: flute.py Proyecto: h1r00/flute
def send_room_join(channel, server, buf):
    """Send ROOM_JOIN message."""
    account = accounts.get_my_account()

    # Don't send ROOM_JOIN to empty channel. No one to handle it.
    if util.irc_channel_is_empty(channel, server):
        util.flute_channel_msg(buf, "Can't 'join-room' in an empty channel!", "red")
        util.flute_channel_msg(buf, "Do '/flute start-room' if you want to start a new flute room instead.", "red")
        return

    # First of all, register this new room.
    flute_room = account.register_flute_room(channel, server, buf)

    # Get the keys to be placed in the packet
    my_pub_key = account.get_identity_pubkey()
    my_room_key = flute_room.get_room_participant_pubkey()

    # Sign them
    packet_fields = my_pub_key + my_room_key
    packet_signed = account.sign_msg_with_identity_key(packet_fields)

    payload_b64 = base64.b64encode(packet_signed)

    msg = ROOM_JOIN_OPCODE + payload_b64
    transport.send_flute_privmsg(server, channel, msg)

    util.flute_channel_msg(buf, "Requested to join room %s..." % channel)
Ejemplo n.º 6
0
def send_key_transport_packet(viola_room):
    util.debug("I'm captain in %s: Membership changed. Refreshing message key." % viola_room.name)

    account = accounts.get_my_account()
    channel = viola_room.name
    server = viola_room.server

    assert(viola_room.i_am_captain) # Only captains should be here!

    # Prepare necessary packet fields.
    captain_identity_key = account.get_identity_pubkey()
    captain_transport_key = viola_room.get_room_participant_pubkey() # XXX maybe special func for captain's key?
    message_key_array = viola_room.get_message_key_array() # XXX also generates key. rename.
    # our array must be a multiple of 72 bytes
    assert(len(message_key_array) % MESSAGE_KEY_ARRAY_CELL_LEN == 0)

    # Sign all previous fields.
    packet_fields = captain_identity_key + captain_transport_key + message_key_array
    packet_signed = account.sign_msg_with_identity_key(packet_fields)

    payload_b64 = base64.b64encode(packet_signed)

    viola_room.status = "bootstrapping"
    util.debug("Sending KEY_TRANSPORT in %s!" % channel)

    msg = KEY_TRANSPORT_OPCODE + payload_b64
    transport.send_viola_privmsg(server, channel, msg)

    viola_room.status = "done"
Ejemplo n.º 7
0
def send_room_join(channel, server, buf):
    """Send ROOM_JOIN message."""
    account = accounts.get_my_account()

    # Don't send ROOM_JOIN to empty channel. No one to handle it.
    if util.irc_channel_is_empty(channel, server):
        util.viola_channel_msg(buf, "Can't 'join-room' in an empty channel!", "red")
        util.viola_channel_msg(buf, "Do '/viola start-room' if you want to start a new viola room instead.", "red")
        return

    # First of all, register this new room.
    viola_room = account.register_viola_room(channel, server, buf)

    # Get the keys to be placed in the packet
    my_pub_key = account.get_identity_pubkey()
    my_room_key = viola_room.get_room_participant_pubkey()

    # Sign them
    packet_fields = my_pub_key + my_room_key
    packet_signed = account.sign_msg_with_identity_key(packet_fields)

    payload_b64 = base64.b64encode(packet_signed)

    msg = ROOM_JOIN_OPCODE + payload_b64
    transport.send_viola_privmsg(server, channel, msg)

    util.viola_channel_msg(buf, "Requested to join room %s..." % channel)
Ejemplo n.º 8
0
def user_left_channel(irc_msg, server):
    """A user left a channel we are in. Remove them from the channel if we are captain."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    channel = parsed['channel']
    command = parsed['command']

    assert(command.upper() == "PART")

    util.debug("Received %s from %s in channel %s." % (command, nick, channel))

    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No viola room at %s. Sending plaintext." % channel)
        return

    try:
        viola_room.remove_member_and_rekey(nick)
    except room.NoSuchMember:
        util.control_msg("A non-existent nick left the room. WTF.") # XXX i think this also catches ourselves
        return
Ejemplo n.º 9
0
def user_got_kicked(irc_msg, server):
    """A user got kicked from a channel we are in. Remove them from the member list."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    channel = parsed['channel']
    command = parsed['command']
    target = parsed['target']

    assert(command.upper() == "KICK")

    util.debug("%s got kicked from %s by %s." % (target, channel, nick))

    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No viola room at %s. Sending plaintext." % channel)
        return

    try:
        viola_room.remove_member_and_rekey(target)
    except room.NoSuchMember:
        util.control_msg("A non-existent nick left the room. WTF.") # XXX i think this also catches ourselves
Ejemplo n.º 10
0
def user_quit_irc(irc_msg, server):
    """A user quit IRC. Remove them form the member list of any channel they are in."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    command = parsed['command']

    assert(command.upper() == "QUIT")

    account.user_quit_irc(nick)
Ejemplo n.º 11
0
def handle_room_message_packet(packet_payload, parsed, server):
    sender_host = parsed['from']
    sender_nick = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not channel: # XXX functionify
        util.debug("Received ROOM_MESSAGE not in channel from %s. Ignoring." % sender_host)
        return ""

    # Is this channel a viola room for us?
    # XXX Code duplication
    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received ROOM_MESSAGE in a regular channel (%s). Ignoring." % channel)
        buf = util.get_current_buffer() # XXX weechat API shouldn't polute viola.py
        util.viola_channel_msg(buf,
                               "[You hear a viola screeching... Please do '/viola join-room' to join the session.]",
                               "lightcyan")
        return ""

    try:
        room_message_key = viola_room.get_room_message_key()
    except room.NoMessageKey:
        util.debug("Received ROOM_MESSAGE in %s but no message key. Ignoring." % channel) # XXX ???
        util.viola_channel_msg(viola_room.buf,
                               "[You hear a viola screeching... Please do '/viola join-room' to join the session.]",
                               "grey")
        return ""

    payload = base64.b64decode(packet_payload)

    if len(payload) <= 64:
        raise IncompletePacket

    util.debug("Attempting to decrypt ROOM_MESSAGE in %s" % channel)

    # Get packet fields
    signature = payload[:SIG_LEN]
    message_ciphertext = payload[SIG_LEN:]

    # XXX catch decrypt exception
    try:
        plaintext = crypto.decrypt_room_message(room_message_key, message_ciphertext)
    except nacl.exceptions.CryptoError:
        util.viola_channel_msg(viola_room.buf,
                               "Could not decrypt message sent in room. Maybe old key. Try rejoining the channel.",
                               "red") # XXX this won't work
        return ""

    msg_in = otrlib.build_privmsg_in(sender_host, channel, plaintext)
    return msg_in[0] + '⚷' + msg_in[1:]
Ejemplo n.º 12
0
Archivo: flute.py Proyecto: h1r00/flute
def user_quit_irc(irc_msg, server):
    """A user quit IRC. Remove them form the member list of any channel they are in."""
    account = accounts.get_my_account()

    parsed = util.parse_irc_quit_kick_part(irc_msg, server)

    nick = parsed['from_nick']
    command = parsed['command']

    assert(command.upper() == "QUIT")

    account.user_quit_irc(nick)
Ejemplo n.º 13
0
Archivo: flute.py Proyecto: h1r00/flute
def handle_room_message_packet(packet_payload, parsed, server):
    sender_host = parsed['from']
    sender_nick = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not channel: # XXX functionify
        util.debug("Received ROOM_MESSAGE not in channel from %s. Ignoring." % sender_host)
        return ""

    # Is this channel a flute room for us?
    # XXX Code duplication
    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received ROOM_MESSAGE in a regular channel (%s). Ignoring." % channel)
        buf = util.get_current_buffer() # XXX weechat API shouldn't polute flute.py
        util.flute_channel_msg(buf,
                               "[Tootie-too! What an annoying sound! Do '/flute join-room' to join the flute session.]",
                               color="lightcyan")
        return ""


    payload = base64.b64decode(packet_payload)

    if len(payload) <= 64:
        raise IncompletePacket

    util.debug("Attempting to decrypt ROOM_MESSAGE in %s" % channel)

    # Get packet fields
    signature = payload[:SIG_LEN]
    message_ciphertext = payload[SIG_LEN:]

    # Decrypt ciphertext
    try:
        plaintext = flute_room.decrypt_room_message(message_ciphertext)
    except room.MessageDecryptFail:
        util.flute_channel_msg(flute_room.buf,
                               "Could not decrypt message sent in room. Maybe old key. Try rejoining the channel.",
                               color="red")
        return ""

    if not plaintext:
        return ""

    msg = "[ENCRYPTED] %s" % plaintext
    msg_in = otrlib.build_privmsg_in(sender_host, channel, msg)
    return msg_in
Ejemplo n.º 14
0
Archivo: flute.py Proyecto: h1r00/flute
def start_flute_room(channel, server, buf):
    """Start a Flute room in 'channel'@'server' on weechat buffer 'buf'."""
    account = accounts.get_my_account()
    util.debug("Starting a flute session in %s." % channel)

    # Make sure we are the only nick in the channel otherwise someone else
    # might already be captaining.
    if not util.irc_channel_is_empty(channel, server):
        util.flute_channel_msg(buf, "Can only start flute session in empty channel!", "red")
        util.flute_channel_msg(buf, "Try '/flute join-room' in this channel instead.", "red")
        return

    account.register_flute_room(channel, server, buf, i_am_captain=True)

    util.flute_channel_msg(buf, "We are now the captain in room %s!" % channel)
Ejemplo n.º 15
0
def start_viola_room(channel, server, buf):
    """Start a Viola room in 'channel'@'server' on weechat buffer 'buf'."""
    account = accounts.get_my_account()
    util.debug("Starting a viola session in %s." % channel)

    # Make sure we are the only nick in the channel otherwise someone else
    # might already be captaining.
    if not util.irc_channel_is_empty(channel, server):
        util.viola_channel_msg(buf, "Can only start viola session in empty channel!", "red")
        util.viola_channel_msg(buf, "Try '/viola join-room' in this channel instead.", "red")
        return

    account.register_viola_room(channel, server, buf, i_am_captain=True)

    util.viola_channel_msg(buf, "We are now the captain in room %s!" % channel)
Ejemplo n.º 16
0
def trust_key_cmd(parsed_args, buf):
    nickname = parsed_args[1]
    hexed_key = parsed_args[2]

    # Check for illegal nickname chars
    if not nickname.isalnum():
        util.control_msg("Invalid nickname: %s" % nickname)
        raise flute.FluteCommandError

    if len(hexed_key) != 64 or not util.is_hex(hexed_key):
        util.control_msg("Invalid key value: %s" % hexed_key)
        raise flute.FluteCommandError

    account = accounts.get_my_account()
    account.trust_key(nickname, hexed_key)
Ejemplo n.º 17
0
def trust_key_cmd(parsed_args, buf):
    nickname = parsed_args[1]
    hexed_key = parsed_args[2]

    # Check for illegal nickname chars
    if not nickname.isalnum():
        util.control_msg("Invalid nickname: %s" % nickname)
        raise flute.FluteCommandError

    if len(hexed_key) != 64 or not util.is_hex(hexed_key):
        util.control_msg("Invalid key value: %s" % hexed_key)
        raise flute.FluteCommandError

    account = accounts.get_my_account()
    account.trust_key(nickname, hexed_key)
Ejemplo n.º 18
0
Archivo: flute.py Proyecto: h1r00/flute
def rekey_room(metadata):
    """Extract channel/server from metadata and rekey flute room."""

    # Get channel/server from metadata
    splited_room_id = metadata.split(',')
    room = splited_room_id[0]
    server = splited_room_id[1]

    util.debug("Attempting to rekey room %s..." % room)

    # Find the right flute room
    account = accounts.get_my_account()
    try:
        flute_room = account.get_flute_room(room, server)
    except accounts.NoSuchRoom:
        util.debug("Tried to rekey unknown room %s..." % room)
        return

    # Rekey room!
    flute_room.rekey()
Ejemplo n.º 19
0
Archivo: flute.py Proyecto: h1r00/flute
def handle_outgoing_irc_msg_to_channel(parsed, server):
    """We are about to send 'parsed' to a channel. If the channel is a flute room
    where the room message key is known, encrypt the message and send it
    directly. Otherwise if no Flute session is going on, return the plaintext
    string that should be output to the channel."""
    channel = parsed['to_channel']
    msg = parsed['text']
    account = accounts.get_my_account()

    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No flute room at %s. Sending plaintext." % channel)
        return msg

    try:
        room_message_key = flute_room.get_current_room_message_key()
    except room.NoMessageKey:
        util.debug("No message key at %s. Sending plaintext." % channel) # XXX ???
        return msg

    if not flute_room.status == "done":
        util.debug("Room %s not setup yet. Sending plaintext." % channel) # XXX ???
        return msg

    util.debug("Sending encrypted msg to %s" % channel)

    # OK we are in a flute room and we even know the key!
    # Send a ROOM_MESSAGE!
    # XXX functionify
    ciphertext = crypto.get_room_message_ciphertext(room_message_key, msg)
    packet_signed = account.sign_msg_with_identity_key(ciphertext)

    payload_b64 = base64.b64encode(packet_signed)

    msg = ROOM_MESSAGE_OPCODE + payload_b64
    transport.send_flute_privmsg(server, channel, msg)

    return ""
Ejemplo n.º 20
0
def handle_outgoing_irc_msg_to_channel(parsed, server):
    """We are about to send 'parsed' to a channel. If the channel is a viola room
    where the room message key is known, encrypt the message and send it
    directly. Otherwise if no Viola session is going on, return the plaintext
    string that should be output to the channel."""
    channel = parsed['to_channel']
    msg = parsed['text']
    account = accounts.get_my_account()

    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("No viola room at %s. Sending plaintext." % channel)
        return msg

    try:
        room_message_key = viola_room.get_room_message_key()
    except room.NoMessageKey:
        util.debug("No message key at %s. Sending plaintext." % channel) # XXX ???
        return msg

    if not viola_room.status == "done":
        util.debug("Room %s not setup yet. Sending plaintext." % channel) # XXX ???
        return msg

    util.debug("Sending encrypted msg to %s" % channel)

    # OK we are in a viola room and we even know the key!
    # Send a ROOM_MESSAGE!
    # XXX functionify
    ciphertext = crypto.get_room_message_ciphertext(room_message_key, msg)
    packet_signed = account.sign_msg_with_identity_key(ciphertext)

    payload_b64 = base64.b64encode(packet_signed)

    msg = ROOM_MESSAGE_OPCODE + payload_b64
    transport.send_viola_privmsg(server, channel, msg)

    return ""
Ejemplo n.º 21
0
def introduction_cmd(parsed_args, buf):
    account = accounts.get_my_account()

    # Prepare the metadata
    server = util.get_local_server(buf)

    # If a nick is provided, introduce to that nick. Otherwise, check if we are
    # currently having a private conversation with another nick, and if so
    # introduce to that nick.
    if len(parsed_args) >= 2:
        target_nick = parsed_args[1]
    else:
        if otrlib.buffer_is_private(buf):
            target_nick = util.get_local_channel(buf)
        else:
            util.control_msg("Bad introduction command! Can't introduce yourself to a channel!")
            raise flute.FluteCommandError

    introduction.send_introduction(account, target_nick, server, buf)

    util.flute_channel_msg(buf,
                           "[Introduced ourselves to %s.]" % target_nick,
                           color="green")
Ejemplo n.º 22
0
Archivo: flute.py Proyecto: h1r00/flute
def handle_room_join_packet(packet_payload, parsed, server):
    sender_nick = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not parsed['to_channel']: # XXX functionify
        util.debug("Received ROOM_JOIN not in channel from %s. Ignoring." % sender_nick)
        return ""

    # Is this channel a flute room for us?
    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received ROOM_JOIN in a regular channel (%s). Ignoring." % channel)
        return ""

    payload = base64.b64decode(packet_payload)

    if len(payload) < ROOM_JOIN_PAYLOAD_LEN:
        raise IncompletePacket

    signature = payload[:SIG_LEN]
    identity_pubkey = crypto.parse_signing_pubkey(payload[SIG_LEN:SIG_LEN+PUBKEY_LEN])
    room_pubkey = crypto.parse_pub_key(payload[SIG_LEN+PUBKEY_LEN:SIG_LEN+PUBKEY_LEN+PUBKEY_LEN])

    # Verify signature
    # XXX is this the right logic for this particular packet?
    # XXX catch exception
    identity_pubkey.verify(payload)

    # XXX should we add all members even if we don't know them?
    flute_room.add_member(sender_nick, identity_pubkey, room_pubkey)

    # No need to do anything more if we are not captain in this channel.
    if not flute_room.i_am_captain:
        util.debug("Received ROOM_JOIN in %s but not captain. Ignoring." % channel)
        return ""

    util.debug("Received ROOM_JOIN in %s. Sending KEY_TRANSPORT (%d members)!" % (channel, len(flute_room.members)))

    # We are the captain. Check if we trust this key. Reject member otherwise.
    try:
        joining_friend_name = account.get_friend_from_identity_key(identity_pubkey)
    except accounts.IdentityKeyNotTrusted:
        buf = flute_room.buf
        util.flute_channel_msg(buf, "%s nickname %s is trying to join the channel with key %s." %
                               (otrlib.colorize("Untrusted", "red"), sender_nick,
                                crypto.get_hexed_key(identity_pubkey)), "red")
        util.flute_channel_msg(buf, "If you trust that key and you want them to join the channel, "
                               "please issue the following command and ask them to rejoin the channel:\n"
                               "\t /flute trust-key <name> %s\n"
                               "where <name> is the nickname you want to assign to the key."  %
                               crypto.get_hexed_key(identity_pubkey), "red")

        util.flute_channel_msg(buf, "Example: /flute trust-key alice %s" % crypto.get_hexed_key(identity_pubkey), "red")
        return ""

    # XXX Security: Maybe we should ask the captain before autoadding them!
    buf = flute_room.buf
    util.flute_channel_msg(buf, "User '%s' (friend name: %s) was added to the flute room!" % \
                           (sender_nick, joining_friend_name),
                           color="green")

    # We are captains in the channel. Act like it!
    # There is a new room member! Refresh and send new key!
    send_key_transport_packet(flute_room)
    return ""
Ejemplo n.º 23
0
def handle_room_join_packet(packet_payload, parsed, server):
    sender_nick = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not parsed['to_channel']: # XXX functionify
        util.debug("Received ROOM_JOIN not in channel from %s. Ignoring." % sender_nick)
        return ""

    # Is this channel a viola room for us?
    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received ROOM_JOIN in a regular channel (%s). Ignoring." % channel)
        return ""

    payload = base64.b64decode(packet_payload)

    if len(payload) < ROOM_JOIN_PAYLOAD_LEN:
        raise IncompletePacket

    signature = payload[:SIG_LEN]
    identity_pubkey = crypto.parse_signing_pubkey(payload[SIG_LEN:SIG_LEN+PUBKEY_LEN])
    room_pubkey = crypto.parse_pub_key(payload[SIG_LEN+PUBKEY_LEN:SIG_LEN+PUBKEY_LEN+PUBKEY_LEN])

    # Verify signature
    # XXX is this the right logic for this particular packet?
    # XXX catch exception
    identity_pubkey.verify(payload)

    # XXX should we add all members even if we don't know them?
    viola_room.add_member(sender_nick, identity_pubkey, room_pubkey)

    # No need to do anything more if we are not captain in this channel.
    if not viola_room.i_am_captain:
        util.debug("Received ROOM_JOIN in %s but not captain. Ignoring." % channel)
        return ""

    util.debug("Received ROOM_JOIN in %s. Sending KEY_TRANSPORT (%d members)!" % (channel, len(viola_room.members)))

    # We are the captain. Check if we trust this key. Reject member otherwise.
    try:
        joining_friend_name = account.get_friend_from_identity_key(identity_pubkey)
    except accounts.IdentityKeyNotTrusted:
        buf = viola_room.buf
        util.viola_channel_msg(buf, "%s nickname %s is trying to join the channel with key %s." %
                               (otrlib.colorize("Untrusted", "red"), sender_nick,
                                crypto.get_hexed_key(identity_pubkey)), "red")
        util.viola_channel_msg(buf, "If you trust that key and you want them to join the channel, "
                               "please issue the following command and ask them to rejoin the channel:\n"
                               "\t /viola trust-key <name> %s\n"
                               "where <name> is the nickname you want to assign to the key."  %
                               crypto.get_hexed_key(identity_pubkey), "red")

        util.viola_channel_msg(buf, "Example: /viola trust-key alice %s" % crypto.get_hexed_key(identity_pubkey), "red")
        return ""

    # XXX Security: Maybe we should ask the captain before autoadding them!
    buf = viola_room.buf
    util.viola_channel_msg(buf, "Friend '%s' was added to the viola room!" % joining_friend_name)

    # We are captains in the channel. Act like it!
    # There is a new room member! Refresh and send new key!
    send_key_transport_packet(viola_room)
    return ""
Ejemplo n.º 24
0
def handle_key_transport_packet(packet_payload, parsed, server):
    sender = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not channel: # XXX functionify
        util.debug("Received KEY_TRANSPORT not in channel from %s. Ignoring." % sender)
        return ""

    # Is this channel a viola room for us?
    # XXX Code duplication
    try:
        viola_room = account.get_viola_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received ROOM_JOIN in a regular channel (%s). Ignoring." % channel)
        return ""

    payload = base64.b64decode(packet_payload)

    if len(payload) < MINIMUM_KEY_TRANSPORT_PAYLOAD_LEN:
        raise IncompletePacket

    if viola_room.i_am_captain:
        util.debug("Received KEY_TRANSPORT in %s by %s but I am captain! Ignoring." % (channel, sender))
        return ""

    util.debug("Received KEY_TRANSPORT in %s! Handling it." % channel)

    # Start parsing the packet
    signature = payload[:SIG_LEN]

    captain_identity_pubkey = payload[SIG_LEN:SIG_LEN+PUBKEY_LEN]
    captain_identity_pubkey = crypto.parse_signing_pubkey(captain_identity_pubkey)

    captain_transport_pubkey = payload[SIG_LEN+PUBKEY_LEN : SIG_LEN+PUBKEY_LEN+PUBKEY_LEN]
    captain_transport_pubkey = crypto.parse_pub_key(captain_transport_pubkey)

    encrypted_message_key_array = payload[SIG_LEN+PUBKEY_LEN+PUBKEY_LEN:]

    # Check if we trust the captain.
    try:
        captain_friend_name = account.get_friend_from_identity_key(captain_identity_pubkey)
    except accounts.IdentityKeyNotTrusted:
        buf = viola_room.buf
        util.viola_channel_msg(buf, "Untrusted nickname %s is the captain of this channel with key: %s" % (sender, captain_identity_pubkey),
                               "red")
        util.viola_channel_msg(buf, "Ignoring KEY_TRANSPORT by untrusted captain. If you trust that key and"
                               "you want to join the channel, please issue the following command and rejoin:\n"
                               "\t /viola trust-key <name> %s\n"
                               "where <name> is the nickname you want to assign to the key."  %
                               crypto.get_hexed_key(captain_identity_pubkey), "red")
        util.viola_channel_msg(buf, "Example: /viola trust-key alice %s" % crypto.get_hexed_key(captain_identity_pubkey), "red")
        return ""

    # Verify captain signature
    captain_identity_pubkey.verify(payload)    # XXX catch exception

    # Try to decrypt the message key array
    try:
        room_message_key = crypto.decrypt_room_message_key(encrypted_message_key_array,
                                                           captain_transport_pubkey,
                                                           viola_room.get_room_participant_privkey())
    except crypto.NoKeyFound:
        util.debug("Received KEY_TRANSPORT but did not find my key. F**k.")
        return ""

    # We got the room message key!
    viola_room.set_room_message_key(room_message_key)
    viola_room.status = "done"

    # We found our captain. Add them to the room!
    # XXX should we do this here or before the checks?
    viola_room.add_member(sender, captain_identity_pubkey, captain_transport_pubkey)

    # Print some messages to the user
    buf = util.viola_channel_msg(viola_room.buf, "Joined room %s with captain %s!" % (channel, sender))
    util.debug("Got a new room message key from captain %s: %s" % \
               (sender, crypto.get_hexed_key(room_message_key)))

    return ""
Ejemplo n.º 25
0
def list_fingerprint_cmd():
    account = accounts.get_my_account()
    account.print_fingerprint()
Ejemplo n.º 26
0
def list_friends_cmd():
    account = accounts.get_my_account()
    account.print_friend_list()
Ejemplo n.º 27
0
Archivo: flute.py Proyecto: h1r00/flute
def user_changed_irc_nick(old_nick, new_nick):
    """User changed nickname. Track the change."""
    account = accounts.get_my_account()
    # A user changed nick: we need to update the flute rooms.
    account.user_changed_nick(old_nick, new_nick)
Ejemplo n.º 28
0
Archivo: flute.py Proyecto: h1r00/flute
def handle_key_transport_packet(packet_payload, parsed, server):
    sender = parsed['from_nick']
    channel = parsed['to_channel']
    account = accounts.get_my_account()

    if not channel: # XXX functionify
        util.debug("Received KEY_TRANSPORT not in channel from %s. Ignoring." % sender)
        return ""

    # Is this channel a flute room for us?
    # XXX Code duplication
    try:
        flute_room = account.get_flute_room(channel, server)
    except accounts.NoSuchRoom:
        util.debug("Received KEY_TRANSPORT in a regular channel (%s). Ignoring." % channel)
        return ""

    payload = base64.b64decode(packet_payload)

    if len(payload) < MINIMUM_KEY_TRANSPORT_PAYLOAD_LEN:
        raise IncompletePacket

    if flute_room.i_am_captain:
        util.debug("Received KEY_TRANSPORT in %s by %s but I am captain! Ignoring." % (channel, sender))
        return ""

    util.debug("Received KEY_TRANSPORT in %s! Handling it." % channel)

    # Start parsing the packet
    signature = payload[:SIG_LEN]

    captain_identity_pubkey = payload[SIG_LEN:SIG_LEN+PUBKEY_LEN]
    captain_identity_pubkey = crypto.parse_signing_pubkey(captain_identity_pubkey)

    captain_transport_pubkey = payload[SIG_LEN+PUBKEY_LEN : SIG_LEN+PUBKEY_LEN+PUBKEY_LEN]
    captain_transport_pubkey = crypto.parse_pub_key(captain_transport_pubkey)

    new_key_counter, = struct.unpack('>I',payload[SIG_LEN + PUBKEY_LEN + PUBKEY_LEN: SIG_LEN + PUBKEY_LEN + PUBKEY_LEN + KEY_ID_LEN])

    encrypted_message_key_array = payload[SIG_LEN+PUBKEY_LEN+PUBKEY_LEN + KEY_ID_LEN:]

    # Check if we trust the captain.
    try:
        captain_friend_name = account.get_friend_from_identity_key(captain_identity_pubkey)
    except accounts.IdentityKeyNotTrusted:
        hexed_captain_key = crypto.get_hexed_key(captain_identity_pubkey)
        buf = flute_room.buf
        util.flute_channel_msg(buf, "Untrusted nickname %s is the captain of this channel with key: %s" % (sender, hexed_captain_key),
                               color="red")
        util.flute_channel_msg(buf, "Ignoring KEY_TRANSPORT by untrusted captain. If you trust that key and "
                               "you want to join the channel, please issue the following command and rejoin:\n"
                               "\t /flute trust-key <name> %s\n"
                               "where <name> is the nickname you want to assign to the key."  % hexed_captain_key,
                               color="red")
        util.flute_channel_msg(buf, "Example: /flute trust-key alice %s" % hexed_captain_key,
                               color="red")
        return ""

    # Verify captain signature
    captain_identity_pubkey.verify(payload)    # XXX catch exception

    # Check for replays using KEY_TRANSPORT counter
    if new_key_counter < 1:
        util.debug("Corrupted key counter %d" % new_key_counter)
        return ""
    if flute_room.key_transport_is_replay(new_key_counter):
        return ""

    # Try to decrypt the message key array
    try:
        room_message_key = crypto.decrypt_room_message_key(encrypted_message_key_array,
                                                           captain_transport_pubkey,
                                                           flute_room.get_room_participant_privkey())
    except crypto.NoKeyFound:
        util.debug("Received KEY_TRANSPORT but did not find my key. F**k.")
        return ""

    # We got the room message key!
    flute_room.set_room_message_key(room_message_key, new_key_counter)
    flute_room.status = "done"

    # We found our captain. Add them to the room!
    # XXX careful not to double-add the captain in case of rekey
    flute_room.add_member(sender, captain_identity_pubkey, captain_transport_pubkey)

    # Print some messages to the user
    buf = util.flute_channel_msg(flute_room.buf,
                                 "Got room key for %s from captain %s (friend name: %s)!" % (channel, sender, captain_friend_name))
    util.debug("Got a new room message key from captain %s: %s" % \
               (sender, crypto.get_hexed_key(room_message_key)))

    return ""
Ejemplo n.º 29
0
def list_friends_cmd():
    account = accounts.get_my_account()
    account.print_friend_list()
Ejemplo n.º 30
0
def list_fingerprint_cmd():
    account = accounts.get_my_account()
    account.print_fingerprint()
Ejemplo n.º 31
0
def user_changed_irc_nick(old_nick, new_nick):
    """User changed nickname. Track the change."""
    account = accounts.get_my_account()
    # A user changed nick: we need to update the viola rooms.
    account.user_changed_nick(old_nick, new_nick)
Ejemplo n.º 32
0
def introduction_cmd(parsed_args, buf):
    account = accounts.get_my_account()
    introduction.send_introduction(account, parsed_args, buf)