Ejemplo n.º 1
0
def fish_secure():
    global fish_secure_key, fish_secure_cipher

    fish_secure_key = weechat.config_string(fish_config_option["key"])

    # if blank, do nothing
    if fish_secure_key == "":
        fish_success()
        return

    # if ${sec.data.fish}, check if sec.conf is decrypted
    # and decrypt
    elif fish_secure_key[:6] == "${sec.":
        decrypted = weechat.string_eval_expression(fish_secure_key, {}, {}, {})

        if decrypted:
            fish_secure_cipher = Blowfish(decrypted)
            fish_decrypt_keys()
            fish_success()
            return

        else:
            global SCRIPT_NAME
            fish_secure_error()
            weechat.command(weechat.current_buffer(),
                            "/wait 1ms /python unload %s" % SCRIPT_NAME)
            return

    # if key is neither ${sec.data.fish} or ""
    # encrypt/decrypt with user supplied, plain text key
    if fish_secure_key != "":
        fish_secure_cipher = Blowfish(fish_secure_key)
        fish_decrypt_keys()
        fish_success()
        return
Ejemplo n.º 2
0
def fish_secure_key_cb(data, option, value):
    global fish_secure_key, fish_secure_cipher

    fish_secure_key = weechat.config_string(
        weechat.config_get("fish.secure.key")
    )

    if fish_secure_key == "":
        fish_secure_cipher = None
        return weechat.WEECHAT_RC_OK

    if fish_secure_key[:6] == "${sec.":
        decrypted = weechat.string_eval_expression(
            fish_secure_key, {}, {}, {}
        )
        if decrypted:
            fish_secure_cipher = Blowfish(decrypted)
            return weechat.WEECHAT_RC_OK
        else:
            weechat.config_option_set(fish_config_option["key"], "", 0)
            weechat.prnt("", "Decrypt sec.conf first\n")
            return weechat.WEECHAT_RC_OK

    if fish_secure_key != "":
        fish_secure_cipher = Blowfish(fish_secure_key)

    return weechat.WEECHAT_RC_OK
Ejemplo n.º 3
0
def fish_modifier_out_topic_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    match = re.match(r"^(TOPIC (.*?) :)(.*)$", string)
    if not match:
        return string
    if not match.group(3):
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (server_name,
            match.group(2)))

    if targetl not in fish_keys:
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_cyphers:
        b = Blowfish(fish_keys[targetl])
        fish_cyphers[targetl] = b
    else:
        b = fish_cyphers[targetl]
    cypher = blowcrypt_pack(match.group(3), b)

    fish_announce_encrypted(buffer, target)

    return "%s%s" % (match.group(1), cypher)
Ejemplo n.º 4
0
def fish_modifier_in_332_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    match = re.match(r"^(?:@time=[\d:TZ.-]+\s)(:.*? 332 .*? (.*?) :)((\+OK |mcps )?.*)$", string)
    if not match:
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (server_name,
            match.group(2)))

    if targetl not in fish_keys or not match.group(4):
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_cyphers:
        b = Blowfish(fish_keys[targetl])
        fish_cyphers[targetl] = b
    else:
        b = fish_cyphers[targetl]

    clean = blowcrypt_unpack(match.group(3), b)

    fish_announce_encrypted(buffer, target)

    return "%s%s" % (match.group(1), fish_msg_w_marker(clean))
Ejemplo n.º 5
0
def fish_modifier_in_topic_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    match = re.match(r"^(:.*?!.*? TOPIC (.*?) :)((\+OK |mcps )?.*)$", string)
    #match.group(0): message
    #match.group(1): msg without payload
    #match.group(2): channel
    #match.group(3): topic
    #match.group(4): +OK |mcps
    if not match:
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (server_name,
            match.group(2)))

    if targetl not in fish_keys or not match.group(4):
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_cyphers:
        b = Blowfish(fish_keys[targetl])
        fish_cyphers[targetl] = b
    else:
        b = fish_cyphers[targetl]
    clean = blowcrypt_unpack(match.group(3), b)

    fish_announce_encrypted(buffer, target)

    return "%s%s" % (match.group(1), fish_msg_w_marker(clean))
Ejemplo n.º 6
0
def fish_modifier_out_privmsg_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    if type(string) is bytes:
        return string

    match = re.match(r"^(PRIVMSG (.*?) :)(.*)$", string)
    if not match:
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer",
                              "%s,%s" % (server_name, match.group(2)))

    if targetl not in fish_keys:
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_cyphers:
        b = Blowfish(fish_keys[targetl])
        fish_cyphers[targetl] = b
    else:
        b = fish_cyphers[targetl]
    cypher = blowcrypt_pack(fish_msg_wo_marker(match.group(3)).encode(), b)

    fish_announce_encrypted(buffer, target)

    return "%s%s" % (match.group(1), cypher)
Ejemplo n.º 7
0
def fish_secure():
    global fish_secure_key, fish_secure_cipher

    fish_secure_key = weechat.config_string(fish_config_option["key"])

    # if blank, do nothing
    if fish_secure_key == "":
        return

    # if ${sec.data.fish}, check if sec.conf is decrypted
    # and decrypt
    elif fish_secure_key[:6] == "${sec.":
        decrypted = weechat.string_eval_expression(fish_secure_key, {}, {}, {})

        if decrypted:
            fish_secure_cipher = Blowfish(decrypted)
            fish_decrypt_keys()
            return

        else:
            global SCRIPT_NAME
            message = ("\n%s%sblowkey:%s unable to recover key from sec.conf\n"
                       "%s%sblowkey:%s fish.py %sNOT LOADED\n"
                       "%s%sblowkey:%s decrypt secured data first\n"
                       "%s%sblowkey:%s then reload fish.py\n\n") % (
                           weechat.prefix("error"), weechat.color("underline"),
                           weechat.color("reset"), weechat.prefix("error"),
                           weechat.color("underline"), weechat.color("reset"),
                           weechat.color("*red"), weechat.prefix("error"),
                           weechat.color("underline"), weechat.color("reset"),
                           weechat.prefix("error"), weechat.color("underline"),
                           weechat.color("reset"))

            weechat.prnt("", "%s" % message)
            weechat.command(weechat.current_buffer(),
                            "/wait 1ms /python unload %s" % SCRIPT_NAME)
            return

    # if key is neither ${sec.data.fish} or ""
    # encrypt/decrypt with user supplied, plain text key
    if fish_secure_key != "":
        fish_secure_cipher = Blowfish(fish_secure_key)
        fish_decrypt_keys()
        return
Ejemplo n.º 8
0
def fish_modifier_in_privmsg_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    match = re.match(
        r"^(:(.*?)!.*? PRIVMSG (.*?) :)(\x01ACTION )?((\+OK |mcps )?.*?)(\x01)?$",
        string,
    )
    # match.group(0): message
    # match.group(1): msg without payload
    # match.group(2): source
    # match.group(3): target
    # match.group(4): action
    # match.group(5): msg
    # match.group(6): +OK |mcps
    if not match:
        return string

    if match.group(3) == weechat.info_get("irc_nick", server_name):
        dest = match.group(2)
    else:
        dest = match.group(3)
    target = "%s/%s" % (server_name, dest)
    targetl = ("%s/%s" % (server_name, dest)).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (server_name, dest))

    if not match.group(6):
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_keys:
        fish_announce_unencrypted(buffer, target)

        return string

    fish_announce_encrypted(buffer, target)

    if targetl not in fish_cyphers:
        b = Blowfish(fish_keys[targetl])
        fish_cyphers[targetl] = b
    else:
        b = fish_cyphers[targetl]
    clean = blowcrypt_unpack(match.group(5), b)

    if not match.group(4):
        return "%s%s" % (match.group(1), fish_msg_w_marker(clean))

    return "%s%s%s\x01" % (
        match.group(1),
        match.group(4),
        fish_msg_w_marker(clean),
    )
Ejemplo n.º 9
0
def fish_secure_genkey(buffer):
    global fish_secure_cipher, fish_config_option

    newKey = blowcrypt_b64encode(urandom(32))

    # test to see if sec.conf decrypted
    weechat.command(buffer, "/secure set fish test")
    decrypted = weechat.string_eval_expression("${sec.data.fish}", {}, {}, {})

    if decrypted == "test":
        weechat.config_option_set(fish_config_option["key"],
                                  "${sec.data.fish}", 0)
        fish_secure_cipher = Blowfish(newKey)
        weechat.command(buffer, "/secure set fish %s" % newKey)
Ejemplo n.º 10
0
def fish_modifier_in_332_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    if type(string) is bytes:
        return string

    match = re.match(r"^(:.*? 332 .*? (.*?) :)((\+OK |mcps )?.*)$", string)
    if not match:
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer",
                              "%s,%s" % (server_name, match.group(2)))

    if targetl not in fish_keys or not match.group(4):
        fish_announce_unencrypted(buffer, target)

        return string

    key = fish_keys[targetl]

    try:
        if targetl not in fish_cyphers:
            b = Blowfish(key)
            fish_cyphers[targetl] = b
        else:
            b = fish_cyphers[targetl]

        clean = blowcrypt_unpack(match.group(3), b, key)

        fish_announce_encrypted(buffer, target)

        return b"%s%s" % (match.group(1).encode(), fish_msg_w_marker(clean))
    except Exception as e:
        fish_announce_unencrypted(buffer, target)

        raise e
Ejemplo n.º 11
0
def fish_modifier_in_notice_cb(data, modifier, server_name, string):
    global fish_DH1080ctx, fish_keys, fish_cyphers

    match = re.match(
        r"^(?:@time=[\d:TZ.-]+\s)?(:(.*?)!.*? NOTICE (.*?) :)((DH1080_INIT |DH1080_INIT_CBC |DH1080_FINISH |\+OK |mcps )?.*)$",
        string)
    #match.group(0): message
    #match.group(1): msg without payload
    #match.group(2): source
    #match.group(3): target
    #match.group(4): msg
    #match.group(5): DH1080_INIT |DH1080_INIT_CBC |DH1080_FINISH
    if not match or not match.group(5):
        return string

    if match.group(3) != weechat.info_get("irc_nick", server_name):
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (
            server_name, match.group(2)))

    if match.group(5) == "DH1080_FINISH " and targetl in fish_DH1080ctx:
        if not dh1080_unpack(match.group(4), fish_DH1080ctx[targetl]):
            fish_announce_unencrypted(buffer, target)
            return string

        msg = "Key exchange for %s successful" % target
        if fish_DH1080ctx[targetl].cbc:
            msg += " (CBC mode)"
        fish_alert(buffer, msg)

        fish_keys[targetl] = dh1080_secret(fish_DH1080ctx[targetl])
        if targetl in fish_cyphers:
            del fish_cyphers[targetl]
        del fish_DH1080ctx[targetl]

        return ""

    if match.group(5).startswith("DH1080_INIT"):
        fish_DH1080ctx[targetl] = DH1080Ctx()

        msg = ' '.join(match.group(4).split()[0:3])

        if not dh1080_unpack(msg, fish_DH1080ctx[targetl]):
            fish_announce_unencrypted(buffer, target)
            return string

        reply = dh1080_pack(fish_DH1080ctx[targetl])

        msg = "Key exchange initiated by %s. Key set." % target
        if fish_DH1080ctx[targetl].cbc:
            msg += " (CBC mode)"
        fish_alert(buffer, msg)

        weechat.command(buffer, "/mute -all notice %s %s" % (
                match.group(2), reply))

        fish_keys[targetl] = dh1080_secret(fish_DH1080ctx[targetl])
        if targetl in fish_cyphers:
            del fish_cyphers[targetl]
        del fish_DH1080ctx[targetl]

        return ""

    if match.group(5) in ["+OK ", "mcps "]:
        if targetl not in fish_keys:
            fish_announce_unencrypted(buffer, target)
            return string

        if targetl not in fish_cyphers:
            b = Blowfish(fish_keys[targetl])
            fish_cyphers[targetl] = b
        else:
            b = fish_cyphers[targetl]

        clean = blowcrypt_unpack(match.group(4), b)

        fish_announce_encrypted(buffer, target)

        return "%s%s" % (match.group(1), fish_msg_w_marker(clean))

    fish_announce_unencrypted(buffer, target)

    return string
Ejemplo n.º 12
0
def decrypt(key, inp):
    b = Blowfish(key)
    return blowcrypt_unpack(inp, b)
Ejemplo n.º 13
0
def encrypt(key, text):
    b = Blowfish(key)
    return blowcrypt_pack(text, b)
Ejemplo n.º 14
0
def new(key, mode=MODE_ECB, IV=None, counter=None, segment_size=None):
    """Create a new cipher object

    Blowfish using pycrypto for algo and pycryptoplus for ciphermode

        key = raw string containing the key
        mode = Blowfish.MODE_ECB/CBC/CFB/OFB/CTR/CMAC, default is ECB
        IV = IV as a raw string, default is "all zero" IV
            -> only needed for CBC mode
        counter = counter object (CryptoPlus.Util.util.Counter)
            -> only needed for CTR mode
        segment_size = amount of bits to use from the keystream in each chain part
            -> supported values: multiple of 8 between 8 and the blocksize
               of the cipher (only per byte access possible), default is 8
            -> only needed for CFB mode

    EXAMPLES:
    **********
    IMPORTING:
    -----------
    >>> from CryptoPlus.Cipher import Blowfish

    ECB EXAMPLE: http://www.schneier.com/code/vectors.txt
    -------------
    >>> cipher = Blowfish.new(('0131D9619DC1376E').decode('hex'))
    >>> ( cipher.encrypt(('5CD54CA83DEF57DA').decode('hex')) ).encode('hex')
    'b1b8cc0b250f09a0'
    >>> ( cipher.decrypt((_).decode('hex')) ).encode('hex')
    '5cd54ca83def57da'

    CBC, CFB, OFB EXAMPLE: http://www.schneier.com/code/vectors.txt
    ----------------------
    >>> key = ('0123456789ABCDEFF0E1D2C3B4A59687').decode('hex')
    >>> IV = ('FEDCBA9876543210').decode('hex')
    >>> plaintext = ('37363534333231204E6F77206973207468652074696D6520').decode('hex')
    >>> cipher = Blowfish.new(key,Blowfish.MODE_CBC,IV)
    >>> ciphertext = cipher.encrypt(plaintext)
    >>> (ciphertext).encode('hex').upper()
    '6B77B4D63006DEE605B156E27403979358DEB9E7154616D9'


    >>> key = '0123456789ABCDEFF0E1D2C3B4A59687'.decode('hex')
    >>> iv = 'FEDCBA9876543210'.decode('hex')
    >>> plaintext = '37363534333231204E6F77206973207468652074696D6520666F722000'.decode('hex')

    >>> cipher = Blowfish.new(key,Blowfish.MODE_CBC,iv)
    >>> ciphertext = cipher.encrypt(plaintext)
    >>> (ciphertext).encode('hex').upper()
    '6B77B4D63006DEE605B156E27403979358DEB9E7154616D9'

    >>> cipher = Blowfish.new(key,Blowfish.MODE_CFB,iv,segment_size=64)
    >>> ciphertext = cipher.encrypt(plaintext)
    >>> (ciphertext).encode('hex').upper()
    'E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3'

    >>> cipher = Blowfish.new(key,Blowfish.MODE_OFB,iv)
    >>> ciphertext = cipher.encrypt(plaintext)
    >>> (ciphertext).encode('hex').upper()
    'E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA'
    """
    return Blowfish(key, mode, IV, counter, segment_size)
Ejemplo n.º 15
0
def fish_modifier_in_privmsg_cb(data, modifier, server_name, string):
    global fish_keys, fish_cyphers

    if type(string) is bytes:
        return string

    match = re.match(
        r"^(:(.*?)!.*? PRIVMSG (.*?) :)(\x01ACTION )?"
        r"((\+OK |mcps )?.*?)(\x01)?$", string)
    # match.group(0): message
    # match.group(1): msg without payload
    # match.group(2): source
    # match.group(3): target
    # match.group(4): action
    # match.group(5): msg
    # match.group(6): "+OK "|"mcps "
    if not match:
        return string

    if match.group(3) == weechat.info_get("irc_nick", server_name):
        dest = match.group(2)
    else:
        dest = match.group(3)
    target = "%s/%s" % (server_name, dest)
    targetl = ("%s/%s" % (server_name, dest)).lower()
    buffer = weechat.info_get("irc_buffer", "%s,%s" % (server_name, dest))

    if not match.group(6):
        fish_announce_unencrypted(buffer, target)

        return string

    if targetl not in fish_keys:
        fish_announce_unencrypted(buffer, target)

        return string

    key = fish_keys[targetl]

    try:
        if targetl not in fish_cyphers:
            b = Blowfish(key)
            fish_cyphers[targetl] = b
        else:
            b = fish_cyphers[targetl]

        clean = blowcrypt_unpack(match.group(5), b, key)

        fish_announce_encrypted(buffer, target)

        if not match.group(4):
            return b'%s%s' % (match.group(1).encode(),
                              fish_msg_w_marker(clean))

        return b"%s%s%s\x01" % (match.group(1).encode(),
                                match.group(4).encode(),
                                fish_msg_w_marker(clean))

    except Exception as e:
        fish_announce_unencrypted(buffer, target)

        raise e
Ejemplo n.º 16
0
def fish_modifier_in_notice_cb(data, modifier, server_name, string):
    global fish_DH1080ctx, fish_keys, fish_cyphers

    if type(string) is bytes:
        return string

    match = re.match(
        r"^(:(.*?)!.*? NOTICE (.*?) :)"
        r"((DH1080_INIT |DH1080_FINISH |\+OK |mcps )?.*)$", string)
    # match.group(0): message
    # match.group(1): msg without payload
    # match.group(2): source
    # match.group(3): target
    # match.group(4): msg
    # match.group(5): "DH1080_INIT "|"DH1080_FINISH "|"+OK "|"mcps "
    if not match or not match.group(5):
        return string

    if match.group(3) != weechat.info_get("irc_nick", server_name):
        return string

    target = "%s/%s" % (server_name, match.group(2))
    targetl = ("%s/%s" % (server_name, match.group(2))).lower()
    buffer = weechat.info_get("irc_buffer",
                              "%s,%s" % (server_name, match.group(2)))

    if match.group(5) == "DH1080_FINISH " and targetl in fish_DH1080ctx:
        if not dh1080_unpack(match.group(4), fish_DH1080ctx[targetl]):
            fish_announce_unencrypted(buffer, target)
            return string

        fish_alert(buffer, "Key exchange for %s successful" % target)

        fish_keys[targetl] = dh1080_secret(fish_DH1080ctx[targetl])
        if targetl in fish_cyphers:
            del fish_cyphers[targetl]
        del fish_DH1080ctx[targetl]

        return ""

    if match.group(5) == "DH1080_INIT ":
        fish_DH1080ctx[targetl] = DH1080Ctx()

        msg = ' '.join(match.group(4).split()[0:2])

        if not dh1080_unpack(msg, fish_DH1080ctx[targetl]):
            fish_announce_unencrypted(buffer, target)
            return string

        reply = dh1080_pack(fish_DH1080ctx[targetl])

        fish_alert(buffer, "Key exchange initiated by %s. Key set." % target)

        weechat.command(buffer,
                        "/mute -all notice %s %s" % (match.group(2), reply))

        fish_keys[targetl] = dh1080_secret(fish_DH1080ctx[targetl])
        if targetl in fish_cyphers:
            del fish_cyphers[targetl]
        del fish_DH1080ctx[targetl]

        return ""

    if match.group(5) in ["+OK ", "mcps "]:
        if targetl not in fish_keys:
            fish_announce_unencrypted(buffer, target)
            return string

        key = fish_keys[targetl]

        try:
            if targetl not in fish_cyphers:
                b = Blowfish(key)
                fish_cyphers[targetl] = b
            else:
                b = fish_cyphers[targetl]

            clean = blowcrypt_unpack(match.group(4), b, key)

            fish_announce_encrypted(buffer, target)

            return b"%s%s" % (match.group(1).encode(),
                              fish_msg_w_marker(clean))
        except Exception as e:
            fish_announce_unencrypted(buffer, target)

            raise e

    fish_announce_unencrypted(buffer, target)

    return string