Insure that sshd is started. Provide more helpful messages through out the process for the person receiving assistance.

This commit is contained in:
Storm Dragon
2026-07-11 14:47:43 -04:00
parent 9bba576acf
commit 46de80a7af
+76 -5
View File
@@ -19,6 +19,7 @@ ircPort = 6667
ircChannel = "#stormux"
remoteHost = "billysballoons.com"
sasUser = "sas"
sshdService = "sshd"
pingIntervalSeconds = 180
pingCount = 5
maxWormholeFailures = 3
@@ -97,6 +98,32 @@ def run_as_user(userName, command, useSpeech, check=True):
return run_command(fullCommand, check=check)
def command_error_text(result):
return (result.stderr or result.stdout or "").strip()
def service_is_active(serviceName):
result = run_command(["systemctl", "is-active", "--quiet", serviceName])
return result.returncode == 0
def start_service(serviceName, useSpeech):
result = run_privileged(["systemctl", "start", serviceName], useSpeech, check=False)
if result.returncode == 0:
return
errorText = command_error_text(result)
if errorText:
raise RuntimeError(f"Failed to start {serviceName}: {errorText}")
raise RuntimeError(f"Failed to start {serviceName}")
def stop_service(serviceName, useSpeech):
result = run_privileged(["systemctl", "stop", serviceName], useSpeech, check=False)
if result.returncode == 0:
return True
return False
def user_exists(userName):
result = run_command(["getent", "passwd", userName])
return result.returncode == 0
@@ -351,13 +378,14 @@ def main():
tempDir = tempfile.mkdtemp(prefix="sas-ii-")
ircSession = None
sshProcess = None
sshdWasActiveAtStart = service_is_active(sshdService)
shouldStopSshdOnCleanup = False
def cleanup(exitMessage=None):
nonlocal cleanupDone
nonlocal cleanupDone, sshProcess
if cleanupDone:
return
cleanupDone = True
nonlocal sshProcess
if exitMessage:
say_or_print(exitMessage, useSpeech)
@@ -371,6 +399,20 @@ def main():
if ircSession:
ircSession.stop()
if shouldStopSshdOnCleanup:
say_or_print("Stopping sshd; it was not active when sas started.", useSpeech)
try:
if not stop_service(sshdService, useSpeech):
say_or_print(
"Cleanup warning: failed to stop sshd. Please stop it manually.",
useSpeech,
)
except Exception:
say_or_print(
"Cleanup warning: failed to stop sshd. Please stop it manually.",
useSpeech,
)
if shouldRemoveUser:
try:
run_privileged(["pkill", "-u", sasUser], useSpeech, check=False)
@@ -398,10 +440,24 @@ def main():
cleanup("Interrupted. Cleaning up.")
sys.exit(1)
signal.signal(signal.SIGINT, handle_signal)
signal.signal(signal.SIGTERM, handle_signal)
def ensure_sshd_active():
nonlocal shouldStopSshdOnCleanup
if service_is_active(sshdService):
shouldStopSshdOnCleanup = not sshdWasActiveAtStart
return
say_or_print("Starting sshd for this support session.", useSpeech)
start_service(sshdService, useSpeech)
if not service_is_active(sshdService):
raise RuntimeError("sshd did not become active")
shouldStopSshdOnCleanup = not sshdWasActiveAtStart
for signalName in ("SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"):
if hasattr(signal, signalName):
signal.signal(getattr(signal, signalName), handle_signal)
try:
say_or_print("Preparing your support session.", useSpeech)
if not user_exists(sasUser):
run_privileged(
["useradd", "-m", "-d", f"/home/{sasUser}", "-s", "/bin/bash", "-G", "wheel", sasUser],
@@ -443,7 +499,7 @@ def main():
ircSession.start()
ircSession.join_channel()
say_or_print("Waiting for assistance on IRC.", useSpeech)
say_or_print("Waiting for a Stormux assistant to respond.", useSpeech)
startTime = time.monotonic()
nextPingTime = startTime
pingsSent = 0
@@ -468,11 +524,18 @@ def main():
cleanup("No one was available to help, please try again later.")
return 1
say_or_print(
"An assistant has responded to your support request and should connect shortly.",
useSpeech,
)
ircSession.send_private_message(
confirmedAdmin,
f'password: "{password}" please send wormhole ssh invite code',
)
say_or_print("Exchanging secure connection information. This may take a moment.", useSpeech)
failures = 0
while failures < maxWormholeFailures:
inviteCode = None
@@ -500,6 +563,11 @@ def main():
say_or_print("Wormhole key transfer succeeded.", useSpeech)
break
say_or_print(
"That connection code did not work. Waiting for a new code from the assistant.",
useSpeech,
)
failures += 1
errorTextFull = (result.stderr or result.stdout or "").strip()
if errorTextFull and not useSpeech:
@@ -523,6 +591,8 @@ def main():
cleanup("Wormhole failed too many times. Exiting.")
return 1
ensure_sshd_active()
say_or_print("Starting reverse SSH tunnel. Press Ctrl+C to stop.", useSpeech)
sshCommand = [
"ssh",
@@ -548,6 +618,7 @@ def main():
sshCommand = ["sudo", "-u", sasUser, "-H"] + sshCommand
sshProcess = subprocess.Popen(sshCommand)
sshProcess.wait()
say_or_print("The support connection ended. Cleaning up.", useSpeech)
except Exception as exc:
cleanup(f"Error: {exc}")