#!/usr/bin/python
#
# sslsniff  Captures data on read/recv or write/send functions of OpenSSL,
#           GnuTLS and NSS
#           For Linux, uses BCC, eBPF.
#
# USAGE: sslsniff.py [-h] [-p PID] [-u UID] [-x] [-c COMM] [-o] [-g] [-n] [-d]
#                    [--hexdump] [--max-buffer-size SIZE] [-l] [--handshake]
#
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 12-Aug-2016    Adrian Lopez   Created this.
# 13-Aug-2016    Mark Drayton   Fix SSL_Read
# 17-Aug-2016    Adrian Lopez   Capture GnuTLS and add options
#

from __future__ import print_function
from bcc import BPF
import argparse
import binascii
import textwrap
import os.path

# arguments
examples = """examples:
    ./sslsniff              # sniff OpenSSL and GnuTLS functions
    ./sslsniff -p 181       # sniff PID 181 only
    ./sslsniff -u 1000      # sniff only UID 1000
    ./sslsniff -c curl      # sniff curl command only
    ./sslsniff --no-openssl # don't show OpenSSL calls
    ./sslsniff --no-gnutls  # don't show GnuTLS calls
    ./sslsniff --no-nss     # don't show NSS calls
    ./sslsniff --hexdump    # show data as hex instead of trying to decode it as UTF-8
    ./sslsniff -x           # show process UID and TID
    ./sslsniff -l           # show function latency
    ./sslsniff -l --handshake  # show SSL handshake latency
    ./sslsniff --extra-lib openssl:/path/libssl.so.1.1 # sniff extra library
"""


def ssllib_type(input_str):
    valid_types = frozenset(['openssl', 'gnutls', 'nss'])

    try:
        lib_type, lib_path = input_str.split(':', 1)
    except ValueError:
        raise argparse.ArgumentTypeError("Invalid SSL library param: %r" % input_str)

    if lib_type not in valid_types:
        raise argparse.ArgumentTypeError("Invalid SSL library type: %r" % lib_type)

    if not os.path.isfile(lib_path):
        raise argparse.ArgumentTypeError("Invalid library path: %r" % lib_path)

    return lib_type, lib_path


parser = argparse.ArgumentParser(
    description="Sniff SSL data",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=examples)
parser.add_argument("-p", "--pid", type=int, help="sniff this PID only.")
parser.add_argument("-u", "--uid", type=int, default=None,
                    help="sniff this UID only.")
parser.add_argument("-x", "--extra", action="store_true",
                    help="show extra fields (UID, TID)")
parser.add_argument("-c", "--comm",
                    help="sniff only commands matching string.")
parser.add_argument("-o", "--no-openssl", action="store_false", dest="openssl",
                    help="do not show OpenSSL calls.")
parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls",
                    help="do not show GnuTLS calls.")
parser.add_argument("-n", "--no-nss", action="store_false", dest="nss",
                    help="do not show NSS calls.")
parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
                    help='debug mode.')
parser.add_argument("--ebpf", action="store_true",
                    help=argparse.SUPPRESS)
parser.add_argument("--hexdump", action="store_true", dest="hexdump",
                    help="show data as hexdump instead of trying to decode it as UTF-8")
parser.add_argument('--max-buffer-size', type=int, default=8192,
                    help='Size of captured buffer')
parser.add_argument("-l", "--latency", action="store_true",
                    help="show function latency")
parser.add_argument("--handshake", action="store_true",
                    help="show SSL handshake latency, enabled only if latency option is on.")
parser.add_argument("--extra-lib", type=ssllib_type, action='append',
                    help="Intercept calls from extra library (format: lib_type:lib_path)")
args = parser.parse_args()


prog = """
#include <linux/ptrace.h>
#include <linux/sched.h>        /* For TASK_COMM_LEN */

#define MAX_BUF_SIZE __MAX_BUF_SIZE__

struct probe_SSL_data_t {
        u64 timestamp_ns;
        u64 delta_ns;
        u32 pid;
        u32 tid;
        u32 uid;
        u32 len;
        int buf_filled;
        int rw;
        char comm[TASK_COMM_LEN];
        u8 buf[MAX_BUF_SIZE];
};

#define BASE_EVENT_SIZE ((size_t)(&((struct probe_SSL_data_t*)0)->buf))
#define EVENT_SIZE(X) (BASE_EVENT_SIZE + ((size_t)(X)))

BPF_PERCPU_ARRAY(ssl_data, struct probe_SSL_data_t, 1);
BPF_PERF_OUTPUT(perf_SSL_rw);

BPF_HASH(start_ns, u32);
BPF_HASH(bufs, u32, u64);

int probe_SSL_rw_enter(struct pt_regs *ctx, void *ssl, void *buf, int num) {
        int ret;
        u32 zero = 0;
        u64 pid_tgid = bpf_get_current_pid_tgid();
        u32 pid = pid_tgid >> 32;
        u32 tid = pid_tgid;
        u32 uid = bpf_get_current_uid_gid();
        u64 ts = bpf_ktime_get_ns();

        PID_FILTER
        UID_FILTER

        bufs.update(&tid, (u64*)&buf);
        start_ns.update(&tid, &ts);
        return 0;
}

static int SSL_exit(struct pt_regs *ctx, int rw) {
        int ret;
        u32 zero = 0;
        u64 pid_tgid = bpf_get_current_pid_tgid();
        u32 pid = pid_tgid >> 32;
        u32 tid = (u32)pid_tgid;
        u32 uid = bpf_get_current_uid_gid();
        u64 ts = bpf_ktime_get_ns();

        PID_FILTER
        UID_FILTER

        u64 *bufp = bufs.lookup(&tid);
        if (bufp == 0)
                return 0;

        u64 *tsp = start_ns.lookup(&tid);
        if (tsp == 0)
                return 0;

        int len = PT_REGS_RC(ctx);
        if (len <= 0) // no data
                return 0;

        struct probe_SSL_data_t *data = ssl_data.lookup(&zero);
        if (!data)
                return 0;

        data->timestamp_ns = ts;
        data->delta_ns = ts - *tsp;
        data->pid = pid;
        data->tid = tid;
        data->uid = uid;
        data->len = (u32)len;
        data->buf_filled = 0;
        data->rw = rw;
        u32 buf_copy_size = min((size_t)MAX_BUF_SIZE, (size_t)len);

        bpf_get_current_comm(&data->comm, sizeof(data->comm));

        if (bufp != 0)
                ret = bpf_probe_read_user(&data->buf, buf_copy_size, (char *)*bufp);

        bufs.delete(&tid);
        start_ns.delete(&tid);

        if (!ret)
                data->buf_filled = 1;
        else
                buf_copy_size = 0;

        perf_SSL_rw.perf_submit(ctx, data, EVENT_SIZE(buf_copy_size));
        return 0;
}

int probe_SSL_read_exit(struct pt_regs *ctx) {
        return (SSL_exit(ctx, 0));
}

int probe_SSL_write_exit(struct pt_regs *ctx) {
        return (SSL_exit(ctx, 1));
}

BPF_PERF_OUTPUT(perf_SSL_do_handshake);

int probe_SSL_do_handshake_enter(struct pt_regs *ctx, void *ssl) {
        u64 pid_tgid = bpf_get_current_pid_tgid();
        u32 pid = pid_tgid >> 32;
        u32 tid = (u32)pid_tgid;
        u64 ts = bpf_ktime_get_ns();

        PID_FILTER
        UID_FILTER

        start_ns.update(&tid, &ts);
        return 0;
}

int probe_SSL_do_handshake_exit(struct pt_regs *ctx) {
        u32 zero = 0;
        u64 pid_tgid = bpf_get_current_pid_tgid();
        u32 pid = pid_tgid >> 32;
        u32 tid = (u32)pid_tgid;
        u32 uid = bpf_get_current_uid_gid();
        u64 ts = bpf_ktime_get_ns();
        int ret;

        PID_FILTER
        UID_FILTER

        u64 *tsp = start_ns.lookup(&tid);
        if (tsp == 0)
                return 0;

        ret = PT_REGS_RC(ctx);
        if (ret <= 0) // handshake failed
                return 0;

        struct probe_SSL_data_t *data = ssl_data.lookup(&zero);
        if (!data)
                return 0;

        data->timestamp_ns = ts;
        data->delta_ns = ts - *tsp;
        data->pid = pid;
        data->tid = tid;
        data->uid = uid;
        data->len = ret;
        data->buf_filled = 0;
        data->rw = 2;
        bpf_get_current_comm(&data->comm, sizeof(data->comm));
        start_ns.delete(&tid);

        perf_SSL_do_handshake.perf_submit(ctx, data, EVENT_SIZE(0));
        return 0;
}
"""

if args.pid:
    prog = prog.replace('PID_FILTER', 'if (pid != %d) { return 0; }' % args.pid)
else:
    prog = prog.replace('PID_FILTER', '')

if args.uid is not None:
    prog = prog.replace('UID_FILTER', 'if (uid != %d) { return 0; }' % args.uid)
else:
    prog = prog.replace('UID_FILTER', '')

prog = prog.replace('__MAX_BUF_SIZE__', str(args.max_buffer_size))

if args.debug or args.ebpf:
    print(prog)
    if args.ebpf:
        exit()


b = BPF(text=prog)

# It looks like SSL_read's arguments aren't available in a return probe so you
# need to stash the buffer address in a map on the function entry and read it
# on its exit (Mark Drayton)
#
def attach_openssl(lib):
    b.attach_uprobe(name=lib, sym="SSL_write",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="SSL_write",
                       fn_name="probe_SSL_write_exit", pid=args.pid or -1)
    b.attach_uprobe(name=lib, sym="SSL_read",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="SSL_read",
                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)
    if args.latency and args.handshake:
        b.attach_uprobe(name="ssl", sym="SSL_do_handshake",
                        fn_name="probe_SSL_do_handshake_enter", pid=args.pid or -1)
        b.attach_uretprobe(name="ssl", sym="SSL_do_handshake",
                           fn_name="probe_SSL_do_handshake_exit", pid=args.pid or -1)

def attach_gnutls(lib):
    b.attach_uprobe(name=lib, sym="gnutls_record_send",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="gnutls_record_send",
                       fn_name="probe_SSL_write_exit", pid=args.pid or -1)
    b.attach_uprobe(name=lib, sym="gnutls_record_recv",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="gnutls_record_recv",
                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)

def attach_nss(lib):
    b.attach_uprobe(name=lib, sym="PR_Write",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="PR_Write",
                       fn_name="probe_SSL_write_exit", pid=args.pid or -1)
    b.attach_uprobe(name=lib, sym="PR_Send",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="PR_Send",
                       fn_name="probe_SSL_write_exit", pid=args.pid or -1)
    b.attach_uprobe(name=lib, sym="PR_Read",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="PR_Read",
                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)
    b.attach_uprobe(name=lib, sym="PR_Recv",
                    fn_name="probe_SSL_rw_enter", pid=args.pid or -1)
    b.attach_uretprobe(name=lib, sym="PR_Recv",
                       fn_name="probe_SSL_read_exit", pid=args.pid or -1)


LIB_TRACERS = {
    "openssl": attach_openssl,
    "gnutls": attach_gnutls,
    "nss": attach_nss,
}


if args.openssl:
    attach_openssl("ssl")
if args.gnutls:
    attach_gnutls("gnutls")
if args.nss:
    attach_nss("nspr4")


if args.extra_lib:
    for lib_type, lib_path in args.extra_lib:
        LIB_TRACERS[lib_type](lib_path)

# define output data structure in Python


# header
header = "%-12s %-18s %-16s %-7s %-7s" % ("FUNC", "TIME(s)", "COMM", "PID", "LEN")

if args.extra:
    header += " %-7s %-7s" % ("UID", "TID")

if args.latency:
    header += " %-7s" % ("LAT(ms)")

print(header)
# process event
start = 0

def print_event_rw(cpu, data, size):
    print_event(cpu, data, size, "perf_SSL_rw")

def print_event_handshake(cpu, data, size):
    print_event(cpu, data, size, "perf_SSL_do_handshake")

def print_event(cpu, data, size, evt):
    global start
    event = b[evt].event(data)
    if event.len <= args.max_buffer_size:
        buf_size = event.len
    else:
        buf_size = args.max_buffer_size

    if event.buf_filled == 1:
        buf = bytearray(event.buf[:buf_size])
    else:
        buf_size = 0
        buf = b""

    # Filter events by command
    if args.comm:
        if not args.comm == event.comm.decode('utf-8', 'replace'):
            return

    if start == 0:
        start = event.timestamp_ns
    time_s = (float(event.timestamp_ns - start)) / 1000000000

    lat_str = "%.3f" % (event.delta_ns / 1000000) if event.delta_ns else "N/A"

    s_mark = "-" * 5 + " DATA " + "-" * 5

    e_mark = "-" * 5 + " END DATA " + "-" * 5

    truncated_bytes = event.len - buf_size
    if truncated_bytes > 0:
        e_mark = "-" * 5 + " END DATA (TRUNCATED, " + str(truncated_bytes) + \
                " bytes lost) " + "-" * 5

    base_fmt = "%(func)-12s %(time)-18.9f %(comm)-16s %(pid)-7d %(len)-6d"

    if args.extra:
        base_fmt += " %(uid)-7d %(tid)-7d"

    if args.latency:
        base_fmt += " %(lat)-7s"

    fmt = ''.join([base_fmt, "\n%(begin)s\n%(data)s\n%(end)s\n\n"])
    if args.hexdump:
        unwrapped_data = binascii.hexlify(buf)
        data = textwrap.fill(unwrapped_data.decode('utf-8', 'replace'), width=32)
    else:
        data = buf.decode('utf-8', 'replace')

    rw_event = {
        0: "READ/RECV",
        1: "WRITE/SEND",
        2: "HANDSHAKE"
    }

    fmt_data = {
        'func': rw_event[event.rw],
        'time': time_s,
        'lat': lat_str,
        'comm': event.comm.decode('utf-8', 'replace'),
        'pid': event.pid,
        'tid': event.tid,
        'uid': event.uid,
        'len': event.len,
        'begin': s_mark,
        'end': e_mark,
        'data': data
    }

    # use base_fmt if no buf filled
    if buf_size == 0:
        print(base_fmt % fmt_data)
    else:
        print(fmt % fmt_data)

b["perf_SSL_rw"].open_perf_buffer(print_event_rw)
b["perf_SSL_do_handshake"].open_perf_buffer(print_event_handshake)
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()
