#!/usr/bin/env 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();
        u32 uid = bpf_get_current_uid_gid();
        
        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()
