mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-03 17:41:58 +02:00
fix(ui): Never write the sudo password to a file; Update label on the progress screen
The askpass helper reads the password from a named pipe that the app feeds from memory each time sudo asks, instead of from a file.
This commit is contained in:
1 parent
11a91ef85c
commit
3c8ca65902
2 files changed
+35
-9
No files matched your search
+1
-1
@@ -858,7 +858,7 @@ ApplicationWindow {
|
|||||||
border.width: parent.parent.st === "wait" || parent.parent.st === "run" ? 2 : 0; border.color: parent.parent.st === "run" ? t.accent : "#343f50"
|
border.width: parent.parent.st === "wait" || parent.parent.st === "run" ? 2 : 0; border.color: parent.parent.st === "run" ? t.accent : "#343f50"
|
||||||
Text { anchors.centerIn: parent; text: parent.parent.parent.st === "ok" ? "✓" : (parent.parent.parent.st === "fail" ? "!" : ""); color: parent.parent.parent.st === "ok" ? t.good : t.bad; font.pixelSize: 13; font.weight: Font.Bold }
|
Text { anchors.centerIn: parent; text: parent.parent.parent.st === "ok" ? "✓" : (parent.parent.parent.st === "fail" ? "!" : ""); color: parent.parent.parent.st === "ok" ? t.good : t.bad; font.pixelSize: 13; font.weight: Font.Bold }
|
||||||
RotationAnimator on rotation { running: parent.parent.parent.st === "run"; from: 0; to: 360; duration: 1000; loops: Animation.Infinite } }
|
RotationAnimator on rotation { running: parent.parent.parent.st === "run"; from: 0; to: 360; duration: 1000; loops: Animation.Infinite } }
|
||||||
Text { text: ({ on: "Turn on ", off: "Turn off ", again: "Re-apply ", desktop: "Boot into ", gaming: "Boot into ", check: "Download and check the ", flash: "Hand to fwupd: the " })[parent.parent.modelData.action] + ((texts[parent.parent.modelData.id] || {}).label || parent.parent.modelData.id)
|
Text { text: (({ on: "Turn on ", off: "Turn off ", again: "Re-apply ", update: "Update ", desktop: "Boot into ", gaming: "Boot into ", check: "Download and check the ", flash: "Hand to fwupd: the " })[parent.parent.modelData.action] || "") + ((texts[parent.parent.modelData.id] || {}).label || parent.parent.modelData.id)
|
||||||
color: parent.parent.st === "wait" ? t.faint : t.textHi; font.family: t.body; font.pixelSize: 16; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter; width: 380; elide: Text.ElideRight }
|
color: parent.parent.st === "wait" ? t.faint : t.textHi; font.family: t.body; font.pixelSize: 16; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter; width: 380; elide: Text.ElideRight }
|
||||||
Text { text: ({ wait: "Waiting", run: "Working…", ok: "Done", fail: "Problem" })[parent.parent.st]; color: parent.parent.st === "ok" ? t.good : (parent.parent.st === "fail" ? t.bad : "#b8c3d1"); font.family: t.body; font.pixelSize: 13; anchors.verticalCenter: parent.verticalCenter }
|
Text { text: ({ wait: "Waiting", run: "Working…", ok: "Done", fail: "Problem" })[parent.parent.st]; color: parent.parent.st === "ok" ? t.good : (parent.parent.st === "fail" ? t.bad : "#b8c3d1"); font.family: t.body; font.pixelSize: 13; anchors.verticalCenter: parent.verticalCenter }
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-8
@@ -197,19 +197,19 @@ class Backend(QObject):
|
|||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
def _make_askpass(self, password):
|
def _make_askpass(self, password):
|
||||||
"""A private folder with the password, a helper that prints it for
|
"""A private folder with a helper that `sudo -A` runs for the
|
||||||
`sudo -A`, and a `sudo` that always uses the helper (makepkg and
|
password, and a `sudo` that always uses it (makepkg and yay call
|
||||||
yay call plain sudo)."""
|
plain sudo). The password is never written to a file: the helper
|
||||||
|
reads it from a named pipe, and the app writes it into the pipe from
|
||||||
|
memory each time sudo asks, until _drop_askpass."""
|
||||||
base = os.environ.get("XDG_RUNTIME_DIR") or tempfile.gettempdir()
|
base = os.environ.get("XDG_RUNTIME_DIR") or tempfile.gettempdir()
|
||||||
d = tempfile.mkdtemp(prefix="steamify-", dir=base)
|
d = tempfile.mkdtemp(prefix="steamify-", dir=base)
|
||||||
os.chmod(d, stat.S_IRWXU)
|
os.chmod(d, stat.S_IRWXU)
|
||||||
secret = os.path.join(d, "secret")
|
pipe = os.path.join(d, "pipe")
|
||||||
fd = os.open(secret, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
os.mkfifo(pipe, 0o600)
|
||||||
with os.fdopen(fd, "w") as f:
|
|
||||||
f.write(password + "\n")
|
|
||||||
askpass = os.path.join(d, "askpass")
|
askpass = os.path.join(d, "askpass")
|
||||||
with open(askpass, "w") as f:
|
with open(askpass, "w") as f:
|
||||||
f.write("#!/bin/sh\nexec cat %s\n" % json.dumps(secret))
|
f.write("#!/bin/sh\nexec cat %s\n" % json.dumps(pipe))
|
||||||
os.chmod(askpass, 0o700)
|
os.chmod(askpass, 0o700)
|
||||||
bindir = os.path.join(d, "bin")
|
bindir = os.path.join(d, "bin")
|
||||||
os.mkdir(bindir)
|
os.mkdir(bindir)
|
||||||
@@ -217,9 +217,35 @@ class Backend(QObject):
|
|||||||
with open(wrapper, "w") as f:
|
with open(wrapper, "w") as f:
|
||||||
f.write("#!/bin/sh\nexec /usr/bin/sudo -A \"$@\"\n")
|
f.write("#!/bin/sh\nexec /usr/bin/sudo -A \"$@\"\n")
|
||||||
os.chmod(wrapper, 0o700)
|
os.chmod(wrapper, 0o700)
|
||||||
|
stop = threading.Event()
|
||||||
|
data = (password + "\n").encode()
|
||||||
|
|
||||||
|
def serve():
|
||||||
|
while not stop.is_set():
|
||||||
|
try:
|
||||||
|
fd = os.open(pipe, os.O_WRONLY) # waits for a reader
|
||||||
|
except OSError:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
if not stop.is_set():
|
||||||
|
os.write(fd, data)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
threading.Thread(target=serve, daemon=True).start()
|
||||||
|
self._askpass_stop = (stop, pipe)
|
||||||
return d, askpass, bindir
|
return d, askpass, bindir
|
||||||
|
|
||||||
def _drop_askpass(self):
|
def _drop_askpass(self):
|
||||||
|
if getattr(self, "_askpass_stop", None):
|
||||||
|
stop, pipe = self._askpass_stop
|
||||||
|
self._askpass_stop = None
|
||||||
|
stop.set()
|
||||||
|
try: # wakes the writer waiting for a reader, which then ends
|
||||||
|
os.close(os.open(pipe, os.O_RDONLY | os.O_NONBLOCK))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
if self._secret_dir:
|
if self._secret_dir:
|
||||||
shutil.rmtree(self._secret_dir, ignore_errors=True)
|
shutil.rmtree(self._secret_dir, ignore_errors=True)
|
||||||
self._secret_dir = None
|
self._secret_dir = None
|
||||||
|
|||||||
Reference in new issue
Block a user