-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·280 lines (240 loc) · 8.03 KB
/
install.sh
File metadata and controls
executable file
·280 lines (240 loc) · 8.03 KB
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#!/bin/bash
set -o pipefail
executable=linux-id
release_url="https://github.com/matejsmycka/linux-id/releases/latest/download/linux-id_Linux_x86_64.tar.gz"
script_dir="$(cd "$(dirname "$0")" && pwd)"
auth_mode="pinentry"
function usage() {
cat <<EOF
Usage: $0 [--auth pinentry|fprintd] [-h|--help]
Options:
--auth pinentry Confirm presence with a click dialog (default).
--auth fprintd Confirm presence with a fingerprint scan.
Requires fprintd installed and a fingerprint enrolled
via 'fprintd-enroll'. Sets the WebAuthn UV flag.
-h, --help Show this help.
EOF
}
while [ $# -gt 0 ]; do
case "$1" in
--auth)
auth_mode="$2"
shift 2
;;
--auth=*)
auth_mode="${1#--auth=}"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
done
case "$auth_mode" in
pinentry|fprintd) ;;
*)
echo "Invalid --auth value: $auth_mode (must be 'pinentry' or 'fprintd')" >&2
exit 1
;;
esac
if [ "$auth_mode" = "fprintd" ]; then
auth_arg=" --auth fprintd"
else
auth_arg=""
fi
function handle() {
if [ $? -ne 0 ]; then
echo "$1" >&2
exit 1
fi
}
function check_prereqs() {
if [ ! -d /sys/class/tpm/tpm0 ]; then
echo "TPM is not present, make sure to enable it in BIOS/UEFI" >&2
exit 1
fi
# Either we're in a source clone (go.mod + go) and build, or we download
# the latest release tarball with curl/wget. No stale local binary path,
# so re-running install.sh always picks up the latest published version.
if [ -f "$script_dir/go.mod" ] && command -v go &>/dev/null; then
:
elif command -v curl &>/dev/null || command -v wget &>/dev/null; then
:
else
echo "Need (go.mod + go) to build, or curl/wget to download the binary" >&2
exit 1
fi
if ! command -v pinentry &>/dev/null; then
echo "pinentry is not installed, please install it" >&2
exit 1
fi
if [ "$auth_mode" = "fprintd" ] && ! command -v fprintd-enroll &>/dev/null; then
echo "--auth fprintd requested but fprintd is not installed" >&2
echo "Install fprintd first, then run 'fprintd-enroll' to enroll a finger" >&2
exit 1
fi
if ! command -v systemctl &>/dev/null; then
echo "systemctl not found — systemd is required" >&2
exit 1
fi
}
function check_aur_install() {
if command -v pacman &>/dev/null && pacman -Q linux-id &>/dev/null; then
echo "linux-id is already installed via the AUR package." >&2
echo "Use 'sudo pacman -R linux-id' first if you want to switch to install.sh." >&2
exit 1
fi
}
function migrate_old_install() {
local old_autostart="/home/$USER/.config/autostart/linux-id.desktop"
if [ -f "$old_autostart" ]; then
echo "Removing old autostart entry: $old_autostart"
rm -f "$old_autostart"
fi
local old_user_unit="/home/$USER/.config/systemd/user/linux-id.service"
if [ -f "$old_user_unit" ]; then
echo "Removing old user systemd unit: $old_user_unit"
systemctl --user disable linux-id.service 2>/dev/null || true
rm -f "$old_user_unit"
fi
if [ -f /usr/local/bin/linux-id ]; then
echo "Removing old binary: /usr/local/bin/linux-id"
sudo rm -f /usr/local/bin/linux-id
fi
if [ -f /etc/udev/rules.d/70-uhid.rules ]; then
echo "Removing old udev rule: /etc/udev/rules.d/70-uhid.rules"
sudo rm -f /etc/udev/rules.d/70-uhid.rules
fi
if [ -f /etc/modules-load.d/uhid.conf ]; then
echo "Removing old modules-load entry: /etc/modules-load.d/uhid.conf"
sudo rm -f /etc/modules-load.d/uhid.conf
fi
if id -nG "$USER" | grep -qw tss; then
echo "Note: user is still in the 'tss' group from a previous install."
echo " The new udev rule no longer needs it; you may run:"
echo " sudo gpasswd -d $USER tss"
fi
if pgrep -x linux-id >/dev/null; then
echo "Stopping existing linux-id process"
pkill -x linux-id || true
fi
}
function make_executable() {
local source_binary
if [ -f "$script_dir/go.mod" ] && command -v go &>/dev/null; then
echo "Building $executable from source in $script_dir"
( cd "$script_dir" && go build -o "$executable" )
handle "Failed to build executable with go"
source_binary="$script_dir/$executable"
else
local tmp
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
echo "Downloading latest binary from $release_url"
if command -v curl &>/dev/null; then
curl -fsSL "$release_url" | tar -xz -C "$tmp"
else
wget -qO- "$release_url" | tar -xz -C "$tmp"
fi
handle "Failed to download or extract the prebuilt binary"
if [ ! -f "$tmp/$executable" ]; then
echo "Tarball did not contain '$executable':" >&2
ls -la "$tmp" >&2
exit 1
fi
source_binary="$tmp/$executable"
fi
sudo install -Dm755 "$source_binary" /usr/bin/"$executable"
handle "Failed to install executable to /usr/bin"
}
function install_unit_and_rules() {
sudo install -Dm644 /dev/stdin /usr/lib/systemd/user/linux-id.service <<EOF
[Unit]
Description=linux-id TPM service
Documentation=https://github.com/matejsmycka/linux-id
Wants=modprobe@uhid.service
After=modprobe@uhid.service
ConditionSecurity=tpm2
ConditionKernelModuleLoaded=uhid
[Service]
Type=simple
ExecStart=/usr/bin/linux-id${auth_arg}
ProtectProc=noaccess
# pinentry may need to access /run/user/\$UID/wayland-0
BindReadOnlyPaths=%t
# pinentry may need to access /tmp/.X11-unix
BindReadOnlyPaths=%T/.X11-unix
# pinentry may need to write here
BindPaths=%E
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=tmpfs
PrivateTmp=true
PrivateNetwork=true
PrivatePIDs=true
PrivateUsers=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
# pinentry may need to connect to wayland/x11 socket
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictRealtime=true
RestrictSUIDSGID=true
PrivateMounts=true
DeviceAllow=/dev/tpmrm0
DeviceAllow=/dev/uhid
[Install]
WantedBy=default.target
EOF
handle "Failed to install systemd unit"
sudo install -Dm644 /dev/stdin /usr/lib/udev/rules.d/60-linux-id-fido-tpm.rules <<'EOF'
# Allow user access tpmrm0 and uhid
KERNEL=="uhid", SUBSYSTEM=="misc", TAG+="uaccess"
KERNEL=="tpmrm0", SUBSYSTEM=="tpmrm", TAG+="uaccess"
EOF
handle "Failed to install udev rules"
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=misc --subsystem-match=tpmrm
}
function enable_user_service() {
if ! systemctl --user daemon-reload 2>/dev/null; then
echo
echo "WARNING: could not reach your user systemd instance from this shell." >&2
echo "Log back in to your desktop session, then run:" >&2
echo " systemctl --user daemon-reload" >&2
echo " systemctl --user enable --now linux-id.service" >&2
echo " systemctl --user status linux-id.service" >&2
return
fi
systemctl --user enable linux-id.service
handle "Failed to enable linux-id.service"
if ! systemctl --user restart linux-id.service; then
echo "WARNING: linux-id.service did not start cleanly. See status below." >&2
fi
echo
echo "linux-id.service status:"
echo "------------------------"
systemctl --user --no-pager status linux-id.service || true
}
echo "Installing linux-id (auth=$auth_mode)"
check_prereqs
check_aur_install
migrate_old_install
make_executable
install_unit_and_rules
enable_user_service
echo
echo "Installation successful (auth=$auth_mode). Log out and back in (or reboot)"
echo "so the new udev rules and user systemd unit are picked up."