aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/run-native-example.sh
blob: 6e9b9ba0b80b5155d15c020d914e8ef756f97154 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/bin/bash

# Script arguments in order:
#
# [-setcap]         Optional 1st argument to use setcap, see below
# [-root]           Optional 1st argument to use sudo, see below
# [-log <filename>] Optional argument to define logfile
# ...               All subsequent arguments are passed to the Direct-BT example
#
# export direct_bt_debug=true
# export direct_bt_debug=adapter.event=false,gatt.data=false,hci.event=true,hci.scan_ad_eir=true,mgmt.event=false
# export direct_bt_debug=adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event
# export direct_bt_debug=adapter.event,gatt.data
# export direct_bt_debug=adapter.event,hci.event
# export direct_bt_debug=adapter.event
#
# Assuming executing dbt_scanner10:
#
# Default logfile in ~/run-dbt_scanner10.log
# 
# Scan and read all devices (using default auto-sec w/ keyboard iocap)
# ../scripts/run-dbt_scanner10.sh
#
# Read device C0:26:DA:01:DA:B1  (using default auto-sec w/ keyboard iocap)
# ../scripts/run-dbt_scanner10.sh -dev C0:26:DA:01:DA:B1
#
# Read device C0:26:DA:01:DA:B1  (enforcing no security)
# ../scripts/run-dbt_scanner10.sh -dev C0:26:DA:01:DA:B1 -seclevel C0:26:DA:01:DA:B1 1
#
# Read any device containing C0:26:DA  (enforcing no security)
# ../scripts/run-dbt_scanner10.sh -dev C0:26:DA -seclevel C0:26:DA 1
#
# Read any device containing name 'TAIDOC'  (enforcing no security)
# ../scripts/run-dbt_scanner10.sh -dev 'TAIDOC' -seclevel 'TAIDOC' 1
#
# Read device C0:26:DA:01:DA:B1, basic debug flags enabled (using default auto-sec w/ keyboard iocap)
# ../scripts/run-dbt_scanner10.sh -dev C0:26:DA:01:DA:B1 -dbt_debug true
#
# Read device C0:26:DA:01:DA:B1, all debug flags enabled (using default auto-sec w/ keyboard iocap)
# ../scripts/run-dbt_scanner10.sh -dev C0:26:DA:01:DA:B1 -dbt_debug adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event
#
# To do a BT adapter removal/add via software, assuming the device is '1-4' (Bus 1.Port 4):
#   echo '1-4' > /sys/bus/usb/drivers/usb/unbind 
#   echo '1-4' > /sys/bus/usb/drivers/usb/bind 
# To retrieve Bus and Port:
#   lsusb -t
#
# Non root (we use the capsh solution per default):
#   Debian 11: Package libcap2-bin, version 1:2.44-1, binaries: /sbin/setcap /sbin/getcap
#   Depends: libc6 (>= 2.14), libcap2 (>= 1:2.33)
#
#   Using setcap (pass '-setcap' as 1st script argument):
#     sudo setcap 'cap_net_raw,cap_net_admin+eip' bin/dbt_scanner10
#     sudo getcap bin/dbt_scanner10
#
#   For debugging (must be explitly done):
#     sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/bin/strace
#     sudo setcap 'cap_sys_ptrace+eip' /usr/bin/gdb
#
#   Using capsh (default): 
#     sudo /sbin/capsh --caps="cap_net_raw,cap_net_admin+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
#        --keep=1 --user=nobody --addamb=cap_net_raw,cap_net_admin+eip \
#        -- -c "YOUR FANCY direct_bt STUFF"
#
# Root execution in case setcap/capsh fails (pass '-root' as 1st script argument):
#     sudo YOUR FANCY direct_bt STUFF
#

# Only reliable way, but Linux specific
THIS_SHELL=`readlink /proc/$$/exe`
#THIS_SHELL=`ps -hp $$ | awk '{ print $5 }'`
if [ "$(basename ${THIS_SHELL})" != "bash" ]; then
    echo "$0 must run in bash to preserve command-line quotes, not ${THIS_SHELL}"
    exit 1
fi

script_args="$@"

username=${USER}

sdir=`dirname $(readlink -f $0)`
rootdir=`dirname $sdir`
bname=`basename $0 .sh`

exename=`echo $bname | sed 's/^run-//g'`

if [ ! -e bin/${exename} -o ! -e lib/libdirect_bt.so ] ; then
    echo run from dist directory
    exit 1
fi

run_setcap=0
run_root=0
if [ "$1" = "-setcap" ] ; then
    run_setcap=1
    shift 1
elif [ "$1" = "-root" ] ; then
    run_root=1
    shift 1
fi

if [ "$1" = "-log" ] ; then
    logbasename=$2
    shift 2
else
    logbasename=~/$bname
fi

logfile=$logbasename.log
rm -f $logfile

valgrindlogfile=$logbasename-valgrind.log
rm -f $valgrindlogfile

callgrindoutfile=$logbasename-callgrind.out
rm -f $callgrindoutfile

echo 'core_%e.%p' | sudo tee /proc/sys/kernel/core_pattern
ulimit -c unlimited

# run as root 'dpkg-reconfigure locales' enable 'en_US.UTF-8'
# perhaps run as root 'update-locale LC_MEASUREMENT=en_US.UTF-8 LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8'
export LC_MEASUREMENT=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

# export EXE_WRAPPER="valgrind --tool=memcheck --leak-check=full --show-reachable=yes --track-origins=yes --malloc-fill=0xff --free-fill=0xfe --error-limit=no --default-suppressions=yes --suppressions=$sdir/valgrind.supp --gen-suppressions=all -s --log-file=$valgrindlogfile"
# export EXE_WRAPPER="valgrind --tool=memcheck --leak-check=full --show-leak-kinds=definite --track-origins=yes --malloc-fill=0xff --free-fill=0xfe --error-limit=no --default-suppressions=yes --suppressions=$sdir/valgrind.supp --gen-suppressions=all -s --log-file=$valgrindlogfile"
# export EXE_WRAPPER="valgrind --tool=helgrind --track-lockorders=yes  --ignore-thread-creation=yes --default-suppressions=yes --suppressions=$sdir/valgrind.supp --gen-suppressions=all -s --log-file=$valgrindlogfile"
# export EXE_WRAPPER="valgrind --tool=drd --segment-merging=no --ignore-thread-creation=yes --trace-barrier=no --trace-cond=no --trace-fork-join=no --trace-mutex=no --trace-rwlock=no --trace-semaphore=no --default-suppressions=yes --suppressions=$sdir/valgrind.supp --gen-suppressions=all -s --log-file=$valgrindlogfile"
# export EXE_WRAPPER="valgrind --tool=callgrind --instr-atstart=yes --collect-atstart=yes --collect-systime=yes --combine-dumps=yes --separate-threads=no --callgrind-out-file=$callgrindoutfile --log-file=$valgrindlogfile"

runit_root() {
    echo "sudo ... ${*@Q}"
    sudo -- bash -c "ulimit -c unlimited; LD_LIBRARY_PATH=`pwd`/lib $EXE_WRAPPER bin/${exename} ${*@Q}"
    exit $?
}

runit_setcap() {
    echo "sudo setcap ... " "$@"
    exe_file=$(readlink -f bin/${exename})
    echo "sudo setcap 'cap_net_raw,cap_net_admin+eip' ${exe_file}"
    trap 'sudo setcap -q -r '"${exe_file}"'' EXIT INT HUP QUIT TERM ALRM USR1
    sudo setcap 'cap_net_raw,cap_net_admin+eip' ${exe_file}
    sudo getcap ${exe_file}
    ulimit -c unlimited
    LD_LIBRARY_PATH=`pwd`/lib $EXE_WRAPPER ${exe_file} "$@"
    exit $?
}

runit_capsh() {
    echo "sudo capsh ... ${*@Q}"
    sudo /sbin/capsh --caps="cap_net_raw,cap_net_admin+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
        --keep=1 --user=$username --addamb=cap_net_raw,cap_net_admin+eip \
        -- -c "ulimit -c unlimited; LD_LIBRARY_PATH=`pwd`/lib "$EXE_WRAPPER" bin/${exename} ${*@Q}"
    exit $?
}

runit() {
    echo "script invocation: $0 ${script_args}"
    echo exename $exename
    echo username $username
    echo run_setcap ${run_setcap}
    echo run_root ${run_root}
    echo ${exename} commandline "$@"
    echo EXE_WRAPPER $EXE_WRAPPER
    echo logbasename $logbasename
    echo logfile $logfile
    echo valgrindlogfile $valgrindlogfile
    echo callgrindoutfile $callgrindoutfile
    echo direct_bt_debug $direct_bt_debug
    echo direct_bt_verbose $direct_bt_verbose

    echo LD_LIBRARY_PATH=`pwd`/lib $EXE_WRAPPER bin/${exename} "$@"
    mkdir -p client_keys
    mkdir -p server_keys

    if [ "${run_setcap}" -eq "1" ]; then
        runit_setcap "$@"
    elif [ "${run_root}" -eq "1" ]; then
        runit_root "$@"
    else
        runit_capsh "$@"
    fi
}

runit "$@" 2>&1 | tee $logfile