oh-my-devpod 0.15.1 → 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/runtime/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.15.
|
|
1
|
+
0.15.3
|
package/runtime/bin/omd
CHANGED
|
Binary file
|
|
@@ -63,13 +63,21 @@ stat_mode() {
|
|
|
63
63
|
|
|
64
64
|
validate_manifest() {
|
|
65
65
|
local service_user manager_group expected_uid expected_gid actual_uid actual_gid installation_id
|
|
66
|
+
local schema resolved_prefix recorded_resolved_prefix
|
|
66
67
|
[[ -f "${manifest}" && ! -L "${manifest}" ]] || fail "missing or unsafe shared manifest"
|
|
67
|
-
|
|
68
|
+
schema="$(manifest_value schema_version || true)"
|
|
69
|
+
case "${schema}" in 1|2) ;; *) fail "unsupported shared manifest schema" ;; esac
|
|
68
70
|
[[ "$(manifest_value managed_by || true)" == "oh-my-devpod" ]] || fail "shared manifest ownership mismatch"
|
|
69
71
|
[[ "$(manifest_value mode || true)" == "shared-service-account" ]] || fail "shared manifest mode mismatch"
|
|
70
72
|
[[ "$(manifest_value prefix || true)" == "${prefix}" ]] || fail "shared prefix mismatch"
|
|
71
73
|
[[ -d "${prefix}" && ! -L "${prefix}" && -x "${real_brew}" ]] || fail "real Brew backend is unavailable"
|
|
72
|
-
|
|
74
|
+
resolved_prefix="$(cd "${prefix}" 2>/dev/null && pwd -P)" || fail "shared prefix cannot be resolved"
|
|
75
|
+
if [[ "${schema}" == "1" ]]; then
|
|
76
|
+
recorded_resolved_prefix="${prefix}"
|
|
77
|
+
else
|
|
78
|
+
recorded_resolved_prefix="$(manifest_value resolved_prefix || true)"
|
|
79
|
+
fi
|
|
80
|
+
[[ "${resolved_prefix}" == "${recorded_resolved_prefix}" ]] || fail "shared resolved prefix mismatch"
|
|
73
81
|
[[ "$(cd "${state_dir}" 2>/dev/null && pwd -P)" == "${state_dir}" ]] || fail "shared state resolves outside its fixed path"
|
|
74
82
|
[[ -d "${inventory_dir}" && ! -L "${inventory_dir}" ]] || fail "shared inventory is unavailable"
|
|
75
83
|
[[ -f "${lock_file}" && ! -L "${lock_file}" ]] || fail "shared mutation lock is unavailable"
|
|
@@ -239,6 +247,15 @@ run_real_brew() {
|
|
|
239
247
|
env -i "${clean_env[@]}" "${real_brew}" "$@"
|
|
240
248
|
}
|
|
241
249
|
|
|
250
|
+
prepare_backend_working_directory() {
|
|
251
|
+
local fallback="$1" current=""
|
|
252
|
+
current="$(pwd -P 2>/dev/null || true)"
|
|
253
|
+
if [[ -n "${current}" && -r "${current}" && -x "${current}" ]]; then
|
|
254
|
+
return 0
|
|
255
|
+
fi
|
|
256
|
+
cd -P "${fallback}" 2>/dev/null || fail "service home is not an accessible working directory"
|
|
257
|
+
}
|
|
258
|
+
|
|
242
259
|
run_backend() {
|
|
243
260
|
local home status mutates=0 before name value
|
|
244
261
|
if [[ "${1:-}" == "--omd-forwarded" ]]; then
|
|
@@ -273,6 +290,7 @@ run_backend() {
|
|
|
273
290
|
[[ "$(id -u)" == "$(manifest_value service_uid)" ]] || fail "backend must run as $(service_user)"
|
|
274
291
|
validate_inventory_records
|
|
275
292
|
home="$(service_home "$(service_user)")"
|
|
293
|
+
prepare_backend_working_directory "${home}"
|
|
276
294
|
before="${state_dir}/.inventory-before.$$"
|
|
277
295
|
if is_inventory_mutation "${1:-}"; then
|
|
278
296
|
mutates=1
|
|
@@ -95,6 +95,121 @@ path_has_no_symlink_components() {
|
|
|
95
95
|
done
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
trusted_storage_root() {
|
|
99
|
+
if [[ "${test_mode}" == "1" ]]; then
|
|
100
|
+
printf '%s\n' "${OHMYDEVPOD_SHARED_BREW_TEST_TRUSTED_STORAGE_ROOT:-/}"
|
|
101
|
+
else
|
|
102
|
+
printf '/\n'
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
trusted_storage_uid() {
|
|
107
|
+
if [[ "${test_mode}" == "1" ]]; then
|
|
108
|
+
printf '%s\n' "${OHMYDEVPOD_SHARED_BREW_TEST_TRUSTED_STORAGE_UID:-$(id -u)}"
|
|
109
|
+
else
|
|
110
|
+
printf '0\n'
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
trusted_storage_gid() {
|
|
115
|
+
if [[ "${test_mode}" == "1" ]]; then
|
|
116
|
+
printf '%s\n' "${OHMYDEVPOD_SHARED_BREW_TEST_TRUSTED_STORAGE_GID:-$(id -g)}"
|
|
117
|
+
else
|
|
118
|
+
printf '0\n'
|
|
119
|
+
fi
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
path_is_within() {
|
|
123
|
+
local path="$1" root="$2"
|
|
124
|
+
[[ "${path}" == "${root}" || "${path}" == "${root%/}"/* ]]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
trusted_storage_directory() {
|
|
128
|
+
local path="$1" expected_uid="$2" expected_gid="$3" mode
|
|
129
|
+
[[ -d "${path}" && ! -L "${path}" ]] || return 1
|
|
130
|
+
[[ "$(stat_uid "${path}")" == "${expected_uid}" ]] || return 1
|
|
131
|
+
mode="$(stat_mode "${path}")" || return 1
|
|
132
|
+
[[ "${mode}" =~ ^[0-7]{3,4}$ ]] || return 1
|
|
133
|
+
(( (8#${mode} & 8#002) == 0 )) || return 1
|
|
134
|
+
if (( (8#${mode} & 8#020) != 0 )); then
|
|
135
|
+
[[ "$(stat_gid "${path}")" == "${expected_gid}" ]] || return 1
|
|
136
|
+
fi
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
trusted_storage_parent_chain() {
|
|
140
|
+
local path="$1" root="$2" expected_uid="$3" expected_gid="$4"
|
|
141
|
+
local parent relative current part
|
|
142
|
+
parent="$(dirname "${path}")"
|
|
143
|
+
path_is_within "${parent}" "${root}" || return 1
|
|
144
|
+
trusted_storage_directory "${root}" "${expected_uid}" "${expected_gid}" || return 1
|
|
145
|
+
if [[ "${root}" == "/" ]]; then
|
|
146
|
+
relative="${parent#/}"
|
|
147
|
+
current="/"
|
|
148
|
+
elif [[ "${parent}" == "${root}" ]]; then
|
|
149
|
+
relative=""
|
|
150
|
+
current="${root}"
|
|
151
|
+
else
|
|
152
|
+
relative="${parent#"${root%/}/"}"
|
|
153
|
+
current="${root%/}"
|
|
154
|
+
fi
|
|
155
|
+
while IFS= read -r part; do
|
|
156
|
+
[[ -n "${part}" ]] || continue
|
|
157
|
+
if [[ "${current}" == "/" ]]; then
|
|
158
|
+
current="/${part}"
|
|
159
|
+
else
|
|
160
|
+
current="${current}/${part}"
|
|
161
|
+
fi
|
|
162
|
+
if [[ -L "${current}" ]]; then
|
|
163
|
+
[[ "$(stat_uid "${current}")" == "${expected_uid}" ]] || return 1
|
|
164
|
+
else
|
|
165
|
+
trusted_storage_directory "${current}" "${expected_uid}" "${expected_gid}" || return 1
|
|
166
|
+
fi
|
|
167
|
+
done < <(tr '/' '\n' <<< "${relative}")
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
trusted_prefix_parent_resolved() {
|
|
171
|
+
local candidate="$1" root expected_uid expected_gid parent resolved_parent resolved_candidate
|
|
172
|
+
[[ "${candidate}" == /* ]] || return 1
|
|
173
|
+
parent="$(dirname "${candidate}")"
|
|
174
|
+
[[ -d "${parent}" ]] || return 1
|
|
175
|
+
root="$(trusted_storage_root)"
|
|
176
|
+
root="$(cd "${root}" 2>/dev/null && pwd -P)" || return 1
|
|
177
|
+
expected_uid="$(trusted_storage_uid)"
|
|
178
|
+
expected_gid="$(trusted_storage_gid)"
|
|
179
|
+
[[ "${expected_uid}" =~ ^[0-9]+$ && "${expected_gid}" =~ ^[0-9]+$ ]] || return 1
|
|
180
|
+
trusted_storage_parent_chain \
|
|
181
|
+
"${candidate}" "${root}" "${expected_uid}" "${expected_gid}" || return 1
|
|
182
|
+
resolved_parent="$(cd "${parent}" 2>/dev/null && pwd -P)" || return 1
|
|
183
|
+
resolved_candidate="${resolved_parent%/}/$(basename "${candidate}")"
|
|
184
|
+
trusted_storage_parent_chain \
|
|
185
|
+
"${resolved_candidate}" "${root}" "${expected_uid}" "${expected_gid}" || return 1
|
|
186
|
+
printf '%s\n' "${resolved_candidate}"
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
trusted_prefix_resolved() {
|
|
190
|
+
local candidate="$1" resolved expected_resolved
|
|
191
|
+
[[ "${candidate}" == /* && -d "${candidate}" && ! -L "${candidate}" ]] || return 1
|
|
192
|
+
resolved="$(cd "${candidate}" 2>/dev/null && pwd -P)" || return 1
|
|
193
|
+
[[ "${resolved}" == /* && -d "${resolved}" && ! -L "${resolved}" ]] || return 1
|
|
194
|
+
if path_has_no_symlink_components "${candidate}"; then
|
|
195
|
+
[[ "${resolved}" == "${candidate}" ]] || return 1
|
|
196
|
+
printf '%s\n' "${resolved}"
|
|
197
|
+
return 0
|
|
198
|
+
fi
|
|
199
|
+
expected_resolved="$(trusted_prefix_parent_resolved "${candidate}")" || return 1
|
|
200
|
+
[[ "${resolved}" == "${expected_resolved}" ]] || return 1
|
|
201
|
+
printf '%s\n' "${resolved}"
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
prepare_prefix_parent() {
|
|
205
|
+
if path_has_no_symlink_components "$(dirname "${prefix}")"; then
|
|
206
|
+
ensure_safe_parent "${prefix}"
|
|
207
|
+
return 0
|
|
208
|
+
fi
|
|
209
|
+
trusted_prefix_parent_resolved "${prefix}" >/dev/null ||
|
|
210
|
+
fail "shared Brew prefix parent is not controlled by the trusted storage root"
|
|
211
|
+
}
|
|
212
|
+
|
|
98
213
|
ensure_safe_parent() {
|
|
99
214
|
local path="$1" parent
|
|
100
215
|
parent="$(dirname "${path}")"
|
|
@@ -198,7 +313,7 @@ ensure_accounts() {
|
|
|
198
313
|
prepare_state_layout() {
|
|
199
314
|
local service_uid service_gid
|
|
200
315
|
ensure_safe_parent "${state_dir}"
|
|
201
|
-
|
|
316
|
+
prepare_prefix_parent
|
|
202
317
|
path_has_no_symlink_components "${libexec_dir}" || fail "unsafe libexec path"
|
|
203
318
|
[[ ! -e "${state_dir}" || -d "${state_dir}" ]] || fail "shared state path is not a directory"
|
|
204
319
|
[[ ! -L "${state_dir}" ]] || fail "shared state path is a symlink"
|
|
@@ -341,7 +456,7 @@ legacy_home_for_user() {
|
|
|
341
456
|
validate_legacy_prefix() {
|
|
342
457
|
local owner_uid owner_gid owner owner_home marker marker_uid reported
|
|
343
458
|
[[ -d "${prefix}" && ! -L "${prefix}" && -x "${prefix}/bin/brew" ]] || fail "unmanaged-prefix-conflict: prefix is missing or unsafe"
|
|
344
|
-
|
|
459
|
+
trusted_prefix_resolved "${prefix}" >/dev/null || fail "unmanaged-prefix-conflict: prefix path is not controlled by the trusted storage root"
|
|
345
460
|
owner_uid="$(stat_uid "${prefix}")"
|
|
346
461
|
owner_gid="$(stat_gid "${prefix}")"
|
|
347
462
|
owner="$(user_for_uid "${owner_uid}")"
|
|
@@ -409,12 +524,14 @@ stage_legacy_inventory() {
|
|
|
409
524
|
}
|
|
410
525
|
|
|
411
526
|
write_manifest() {
|
|
412
|
-
local mirror_profile="$1" installation_id="$2" service_uid="$3" service_gid="$4" destination="$5"
|
|
527
|
+
local mirror_profile="$1" installation_id="$2" service_uid="$3" service_gid="$4" destination="$5" resolved_prefix
|
|
528
|
+
resolved_prefix="$(trusted_prefix_resolved "${prefix}")" || fail "shared Brew prefix path is not trusted"
|
|
413
529
|
{
|
|
414
|
-
printf 'schema_version=
|
|
530
|
+
printf 'schema_version=2\n'
|
|
415
531
|
printf 'managed_by=oh-my-devpod\n'
|
|
416
532
|
printf 'mode=shared-service-account\n'
|
|
417
533
|
printf 'prefix=%s\n' "${prefix}"
|
|
534
|
+
printf 'resolved_prefix=%s\n' "${resolved_prefix}"
|
|
418
535
|
printf 'service_user=%s\n' "${service_user}"
|
|
419
536
|
printf 'service_uid=%s\n' "${service_uid}"
|
|
420
537
|
printf 'manager_group=%s\n' "${manager_group}"
|
|
@@ -426,10 +543,11 @@ write_manifest() {
|
|
|
426
543
|
}
|
|
427
544
|
|
|
428
545
|
validate_existing_manifest() {
|
|
429
|
-
local expected_uid expected_gid
|
|
546
|
+
local expected_uid expected_gid schema resolved_prefix recorded_resolved_prefix
|
|
430
547
|
[[ -f "${manifest}" && ! -L "${manifest}" ]] || fail "shared manifest is missing or unsafe"
|
|
431
548
|
path_has_no_symlink_components "${state_dir}" || fail "shared state path contains a symlink"
|
|
432
|
-
|
|
549
|
+
schema="$(manifest_value schema_version || true)"
|
|
550
|
+
case "${schema}" in 1|2) ;; *) fail "unsupported shared manifest schema" ;; esac
|
|
433
551
|
[[ "$(manifest_value managed_by || true)" == "oh-my-devpod" ]] || fail "shared manifest ownership mismatch"
|
|
434
552
|
[[ "$(manifest_value mode || true)" == "shared-service-account" ]] || fail "shared manifest mode mismatch"
|
|
435
553
|
[[ "$(manifest_value prefix || true)" == "${prefix}" ]] || fail "shared manifest prefix mismatch"
|
|
@@ -441,9 +559,15 @@ validate_existing_manifest() {
|
|
|
441
559
|
[[ "$(manifest_value service_gid || true)" == "${expected_gid}" ]] || fail "shared manifest service GID mismatch"
|
|
442
560
|
[[ "$(manifest_value installation_id || true)" =~ ^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$ ]] || fail "shared manifest installation ID is invalid"
|
|
443
561
|
[[ -x "${prefix}/bin/brew" && ! -L "${prefix}" ]] || fail "shared Brew backend is missing or unsafe"
|
|
444
|
-
|
|
445
|
-
[[ "${
|
|
446
|
-
|
|
562
|
+
resolved_prefix="$(trusted_prefix_resolved "${prefix}")" || fail "shared Brew prefix path is not trusted"
|
|
563
|
+
if [[ "${schema}" == "1" ]]; then
|
|
564
|
+
recorded_resolved_prefix="${prefix}"
|
|
565
|
+
else
|
|
566
|
+
recorded_resolved_prefix="$(manifest_value resolved_prefix || true)"
|
|
567
|
+
fi
|
|
568
|
+
[[ "${resolved_prefix}" == "${recorded_resolved_prefix}" ]] || fail "shared Brew resolved prefix mismatch"
|
|
569
|
+
[[ "${test_mode}" == "1" || "$(stat_uid "${resolved_prefix}")" == "${expected_uid}" ]] || fail "shared Brew prefix owner mismatch"
|
|
570
|
+
[[ "${test_mode}" == "1" || "$(stat_gid "${resolved_prefix}")" == "${expected_gid}" ]] || fail "shared Brew prefix group mismatch"
|
|
447
571
|
if [[ "${test_mode}" != "1" ]]; then
|
|
448
572
|
[[ "$(stat_uid "${manifest}")" == "0" && "$(stat_gid "${manifest}")" == "0" ]] || fail "shared manifest is not root-owned"
|
|
449
573
|
(( (8#$(stat_mode "${manifest}") & 8#022) == 0 )) || fail "shared manifest is writable by non-root users"
|
|
@@ -108,12 +108,14 @@ omd_shared_linuxbrew_stat_mode() {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
omd_shared_linuxbrew_validate() {
|
|
111
|
-
local manifest prefix recorded_prefix
|
|
111
|
+
local manifest prefix recorded_prefix resolved_prefix recorded_resolved_prefix schema
|
|
112
|
+
local service_user manager_group installation_id
|
|
112
113
|
local expected_uid expected_gid actual_uid actual_gid
|
|
113
114
|
omd_shared_linuxbrew_enabled || return 1
|
|
114
115
|
manifest="$(omd_shared_linuxbrew_manifest)"
|
|
115
116
|
[[ -f "${manifest}" && ! -L "${manifest}" ]] || return 1
|
|
116
|
-
|
|
117
|
+
schema="$(omd_shared_linuxbrew_manifest_value schema_version || true)"
|
|
118
|
+
case "${schema}" in 1|2) ;; *) return 1 ;; esac
|
|
117
119
|
[[ "$(omd_shared_linuxbrew_manifest_value managed_by || true)" == "oh-my-devpod" ]] || return 1
|
|
118
120
|
[[ "$(omd_shared_linuxbrew_manifest_value mode || true)" == "shared-service-account" ]] || return 1
|
|
119
121
|
|
|
@@ -121,8 +123,13 @@ omd_shared_linuxbrew_validate() {
|
|
|
121
123
|
recorded_prefix="$(omd_shared_linuxbrew_manifest_value prefix || true)"
|
|
122
124
|
[[ "${recorded_prefix}" == "${prefix}" && "${prefix}" == /* && ! -L "${prefix}" ]] || return 1
|
|
123
125
|
[[ -d "${prefix}" && -x "${prefix}/bin/brew" ]] || return 1
|
|
124
|
-
|
|
125
|
-
[[ "${
|
|
126
|
+
resolved_prefix="$(cd "${prefix}" 2>/dev/null && pwd -P)" || return 1
|
|
127
|
+
if [[ "${schema}" == "1" ]]; then
|
|
128
|
+
recorded_resolved_prefix="${recorded_prefix}"
|
|
129
|
+
else
|
|
130
|
+
recorded_resolved_prefix="$(omd_shared_linuxbrew_manifest_value resolved_prefix || true)"
|
|
131
|
+
fi
|
|
132
|
+
[[ "${resolved_prefix}" == "${recorded_resolved_prefix}" ]] || return 1
|
|
126
133
|
|
|
127
134
|
service_user="$(omd_shared_linuxbrew_manifest_value service_user || true)"
|
|
128
135
|
manager_group="$(omd_shared_linuxbrew_manifest_value manager_group || true)"
|
|
@@ -140,8 +147,8 @@ omd_shared_linuxbrew_validate() {
|
|
|
140
147
|
actual_gid="$(omd_shared_linuxbrew_group_gid "${manager_group}" 2>/dev/null || true)"
|
|
141
148
|
fi
|
|
142
149
|
[[ "${actual_uid}" == "${expected_uid}" && "${actual_gid}" == "${expected_gid}" ]] || return 1
|
|
143
|
-
[[ "$(omd_shared_linuxbrew_stat_uid "${
|
|
144
|
-
[[ "$(omd_shared_linuxbrew_stat_gid "${
|
|
150
|
+
[[ "$(omd_shared_linuxbrew_stat_uid "${resolved_prefix}")" == "${expected_uid}" ]] || return 1
|
|
151
|
+
[[ "$(omd_shared_linuxbrew_stat_gid "${resolved_prefix}")" == "${expected_gid}" ]] || return 1
|
|
145
152
|
if ! omd_shared_linuxbrew_test_mode; then
|
|
146
153
|
[[ "$(omd_shared_linuxbrew_stat_uid "${manifest}")" == "0" ]] || return 1
|
|
147
154
|
[[ "$(omd_shared_linuxbrew_stat_gid "${manifest}")" == "0" ]] || return 1
|