CH-J Toolsgestione server su SSH
Menu

Salvataggio dell'editor remoto e monitoraggio della latenza

Scarica file

La revisione linguistica di questa traduzione è in corso. In caso di dubbi, consultare l’originale inglese.

Cause della radice

L'editor precedente ha caricato il suo file di lavoro nella directory madre del target, che spesso non può essere scritto dall'account SSH sotto /etc o /var . SFTP rinomina non ha fornito alcun percorso sudo autorizzato, controllo di conflitto di base, verifica dei metadati di sicurezza o semantica di sovrascrittura affidabile. Il gestore errore ha eliminato la copia temporanea, rimuovendo il materiale di recupero anche quando il completamento era incerto.

Stato della sessione precedentemente esposto solo lo stato della connessione. Non c'era una misura di risposta ICMP o autenticata SSH che alimentasse l'indicatore terminale.

Salva protocollo

  1. Un helper SSH fisso apre un file regolare con un collegamento singolo usando il descrittore-relativo operazioni e O_NOFOLLOW per ogni componente del percorso. Cattura il contenuto, hash SHA-256, device/inode, UID, GID, bit di autorizzazione completi, tempi di modifica/cambio nanosecondi e tutti gli attributi estesi leggibili. Core verifica l'hash e decodifica UTF-8 rigoroso, conservando un BOM. Ogni documento ottiene un editId opaco, per il suo plugin, la sessione del terminale e l'identità del server.
  2. Un'operazione di preparazione non privilegiata risolve il conto autenticato home attraverso pwd.getpwuid(os.getuid()) , crea $HOME/ch-j-sm/ con la modalità 0700 e crea un diario di recupero privato ed esclusivo. Viene rifiutata una casa non sicura, un workspace di collegamento simbolico o uno spazio di lavoro di proprietà di un altro account.
  3. Core carica un file di lavoro 128-bit .tmp nascosto e casuale tramite SFTP con creazione esclusiva ( wx ), modalità 0600 e un timeout di 60 secondi/upload. Il diario contiene l'obiettivo, la linea di base originale e l'hash di lavoro previsto; non contiene credenziali.
  4. One SSH esegue l'intera finalizzazione , opzionalmente attraverso il Esecutore sudo esistente. L'aiutante si apre in modo sicuro e hash la copia di lavoro privata e lo sciacquone. Blocca l'inode originale, controlla la sua linea di base, crea un file di destinazione esclusivo accanto all'obiettivo, scrive tutto il contenuto, applica e verifica i metadati, controlla l'originale nuovamente, e ripulisce la sostituzione.
  5. Una stessa directory os.replace sostituisce atomicamente l'obiettivo. Il genitore la directory viene ripulita e vengono verificati il percorso finale, l'hash, l'inode e i metadati. Il percorso originale rimane disponibile fino alla sostituzione. Il file di lavoro non viene mai spostato attraverso i filesystem e non viene mai rimosso dalla finalizzazione.
  6. Dopo Core riceve un successo verificato, una pulizia separata ricontrolla la finale metadati di contenuto e sicurezza prima di rimuovere il file di lavoro e il diario. Un guasto alla pulizia segnala ancora un salvataggio confermato con recoveryAvailable: true .

Un upload fallito, un sudo fallito, un conflitto, un errore di metadati o una sostituzione non riuscita mantengono il materiale originale e qualsiasi materiale messo in scena. Gli upload incompleti sono identificati come tali e non possono essere recuperati come un documento modificato completo. Comunicazione SSH persa, stato di uscita mancante, timeout e risultati di finalizzazione inaspettati sono segnalati come unknown , mai come salvato. Il core blocca un altro salvataggio su un documento incerto; non c'è nessuna prova automatica di sostituzione.

Metadati, privilegi e limiti di sicurezza

L'helper conserva e verifica i bit UID, GID e tutti i permessi POSIX, inclusi i bit eseguibili, setuid, setgid e appiccicosi. Riproduce il byte degli attributi estesi Linux per byte, inclusi gli ACL POSIX, le funzionalità e le etichette SELinux. La proprietà e il contenuto dei file sono impostati prima degli attributi di sicurezza, perché writes/chown può cancellare le funzionalità o bit permessi speciali. Gli attributi di destinazione ereditati che sono assenti sull'originale vengono rimossi. Il tempo di modifica riflette la nuova scrittura e non è copiato dall'originale.

Un attributo illeggibile o irraggiungibile interrompe l'operazione; i metadati non vengono rifiutati in silenzio. Le firme IMA/EVM sono esplicitamente rifiutate perché copiare le firme di integrità con contenuto/inode li invalida. Simlink nel percorso di destinazione o home, file hard-linked e file non regolari sono rifiutati. Non viene utilizzato alcun ripiego in luogo o più debole SFTP.

I salvataggi scrivibili ordinari vengono eseguiti come account SSH. I salvataggi protetti richiedono { sudo: true } esplicito; una password sudo è opzionale per il sudo senza passwoword. Le password vengono convalidate e passate solo su stdin canale, mai all'interno del comando, diario, file di lavoro, logger o errore remoto. Le sessioni di Root SSH usano l'eseguitore diretto di root esistente. L'autorizzazione non riuscita lascia intatta la copia originale e funzionante. Tutti i salva eseguiti come root (direct root SSH o sudo) rifiutano anche directory/antenati di destinazione posseduti o scrivibili da altri account, o portano un accesso ACL, piuttosto che fidarsi di un nome di percorso privilegiato controllato da un altro account.

L'helper fisso viene eseguito con python3 -I -B : ignora i percorsi Python dell'utente, la directory di lavoro e i pacchetti del sito utente, e non scrive alcun bytecode. I percorsi e gli argomenti JSON sono citati nella shell Core. I plugin non ricevono mai arbitrarie SSH exec o SFTP maniglie. La sandbox esistente, CSP, i permessi di manifestazione, la verifica host-key e la verifica dell'aggiornamento rimangono in uso.

Plugin API e integrazione di Monaco

L'interfaccia utente Monaco/File Manager distribuita separatamente è assente da questo checkout. L'integrazione dell'interfaccia utente, il prompt sudo, la gestione di buffer sporchi e le traduzioni non possono essere implementate o testate qui. La sorgente del plugin in bundle è il plug-in Hash & Checksum. Non è stato inventato alcun sorgente di File Manager sostitutivo.

I metodi esistenti rimangono disponibili. I metodi/le opzioni di additivo sono esposti dal precarico sandboxed e dal runtime controllato con autorizzazione:

const opened = await chjPlugin.files.readText(sessionId, path);
// For a protected read, explicitly pass { sudo: true, sudoPassword }.

const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), {
  editId: opened.editId,
  sudo: true,           // Include only after the user authorizes elevation.
  sudoPassword         // Omit for passwordless sudo; never persist this value.
});

if (result.ok && result.value.status === "saved") {
  // Mark this exact submitted editor version as saved. Later edits stay dirty.
} else {
  // Keep the Monaco model dirty. Translate result.error.code/status.
  // result.error.recoveryId/recoveryPath identify retained working material.
}

await chjPlugin.files.closeText(opened.editId);
const recovery = await chjPlugin.files.listRecovery(sessionId);
const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId);
// Review copy.status and copy.text; open a fresh document before another save.
await chjPlugin.files.cleanupRecovery(sessionId, recoveryId);
// Cleanup rejects anything whose target is not currently confirmed.

I metodi di recupero accettano un argomento { sudo: true, sudoPassword } finale opzionale durante l'ispezione di un obiettivo richiede elevazione. Conservano lo spazio di lavoro dell'utente autenticato anche quando eseguito tramite sudo. I giornali sopravvivono al riavvio dell'app e alla riconnessione di SSH; il recupero non ripete mai automaticamente la finalizzazione. Rivedere un buffer recuperato contro un obiettivo appena aperto prima di salvarlo esplicitamente.

Le guardie files.read leggono, ispezionano e gestiscono il rilascio. Le protezioni files.write salvano e ripuliscono il recupero. writeText rifiuta ancora il fallimento per i plugin esistenti; saveText restituisce una busta strutturata { ok, value/error } perché Electron rilascia proprietà personalizzate sugli oggetti di errore rifiutati. Un'eredità a tre argomenti writeText può usare il basale di un singolo documento aperto. Diversi documenti live per lo stesso percorso richiedono editId ; le chiamate legacy ambigue falliscono in modo sicuro invece di scegliere la linea di base di un altro documento. I plugin devono rilasciare le maniglie non utilizzate.

L'interfaccia utente esterna deve visualizzare immediatamente il salvataggio, mantenere i buffer sporchi sul fallimento, offrire sudo solo dopo l'autorizzazione/autenticazione guasti, mostrare conflitti senza sovrascrittura, e offrire recupero dopo perdita di connessione o un risultato sconosciuto. Deve tradurre questi stati in ceco, tedesco e inglese. Copia di stato suggerita:

StateCzechGermanEnglish
SavingUkládání…Wird gespeichert…Saving…
ConfirmedUloženoGespeichertSaved
FailureUložení selhaloSpeichern fehlgeschlagenSave failed
Sudo requiredVyžadováno oprávnění sudosudo-Autorisierung erforderlichSudo authorization required
ConflictPůvodní soubor byl změněnOriginaldatei wurde geändertOriginal file changed
DisconnectedSpojení bylo přerušenoVerbindung unterbrochenConnection lost
UnknownVýsledek uložení není známSpeicherergebnis unbekanntSave result unknown
RecoveryObnova je dostupnáWiederherstellung verfügbarRecovery available

Definizioni di latenza e ciclo di vita

Ping è la latenza segnalata da una reale risposta ICMP echo client-side all'IP risolto utilizzato da SSH. Core invoca la piattaforma ping eseguibile asincronamente con un array di argomenti fisso, senza bisogno di avvio di shell o amministratore. Gli argomenti Linux, macOS (inclusi ping6 ) e Windows sono selezionati separatamente. Bloccato ICMP, un eseguibile mancante, un timeout, output non valido o una risposta Windows solo in alto, come <1ms producono un valore non disponibile, non un numero inventato.

SSH RTT è la durata monotona performance.now() di una richiesta exec fissa true sul client SSH autenticato esistente. Esso include l'impostazione del canale, l'elaborazione del server e la consegna delle risposte; non è pura rete RTT o SSH durata di accesso. Il suggerimento dell'indicatore tradotto spiega questa distinzione.

Il monitoraggio inizia non appena il terminale si connette. Le sonde corrono simultaneamente e in modo asincrono, con un timeout di cinque secondi per la richiesta/processo. Il campione successivo è programmato dodici secondi dopo che il campione precedente ha completato, evitando sovrapposizioni. Disconnetti aborti ICMP, cancella i timer, annulla il lavoro in attesa di SSH e cancella i valori. Registrare i controlli di identità impedisce una connessione precedente dalla pubblicazione dopo la riconnettersi. Il fallimento ICMP non cambia mai lo stato della connessione SSH.

La latenza viaggia all'interno dell'evento state esistente / ssh:state IPC payload:

latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }

I numeri non disponibili sono null . L'indicatore morsetto compatto utilizza millisecondi, testo non disponibile localizzato ed etichette Czech/German/English. Si nasconde sulla disconnessione. Non era necessaria alcuna capacità di esecuzione del render o richiesta IPC.

Convalida e limiti operativi

L'utente ha richiesto di mantenere le modifiche nell'albero di lavoro esistente, attualmente feature/hash-checksum-plugin ; non è stato eseguito alcun interruttore di ramo o pulizia indipendente.

File modificati per questa attività