Repository navigation
Expand file tree
/
Copy pathlsshm.ps1
More file actions
2669 lines (2507 loc) · 123 KB
/
Copy pathlsshm.ps1
File metadata and controls
2669 lines (2507 loc) · 123 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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#Requires -Version 5.1
<#
.SYNOPSIS
LSSHM - Local SSH Manager (Windows / PowerShell)
.DESCRIPTION
Local OpenSSH management on Windows: SSH server, incoming access,
outgoing keys and remote hosts. Menu-driven CLI, no external
dependency. Same concepts and menus as the Bash/Linux version.
The interface language is selectable (English, French, Spanish) and is
stored in the configuration file. It defaults to the detected system
language, falling back to English.
.NOTES
Version aligned with the repository VERSION file.
Windows OpenSSH paths:
%ProgramData%\ssh\sshd_config
%ProgramData%\ssh\administrators_authorized_keys
%USERPROFILE%\.ssh\
#>
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# =============================================================================
# Constants and state
# =============================================================================
$script:LSSHM_VERSION = '0.4.1'
$script:LSSHM_NAME = 'LSSHM'
$script:LSSHM_LONG_NAME = 'LSSHM - Local SSH Manager'
$script:LSSHM_REPO_RAW = if ($env:LSSHM_REPO_RAW) { $env:LSSHM_REPO_RAW } else { 'https://raw.githubusercontent.com/sannier3/lsshm/preview' }
$script:LSSHM_ASSUME_YES = $false
$script:LSSHM_TARGET_USER = $null
$script:LSSHM_LANG = 'en'
$script:LSSHM_LANG_OVERRIDE = ''
# =============================================================================
# Internationalization (message catalogs + language selection)
# =============================================================================
# Source strings are written in English (the msgid). Translations live in
# per-language hashtables keyed by the English msgid. A missing translation
# falls back to English. Format strings use .NET placeholders ({0}, {1}, ...).
$script:LSSHM_LANGS = @('en', 'fr', 'es')
$script:LSSHM_MSG_fr = @{
# Prompts / common
'Press Enter to continue' = 'Appuyez sur Entree pour continuer'
'Choice' = 'Choix'
'Invalid choice.' = 'Choix invalide.'
'Cancelled.' = 'Annule.'
'No change.' = 'Aucun changement.'
'yes' = 'oui'
'no' = 'non'
'not set' = 'non defini'
'present' = 'presente'
'absent' = 'absente'
'unknown' = 'inconnue'
'forbidden' = 'interdit'
'key only' = 'cle uniquement'
'key or password' = 'cle ou mot de passe'
'forced commands only' = 'commandes imposees'
'active' = 'actif'
'inactive' = 'inactif'
# Language
'Language set to: {0}' = 'Langue definie sur : {0}'
'Change the language' = 'Changer la langue'
# Privileges
'This operation requires PowerShell as administrator.' = 'Cette operation necessite PowerShell en administrateur.'
'Relaunch: Start-Process powershell -Verb RunAs' = 'Relancez : Start-Process powershell -Verb RunAs'
'Elevation required' = 'Elevation requise'
# Status panel
'SSH server status: {0}' = 'Etat du serveur SSH : {0}'
'Port: {0}' = 'Port : {0}'
'Root / admin access: {0}' = 'Acces root / admin : {0}'
'Password authentication: {0}' = 'Authentification par mot de passe : {0}'
'Administrator keys (administrators_authorized_keys): {0}' = 'Cles administrateurs (administrators_authorized_keys) : {0}'
'Private keys of user {0}: {1}' = 'Cles privees de l''utilisateur {0} : {1}'
'Registered remote hosts: {0}' = 'Machines distantes enregistrees : {0}'
# Server status
'OpenSSH Server is not installed (sshd.exe not found).' = 'OpenSSH Server n''est pas installe (sshd.exe introuvable).'
'Auto-start : {0}' = 'Demarrage auto : {0}'
'Port : {0}' = 'Port : {0}'
'Admin access : {0}' = 'Acces admin : {0}'
'Password auth : {0}' = 'Auth. mot de passe : {0}'
'Key auth : {0}' = 'Auth. par cle : {0}'
'Config : {0}' = 'Config : {0}'
# Server install / actions
'OpenSSH Server already present: {0}' = 'OpenSSH Server deja present : {0}'
'Installing OpenSSH.Server (optional Windows feature)...' = 'Installation de OpenSSH.Server (fonctionnalite facultative Windows)...'
'OpenSSH Server installed.' = 'OpenSSH Server installe.'
'Installation failed. Try: Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0' = 'Installation echouee. Essayez : Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0'
'SSH service started.' = 'Service SSH demarre.'
'SSH service stopped.' = 'Service SSH arrete.'
'SSH service restarted.' = 'Service SSH redemarre.'
'Automatic startup: {0}' = 'Demarrage automatique : {0}'
'sshd not found.' = 'sshd introuvable.'
'Configuration valid (sshd -t).' = 'Configuration valide (sshd -t).'
'Invalid configuration.' = 'Configuration invalide.'
'No server configuration to back up.' = 'Aucune configuration serveur a sauvegarder.'
'Backup created: {0}' = 'Sauvegarde creee : {0}'
'File not found: {0}' = 'Fichier introuvable : {0}'
'Invalid configuration: restore a backup if needed.' = 'Configuration invalide : restaurez une sauvegarde si besoin.'
'Directive applied: {0} {1}' = 'Directive appliquee : {0} {1}'
# Root login menu
'Administrator / root SSH login' = 'Connexion SSH administrateur / root'
' 1. Forbid entirely' = ' 1. Interdire totalement'
' 2. Allow with a key only' = ' 2. Autoriser uniquement avec une cle'
' 3. Allow with a key or a password' = ' 3. Autoriser avec une cle ou un mot de passe'
' 4. Allow only for forced commands' = ' 4. Autoriser uniquement pour des commandes imposees'
'Apply this sensitive change?' = 'Appliquer ce changement sensible ?'
# Access
'File: {0}' = 'Fichier : {0}'
'No authorized key.' = 'Aucune cle autorisee.'
'Paste the public key (one line) or a .pub path' = 'Collez la cle publique (une ligne) ou chemin .pub'
'Key added to {0}' = 'Cle ajoutee dans {0}'
'.ssh not found.' = '.ssh introuvable.'
'.ssh permissions repaired (Windows ACL).' = 'Permissions .ssh reparees (ACL Windows).'
# Local keys
'Directory: {0}' = 'Repertoire : {0}'
'No key pair detected.' = 'Aucune paire de cles detectee.'
' Public : {0}' = ' Publique : {0}'
' Private : {0}' = ' Privee : {0}'
' Fingerprint: {0}' = ' Empreinte: {0}'
'Choose a key' = 'Choisir une cle'
'Private key not found: {0}' = 'Cle privee introuvable : {0}'
'Key not found: {0}' = 'Cle introuvable : {0}'
'{0} (number)' = '{0} (numero)'
'Invalid choice: {0}' = 'Choix invalide : {0}'
'Number out of range (1-{0}).' = 'Numero hors plage (1-{0}).'
'Private key missing for {0}.' = 'Cle privee absente pour {0}.'
'Key type (ed25519/rsa)' = 'Type de cle (ed25519/rsa)'
'File name' = 'Nom du fichier'
'Comment' = 'Commentaire'
'Key generated: {0}' = 'Cle generee : {0}'
'Generation failed.' = 'Echec de la generation.'
'Key to inspect' = 'Cle a inspecter'
'Key to export' = 'Cle a exporter'
'Public key not found: {0}' = 'Cle publique introuvable : {0}'
'Public key ({0}):' = 'Cle publique ({0}) :'
'Key to delete' = 'Cle a supprimer'
'Deleting the key pair:' = 'Suppression de la paire de cles :'
'A backup will be created. Confirm deletion?' = 'Une sauvegarde sera creee. Confirmer la suppression ?'
'Key pair deleted (backup kept).' = 'Paire de cles supprimee (sauvegarde conservee).'
# ssh-agent
'No ssh-agent detected. On Windows: Get-Service ssh-agent ; Start-Service ssh-agent' = 'Aucun ssh-agent detecte. Sous Windows : Get-Service ssh-agent ; Start-Service ssh-agent'
'Key to add to ssh-agent' = 'Cle a ajouter a ssh-agent'
'Key added to ssh-agent.' = 'Cle ajoutee a ssh-agent.'
'Failed.' = 'Echec.'
'Remove all keys from the agent?' = 'Retirer toutes les cles de l''agent ?'
'All keys removed.' = 'Toutes les cles retirees.'
'Key to remove from ssh-agent' = 'Cle a retirer de ssh-agent'
'Key removed from ssh-agent.' = 'Cle retiree de ssh-agent.'
# Hosts
'No remote host in ~/.ssh/config.' = 'Aucune machine distante dans ~/.ssh/config.'
'Remote hosts ({0}):' = 'Machines distantes ({0}) :'
'Host alias' = 'Nom (alias)'
'Name required.' = 'Nom requis.'
'A host ''{0}'' already exists.' = 'Un hote ''{0}'' existe deja.'
'Address (HostName)' = 'Adresse (HostName)'
'User' = 'Utilisateur'
'Port' = 'Port'
'Key file' = 'Fichier de cle'
'Host ''{0}'' added.' = 'Hote ''{0}'' ajoute.'
'Host name to delete' = 'Nom de l''hote a supprimer'
'Host not found: {0}' = 'Hote introuvable : {0}'
'Delete host ''{0}''?' = 'Supprimer l''hote ''{0}'' ?'
'Host ''{0}'' deleted.' = 'Hote ''{0}'' supprime.'
'Host name to test' = 'Nom de l''hote a tester'
'Resolving {0}...' = 'Resolution de {0}...'
'DNS resolution succeeded.' = 'Resolution DNS reussie.'
'DNS resolution uncertain.' = 'Resolution DNS incertaine.'
'Testing port {0}...' = 'Test du port {0}...'
'Port {0} open.' = 'Port {0} ouvert.'
'Port {0} unreachable.' = 'Port {0} injoignable.'
'SSH authentication test (BatchMode)...' = 'Test authentification SSH (BatchMode)...'
'Authentication succeeded.' = 'Authentification reussie.'
'Automatic authentication failed.' = 'Authentification non automatique.'
'Host name' = 'Nom de l''hote'
# Doctor
'LSSHM diagnostics (doctor)' = 'Diagnostic LSSHM (doctor)'
'OS : {0}' = 'OS : {0}'
'User : {0}' = 'Utilisateur : {0}'
'Administrator: {0}' = 'Administrateur: {0}'
'sshd : {0}' = 'sshd : {0}'
'Service : {0}' = 'Service : {0}'
'not detected' = 'non detecte'
'SSH tools:' = 'Outils SSH :'
'LSSHM paths:' = 'Chemins LSSHM :'
# Audit
'Local SSH security audit (Windows)' = 'Audit de securite SSH local (Windows)'
'OpenSSH Server not installed.' = 'OpenSSH Server non installe.'
'PermitRootLogin = no.' = 'PermitRootLogin = no.'
'PermitRootLogin = key only.' = 'PermitRootLogin = cle uniquement.'
'PermitRootLogin = yes (admin password possible).' = 'PermitRootLogin = yes (mot de passe admin possible).'
'PermitRootLogin = {0}' = 'PermitRootLogin = {0}'
'Password authentication disabled.' = 'Authentification par mot de passe desactivee.'
'Password authentication enabled.' = 'Authentification par mot de passe activee.'
'PasswordAuthentication = {0}' = 'PasswordAuthentication = {0}'
'.ssh present for the current user.' = '.ssh present pour l''utilisateur courant.'
'No .ssh directory.' = 'Aucun repertoire .ssh.'
'sshd service active.' = 'Service sshd actif.'
'sshd service inactive or absent.' = 'Service sshd inactif ou absent.'
'Summary: {0} OK, {1} warnings, {2} failures' = 'Resume : {0} OK, {1} avertissements, {2} echecs'
# Logs
'Connections and logs' = 'Connexions et journaux'
' 1. Sessions / sshd processes' = ' 1. Sessions / processus sshd'
' 2. OpenSSH events (Event Log)' = ' 2. Evenements OpenSSH (Journal des evenements)'
' 3. Back' = ' 3. Retour'
'OpenSSH/Operational log unavailable: {0}' = 'Journal OpenSSH/Operational indisponible : {0}'
# Backup menu
'Backup and restore' = 'Sauvegarde et restauration'
' 1. Back up sshd_config' = ' 1. Sauvegarder sshd_config'
' 2. Back up user authorized_keys' = ' 2. Sauvegarder authorized_keys utilisateur'
' 3. List backups' = ' 3. Lister les sauvegardes'
' 4. Back' = ' 4. Retour'
'Backup: {0}' = 'Sauvegarde : {0}'
'authorized_keys not found.' = 'authorized_keys introuvable.'
# Settings menu
'LSSHM settings (Windows)' = 'Parametres de LSSHM (Windows)'
'Config : {0}' = 'Config : {0}'
'Data : {0}' = 'Data : {0}'
'Language : {0}' = 'Langue : {0}'
' 1. Show diagnostics (doctor)' = ' 1. Afficher le diagnostic (doctor)'
' 2. Install LSSHM into the user profile' = ' 2. Installer LSSHM dans le profil utilisateur'
' 3. Change the language' = ' 3. Changer la langue'
# Install
'Downloading lsshm.ps1...' = 'Telechargement de lsshm.ps1...'
'Added to the user PATH: {0}' = 'Ajoute au PATH utilisateur : {0}'
'Installed:' = 'Installe :'
'Installation complete.' = 'Installation terminee.'
'Run: lsshm.ps1' = 'Lancez : lsshm.ps1'
# Server menu
'Local SSH server (Windows OpenSSH)' = 'Serveur SSH local (Windows OpenSSH)'
' 1. Install OpenSSH Server' = ' 1. Installer OpenSSH Server'
' 2. Start the service' = ' 2. Demarrer le service'
' 3. Stop the service' = ' 3. Arreter le service'
' 4. Restart the service' = ' 4. Redemarrer le service'
' 5. Enable at boot' = ' 5. Activer au demarrage'
' 6. Disable at boot' = ' 6. Desactiver au demarrage'
' 7. Change the port' = ' 7. Changer le port'
' 8. Address family (AddressFamily)' = ' 8. Famille d''adresses (AddressFamily)'
' 9. Listen addresses (ListenAddress)' = ' 9. Adresses d''ecoute (ListenAddress)'
' 10. Windows Firewall (allow OpenSSH)' = ' 10. Pare-feu Windows (autoriser OpenSSH)'
' 11. Manage PermitRootLogin / admin access' = ' 11. Gerer PermitRootLogin / acces admin'
' 12. Password authentication' = ' 12. Authentification par mot de passe'
' 13. Key authentication' = ' 13. Authentification par cle'
' 14. Test the configuration (sshd -t)' = ' 14. Tester la configuration (sshd -t)'
' 15. Show the effective configuration (sshd -T)' = ' 15. Afficher la configuration effective (sshd -T)'
' 16. Back' = ' 16. Retour'
'Change the port' = 'Changer le port'
'Address family (AddressFamily)' = 'Famille d''adresses (AddressFamily)'
'Listen addresses (ListenAddress)' = 'Adresses d''ecoute (ListenAddress)'
'New SSH port' = 'Nouveau port SSH'
'Invalid port.' = 'Port invalide.'
'Check your firewall before changing the port.' = 'Verifiez votre pare-feu avant de changer le port.'
'SSH address family (AddressFamily)' = 'Famille d''adresses SSH (AddressFamily)'
'Current: {0}' = 'Actuel : {0}'
' 1. any (IPv4 + IPv6, OpenSSH default)' = ' 1. any (IPv4 + IPv6, defaut OpenSSH)'
' 2. inet (IPv4 only)' = ' 2. inet (IPv4 uniquement)'
' 3. inet6 (IPv6 only)' = ' 3. inet6 (IPv6 uniquement)'
'SSH listen addresses (ListenAddress)' = 'Adresses d''ecoute SSH (ListenAddress)'
'Examples: 0.0.0.0 :: 192.168.1.10 0.0.0.0 ::' = 'Exemples : 0.0.0.0 :: 192.168.1.10 0.0.0.0 ::'
'Empty input restores OpenSSH defaults (all interfaces).' = 'Une saisie vide restaure les defauts OpenSSH (toutes les interfaces).'
'Listen addresses (space-separated)' = 'Adresses d''ecoute (separees par des espaces)'
'Directive removed: {0}' = 'Directive retiree : {0}'
'Directive applied: {0} ({1})' = 'Directive appliquee : {0} ({1})'
'Address family : {0}' = 'Famille d''adresses : {0}'
'Listen addresses : {0}' = 'Adresses d''ecoute : {0}'
'Firewall : {0}' = 'Pare-feu : {0}'
'allowed (port {0})' = 'autorise (port {0})'
'not allowed / no matching rule' = 'non autorise / aucune regle correspondante'
'Windows Firewall — OpenSSH' = 'Pare-feu Windows — OpenSSH'
'Status: {0}' = 'Etat : {0}'
' 1. Allow OpenSSH through the firewall' = ' 1. Autoriser OpenSSH dans le pare-feu'
' 2. Disable OpenSSH firewall rules' = ' 2. Desactiver les regles pare-feu OpenSSH'
'Allow OpenSSH through Windows Firewall?' = 'Autoriser OpenSSH dans le pare-feu Windows ?'
'OpenSSH is allowed through Windows Firewall.' = 'OpenSSH est autorise dans le pare-feu Windows.'
'Created firewall rule for OpenSSH on port {0}.' = 'Regle pare-feu creee pour OpenSSH sur le port {0}.'
'Firewall rule updated for port {0}.' = 'Regle pare-feu mise a jour pour le port {0}.'
'Enabled firewall rule: {0}' = 'Regle pare-feu activee : {0}'
'Disabled firewall rule: {0}' = 'Regle pare-feu desactivee : {0}'
'LSSHM firewall rule disabled.' = 'Regle pare-feu LSSHM desactivee.'
'No OpenSSH firewall rule found to disable.' = 'Aucune regle pare-feu OpenSSH a desactiver.'
'Unable to create firewall rule: {0}' = 'Impossible de creer la regle pare-feu : {0}'
'Unable to update firewall rule: {0}' = 'Impossible de mettre a jour la regle pare-feu : {0}'
'Unable to disable LSSHM firewall rule: {0}' = 'Impossible de desactiver la regle pare-feu LSSHM : {0}'
'Allow PasswordAuthentication?' = 'Autoriser PasswordAuthentication ?'
'Allow PubkeyAuthentication?' = 'Autoriser PubkeyAuthentication ?'
'Disabling keys may lock you out. Continue?' = 'Desactiver les cles peut vous verrouiller. Continuer ?'
# Access menu
'Access to this machine (keys allowed HERE)' = 'Acces a cette machine (cles autorisees ICI)'
' 1. List user keys (~/.ssh/authorized_keys)' = ' 1. Lister les cles utilisateur (~/.ssh/authorized_keys)'
' 2. List administrator keys (administrators_authorized_keys)' = ' 2. Lister les cles administrateurs (administrators_authorized_keys)'
' 3. Add a user key' = ' 3. Ajouter une cle utilisateur'
' 4. Add an administrator key' = ' 4. Ajouter une cle administrateur'
' 5. Repair .ssh permissions' = ' 5. Reparer les permissions .ssh'
' 6. Back' = ' 6. Retour'
# Keys menu
'My SSH keys (to connect ELSEWHERE)' = 'Mes cles SSH (pour se connecter AILLEURS)'
' 1. List key pairs' = ' 1. Lister les paires de cles'
' 2. Generate a new key (ED25519 by default)' = ' 2. Generer une nouvelle cle (ED25519 par defaut)'
' 3. Inspect a key' = ' 3. Inspecter une cle'
' 4. Show / export a public key' = ' 4. Afficher / exporter une cle publique'
' 5. Delete a key pair' = ' 5. Supprimer une paire de cles'
' 6. ssh-agent: list' = ' 6. ssh-agent : lister'
' 7. ssh-agent: add a key' = ' 7. ssh-agent : ajouter une cle'
' 8. ssh-agent: remove a key' = ' 8. ssh-agent : retirer une cle'
' 9. Back' = ' 9. Retour'
# Hosts menu
'Remote hosts (~/.ssh/config) - optional' = 'Machines distantes (~/.ssh/config) - facultatif'
' 1. List hosts' = ' 1. Lister les machines'
' 2. Add a host' = ' 2. Ajouter une machine'
' 3. Delete a host' = ' 3. Supprimer une machine'
' 4. Test a host' = ' 4. Tester une machine'
' 5. Connect' = ' 5. Se connecter'
' 6. known_hosts: list' = ' 6. known_hosts : lister'
' 7. known_hosts: remove a fingerprint' = ' 7. known_hosts : supprimer une empreinte'
' 8. Update / accept a host key' = ' 8. Mettre a jour / accepter une cle d''hote'
'Remote host identification has changed (known_hosts conflict).' = 'L''identification de l''hote distant a change (conflit known_hosts).'
'This can happen after a reinstall, or indicate a MITM risk.' = 'Cela peut arriver apres une reinstallation, ou indiquer un risque MITM.'
'Remove the old host key for {0} from known_hosts?' = 'Supprimer l''ancienne cle d''hote de {0} dans known_hosts ?'
'Fetch and accept the new host key now?' = 'Recuperer et accepter la nouvelle cle d''hote maintenant ?'
'New host key(s) for {0} added to known_hosts.' = 'Nouvelle(s) cle(s) d''hote pour {0} ajoutee(s) a known_hosts.'
'Unable to fetch host keys from {0}.' = 'Impossible de recuperer les cles d''hote de {0}.'
'Re-run the host test after updating known_hosts.' = 'Relancez le test de l''hote apres la mise a jour de known_hosts.'
'Connecting to {0}...' = 'Connexion a {0}...'
'No known_hosts file.' = 'Aucun fichier known_hosts.'
'Known fingerprints ({0}):' = 'Empreintes connues ({0}) :'
'Host to remove from known_hosts' = 'Hote a supprimer de known_hosts'
'Fingerprint of {0} removed.' = 'Empreinte de {0} supprimee.'
'Removal failed for {0}.' = 'Echec de la suppression pour {0}.'
'Host to scan' = 'Hote a scanner'
'ssh-keyscan not found.' = 'ssh-keyscan introuvable.'
'Announced fingerprints:' = 'Empreintes annoncees :'
'Automatic authentication failed (missing key or password required).' = 'Authentification non automatique (cle manquante ou mot de passe requis).'
# Main menu
'1. Manage the local SSH server' = '1. Gerer le serveur SSH local'
'2. Manage access to this machine' = '2. Gerer les acces a cette machine'
'3. Manage my SSH keys' = '3. Gerer mes cles SSH'
'4. Manage remote hosts' = '4. Gerer les machines distantes'
'5. View connections and logs' = '5. Consulter les connexions et journaux'
'6. Run a security audit' = '6. Effectuer un audit de securite'
'7. Back up or restore' = '7. Sauvegarder ou restaurer'
'8. LSSHM settings' = '8. Parametres de LSSHM'
'9. Quit' = '9. Quitter'
# Dispatch errors
'Unknown server subcommand: {0}' = 'Sous-commande server inconnue : {0}'
'Unknown access subcommand: {0}' = 'Sous-commande access inconnue : {0}'
'Unknown key subcommand: {0}' = 'Sous-commande key inconnue : {0}'
'Unknown host subcommand: {0}' = 'Sous-commande host inconnue : {0}'
'Unknown command: {0}' = 'Commande inconnue : {0}'
# Usage / help
'Usage:' = 'Utilisation :'
'CLI menu' = 'Menu CLI'
'Local SSH status' = 'Etat SSH local'
'Diagnostics' = 'Diagnostic'
'Security audit' = 'Audit de securite'
'Install into the user profile' = 'Installer dans le profil utilisateur'
'sshd service status' = 'Etat du service sshd'
'List local keys' = 'Lister les cles locales'
'List hosts in ~/.ssh/config' = 'Lister les hotes de ~/.ssh/config'
'This help' = 'Cette aide'
'Options:' = 'Options :'
'Assume yes (non-interactive)' = 'Repondre oui automatiquement (non interactif)'
'Target user (display)' = 'Utilisateur cible (affichage)'
'Interface language (en, fr, es)' = 'Langue de l''interface (en, fr, es)'
}
$script:LSSHM_MSG_es = @{
'Press Enter to continue' = 'Pulse Intro para continuar'
'Choice' = 'Eleccion'
'Invalid choice.' = 'Eleccion no valida.'
'Cancelled.' = 'Cancelado.'
'No change.' = 'Sin cambios.'
'yes' = 'si'
'no' = 'no'
'not set' = 'sin definir'
'present' = 'presente'
'absent' = 'ausente'
'unknown' = 'desconocida'
'forbidden' = 'prohibido'
'key only' = 'solo clave'
'key or password' = 'clave o contrasena'
'forced commands only' = 'solo comandos forzados'
'active' = 'activo'
'inactive' = 'inactivo'
'Language set to: {0}' = 'Idioma establecido en: {0}'
'Change the language' = 'Cambiar el idioma'
'This operation requires PowerShell as administrator.' = 'Esta operacion requiere PowerShell como administrador.'
'Relaunch: Start-Process powershell -Verb RunAs' = 'Reinicie: Start-Process powershell -Verb RunAs'
'Elevation required' = 'Se requiere elevacion'
'SSH server status: {0}' = 'Estado del servidor SSH: {0}'
'Port: {0}' = 'Puerto: {0}'
'Root / admin access: {0}' = 'Acceso root / admin: {0}'
'Password authentication: {0}' = 'Autenticacion por contrasena: {0}'
'Administrator keys (administrators_authorized_keys): {0}' = 'Claves de administrador (administrators_authorized_keys): {0}'
'Private keys of user {0}: {1}' = 'Claves privadas del usuario {0}: {1}'
'Registered remote hosts: {0}' = 'Maquinas remotas registradas: {0}'
'OpenSSH Server is not installed (sshd.exe not found).' = 'OpenSSH Server no esta instalado (sshd.exe no encontrado).'
'Auto-start : {0}' = 'Inicio automatico : {0}'
'Port : {0}' = 'Puerto : {0}'
'Admin access : {0}' = 'Acceso admin : {0}'
'Password auth : {0}' = 'Auth. contrasena : {0}'
'Key auth : {0}' = 'Auth. por clave : {0}'
'Config : {0}' = 'Config : {0}'
'OpenSSH Server already present: {0}' = 'OpenSSH Server ya presente: {0}'
'Installing OpenSSH.Server (optional Windows feature)...' = 'Instalando OpenSSH.Server (caracteristica opcional de Windows)...'
'OpenSSH Server installed.' = 'OpenSSH Server instalado.'
'Installation failed. Try: Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0' = 'Instalacion fallida. Pruebe: Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0'
'SSH service started.' = 'Servicio SSH iniciado.'
'SSH service stopped.' = 'Servicio SSH detenido.'
'SSH service restarted.' = 'Servicio SSH reiniciado.'
'Automatic startup: {0}' = 'Inicio automatico: {0}'
'sshd not found.' = 'sshd no encontrado.'
'Configuration valid (sshd -t).' = 'Configuracion valida (sshd -t).'
'Invalid configuration.' = 'Configuracion no valida.'
'No server configuration to back up.' = 'No hay configuracion de servidor para respaldar.'
'Backup created: {0}' = 'Respaldo creado: {0}'
'File not found: {0}' = 'Archivo no encontrado: {0}'
'Invalid configuration: restore a backup if needed.' = 'Configuracion no valida: restaure un respaldo si es necesario.'
'Directive applied: {0} {1}' = 'Directiva aplicada: {0} {1}'
'Administrator / root SSH login' = 'Inicio de sesion SSH de administrador / root'
' 1. Forbid entirely' = ' 1. Prohibir por completo'
' 2. Allow with a key only' = ' 2. Permitir solo con una clave'
' 3. Allow with a key or a password' = ' 3. Permitir con clave o contrasena'
' 4. Allow only for forced commands' = ' 4. Permitir solo para comandos forzados'
'Apply this sensitive change?' = 'Aplicar este cambio sensible?'
'File: {0}' = 'Archivo: {0}'
'No authorized key.' = 'Ninguna clave autorizada.'
'Paste the public key (one line) or a .pub path' = 'Pegue la clave publica (una linea) o una ruta .pub'
'Key added to {0}' = 'Clave anadida a {0}'
'.ssh not found.' = '.ssh no encontrado.'
'.ssh permissions repaired (Windows ACL).' = 'Permisos de .ssh reparados (ACL de Windows).'
'Directory: {0}' = 'Directorio: {0}'
'No key pair detected.' = 'No se detecto ningun par de claves.'
' Public : {0}' = ' Publica : {0}'
' Private : {0}' = ' Privada : {0}'
' Fingerprint: {0}' = ' Huella : {0}'
'Choose a key' = 'Elegir una clave'
'Private key not found: {0}' = 'Clave privada no encontrada: {0}'
'Key not found: {0}' = 'Clave no encontrada: {0}'
'{0} (number)' = '{0} (numero)'
'Invalid choice: {0}' = 'Eleccion no valida: {0}'
'Number out of range (1-{0}).' = 'Numero fuera de rango (1-{0}).'
'Private key missing for {0}.' = 'Falta la clave privada para {0}.'
'Key type (ed25519/rsa)' = 'Tipo de clave (ed25519/rsa)'
'File name' = 'Nombre de archivo'
'Comment' = 'Comentario'
'Key generated: {0}' = 'Clave generada: {0}'
'Generation failed.' = 'Fallo la generacion.'
'Key to inspect' = 'Clave a inspeccionar'
'Key to export' = 'Clave a exportar'
'Public key not found: {0}' = 'Clave publica no encontrada: {0}'
'Public key ({0}):' = 'Clave publica ({0}):'
'Key to delete' = 'Clave a eliminar'
'Deleting the key pair:' = 'Eliminando el par de claves:'
'A backup will be created. Confirm deletion?' = 'Se creara un respaldo. Confirmar la eliminacion?'
'Key pair deleted (backup kept).' = 'Par de claves eliminado (respaldo conservado).'
'No ssh-agent detected. On Windows: Get-Service ssh-agent ; Start-Service ssh-agent' = 'No se detecto ssh-agent. En Windows: Get-Service ssh-agent ; Start-Service ssh-agent'
'Key to add to ssh-agent' = 'Clave a anadir a ssh-agent'
'Key added to ssh-agent.' = 'Clave anadida a ssh-agent.'
'Failed.' = 'Fallo.'
'Remove all keys from the agent?' = 'Quitar todas las claves del agente?'
'All keys removed.' = 'Todas las claves eliminadas.'
'Key to remove from ssh-agent' = 'Clave a quitar de ssh-agent'
'Key removed from ssh-agent.' = 'Clave quitada de ssh-agent.'
'No remote host in ~/.ssh/config.' = 'Ninguna maquina remota en ~/.ssh/config.'
'Remote hosts ({0}):' = 'Maquinas remotas ({0}):'
'Host alias' = 'Nombre (alias)'
'Name required.' = 'Nombre requerido.'
'A host ''{0}'' already exists.' = 'Ya existe un host ''{0}''.'
'Address (HostName)' = 'Direccion (HostName)'
'User' = 'Usuario'
'Port' = 'Puerto'
'Key file' = 'Archivo de clave'
'Host ''{0}'' added.' = 'Host ''{0}'' anadido.'
'Host name to delete' = 'Nombre del host a eliminar'
'Host not found: {0}' = 'Host no encontrado: {0}'
'Delete host ''{0}''?' = 'Eliminar el host ''{0}''?'
'Host ''{0}'' deleted.' = 'Host ''{0}'' eliminado.'
'Host name to test' = 'Nombre del host a probar'
'Resolving {0}...' = 'Resolviendo {0}...'
'DNS resolution succeeded.' = 'Resolucion DNS correcta.'
'DNS resolution uncertain.' = 'Resolucion DNS incierta.'
'Testing port {0}...' = 'Probando el puerto {0}...'
'Port {0} open.' = 'Puerto {0} abierto.'
'Port {0} unreachable.' = 'Puerto {0} inaccesible.'
'SSH authentication test (BatchMode)...' = 'Prueba de autenticacion SSH (BatchMode)...'
'Authentication succeeded.' = 'Autenticacion correcta.'
'Automatic authentication failed.' = 'Autenticacion automatica fallida.'
'Host name' = 'Nombre del host'
'LSSHM diagnostics (doctor)' = 'Diagnostico de LSSHM (doctor)'
'OS : {0}' = 'SO : {0}'
'User : {0}' = 'Usuario : {0}'
'Administrator: {0}' = 'Administrador: {0}'
'sshd : {0}' = 'sshd : {0}'
'Service : {0}' = 'Servicio : {0}'
'not detected' = 'no detectado'
'SSH tools:' = 'Herramientas SSH:'
'LSSHM paths:' = 'Rutas de LSSHM:'
'Local SSH security audit (Windows)' = 'Auditoria de seguridad SSH local (Windows)'
'OpenSSH Server not installed.' = 'OpenSSH Server no instalado.'
'PermitRootLogin = no.' = 'PermitRootLogin = no.'
'PermitRootLogin = key only.' = 'PermitRootLogin = solo clave.'
'PermitRootLogin = yes (admin password possible).' = 'PermitRootLogin = yes (contrasena de admin posible).'
'PermitRootLogin = {0}' = 'PermitRootLogin = {0}'
'Password authentication disabled.' = 'Autenticacion por contrasena desactivada.'
'Password authentication enabled.' = 'Autenticacion por contrasena activada.'
'PasswordAuthentication = {0}' = 'PasswordAuthentication = {0}'
'.ssh present for the current user.' = '.ssh presente para el usuario actual.'
'No .ssh directory.' = 'Ningun directorio .ssh.'
'sshd service active.' = 'Servicio sshd activo.'
'sshd service inactive or absent.' = 'Servicio sshd inactivo o ausente.'
'Summary: {0} OK, {1} warnings, {2} failures' = 'Resumen: {0} OK, {1} advertencias, {2} fallos'
'Connections and logs' = 'Conexiones y registros'
' 1. Sessions / sshd processes' = ' 1. Sesiones / procesos sshd'
' 2. OpenSSH events (Event Log)' = ' 2. Eventos OpenSSH (Visor de eventos)'
' 3. Back' = ' 3. Volver'
'OpenSSH/Operational log unavailable: {0}' = 'Registro OpenSSH/Operational no disponible: {0}'
'Backup and restore' = 'Respaldo y restauracion'
' 1. Back up sshd_config' = ' 1. Respaldar sshd_config'
' 2. Back up user authorized_keys' = ' 2. Respaldar authorized_keys de usuario'
' 3. List backups' = ' 3. Listar respaldos'
' 4. Back' = ' 4. Volver'
'Backup: {0}' = 'Respaldo: {0}'
'authorized_keys not found.' = 'authorized_keys no encontrado.'
'LSSHM settings (Windows)' = 'Configuracion de LSSHM (Windows)'
'Config : {0}' = 'Config : {0}'
'Data : {0}' = 'Data : {0}'
'Language : {0}' = 'Idioma : {0}'
' 1. Show diagnostics (doctor)' = ' 1. Mostrar el diagnostico (doctor)'
' 2. Install LSSHM into the user profile' = ' 2. Instalar LSSHM en el perfil de usuario'
' 3. Change the language' = ' 3. Cambiar el idioma'
'Downloading lsshm.ps1...' = 'Descargando lsshm.ps1...'
'Added to the user PATH: {0}' = 'Anadido al PATH de usuario: {0}'
'Installed:' = 'Instalado:'
'Installation complete.' = 'Instalacion completada.'
'Run: lsshm.ps1' = 'Ejecute: lsshm.ps1'
'Local SSH server (Windows OpenSSH)' = 'Servidor SSH local (Windows OpenSSH)'
' 1. Install OpenSSH Server' = ' 1. Instalar OpenSSH Server'
' 2. Start the service' = ' 2. Iniciar el servicio'
' 3. Stop the service' = ' 3. Detener el servicio'
' 4. Restart the service' = ' 4. Reiniciar el servicio'
' 5. Enable at boot' = ' 5. Activar al inicio'
' 6. Disable at boot' = ' 6. Desactivar al inicio'
' 7. Change the port' = ' 7. Cambiar el puerto'
' 8. Address family (AddressFamily)' = ' 8. Familia de direcciones (AddressFamily)'
' 9. Listen addresses (ListenAddress)' = ' 9. Direcciones de escucha (ListenAddress)'
' 10. Windows Firewall (allow OpenSSH)' = ' 10. Firewall de Windows (permitir OpenSSH)'
' 11. Manage PermitRootLogin / admin access' = ' 11. Gestionar PermitRootLogin / acceso admin'
' 12. Password authentication' = ' 12. Autenticacion por contrasena'
' 13. Key authentication' = ' 13. Autenticacion por clave'
' 14. Test the configuration (sshd -t)' = ' 14. Probar la configuracion (sshd -t)'
' 15. Show the effective configuration (sshd -T)' = ' 15. Mostrar la configuracion efectiva (sshd -T)'
' 16. Back' = ' 16. Volver'
'Change the port' = 'Cambiar el puerto'
'Address family (AddressFamily)' = 'Familia de direcciones (AddressFamily)'
'Listen addresses (ListenAddress)' = 'Direcciones de escucha (ListenAddress)'
'New SSH port' = 'Nuevo puerto SSH'
'Invalid port.' = 'Puerto no valido.'
'Check your firewall before changing the port.' = 'Verifique su firewall antes de cambiar el puerto.'
'SSH address family (AddressFamily)' = 'Familia de direcciones SSH (AddressFamily)'
'Current: {0}' = 'Actual: {0}'
' 1. any (IPv4 + IPv6, OpenSSH default)' = ' 1. any (IPv4 + IPv6, predeterminado OpenSSH)'
' 2. inet (IPv4 only)' = ' 2. inet (solo IPv4)'
' 3. inet6 (IPv6 only)' = ' 3. inet6 (solo IPv6)'
'SSH listen addresses (ListenAddress)' = 'Direcciones de escucha SSH (ListenAddress)'
'Examples: 0.0.0.0 :: 192.168.1.10 0.0.0.0 ::' = 'Ejemplos: 0.0.0.0 :: 192.168.1.10 0.0.0.0 ::'
'Empty input restores OpenSSH defaults (all interfaces).' = 'Una entrada vacia restaura los valores predeterminados de OpenSSH (todas las interfaces).'
'Listen addresses (space-separated)' = 'Direcciones de escucha (separadas por espacios)'
'Directive removed: {0}' = 'Directiva eliminada: {0}'
'Directive applied: {0} ({1})' = 'Directiva aplicada: {0} ({1})'
'Address family : {0}' = 'Familia de direcciones: {0}'
'Listen addresses : {0}' = 'Direcciones de escucha: {0}'
'Firewall : {0}' = 'Firewall : {0}'
'allowed (port {0})' = 'permitido (puerto {0})'
'not allowed / no matching rule' = 'no permitido / ninguna regla coincidente'
'Windows Firewall — OpenSSH' = 'Firewall de Windows — OpenSSH'
'Status: {0}' = 'Estado: {0}'
' 1. Allow OpenSSH through the firewall' = ' 1. Permitir OpenSSH en el firewall'
' 2. Disable OpenSSH firewall rules' = ' 2. Desactivar las reglas de firewall OpenSSH'
'Allow OpenSSH through Windows Firewall?' = 'Permitir OpenSSH en el firewall de Windows?'
'OpenSSH is allowed through Windows Firewall.' = 'OpenSSH esta permitido en el firewall de Windows.'
'Created firewall rule for OpenSSH on port {0}.' = 'Regla de firewall creada para OpenSSH en el puerto {0}.'
'Firewall rule updated for port {0}.' = 'Regla de firewall actualizada para el puerto {0}.'
'Enabled firewall rule: {0}' = 'Regla de firewall activada: {0}'
'Disabled firewall rule: {0}' = 'Regla de firewall desactivada: {0}'
'LSSHM firewall rule disabled.' = 'Regla de firewall LSSHM desactivada.'
'No OpenSSH firewall rule found to disable.' = 'No hay regla de firewall OpenSSH para desactivar.'
'Unable to create firewall rule: {0}' = 'No se pudo crear la regla de firewall: {0}'
'Unable to update firewall rule: {0}' = 'No se pudo actualizar la regla de firewall: {0}'
'Unable to disable LSSHM firewall rule: {0}' = 'No se pudo desactivar la regla de firewall LSSHM: {0}'
'Allow PasswordAuthentication?' = 'Permitir PasswordAuthentication?'
'Allow PubkeyAuthentication?' = 'Permitir PubkeyAuthentication?'
'Disabling keys may lock you out. Continue?' = 'Desactivar las claves puede bloquearle. Continuar?'
'Access to this machine (keys allowed HERE)' = 'Acceso a esta maquina (claves permitidas AQUI)'
' 1. List user keys (~/.ssh/authorized_keys)' = ' 1. Listar claves de usuario (~/.ssh/authorized_keys)'
' 2. List administrator keys (administrators_authorized_keys)' = ' 2. Listar claves de administrador (administrators_authorized_keys)'
' 3. Add a user key' = ' 3. Anadir una clave de usuario'
' 4. Add an administrator key' = ' 4. Anadir una clave de administrador'
' 5. Repair .ssh permissions' = ' 5. Reparar los permisos de .ssh'
' 6. Back' = ' 6. Volver'
'My SSH keys (to connect ELSEWHERE)' = 'Mis claves SSH (para conectarse EN OTRO LUGAR)'
' 1. List key pairs' = ' 1. Listar los pares de claves'
' 2. Generate a new key (ED25519 by default)' = ' 2. Generar una nueva clave (ED25519 por defecto)'
' 3. Inspect a key' = ' 3. Inspeccionar una clave'
' 4. Show / export a public key' = ' 4. Mostrar / exportar una clave publica'
' 5. Delete a key pair' = ' 5. Eliminar un par de claves'
' 6. ssh-agent: list' = ' 6. ssh-agent: listar'
' 7. ssh-agent: add a key' = ' 7. ssh-agent: anadir una clave'
' 8. ssh-agent: remove a key' = ' 8. ssh-agent: quitar una clave'
' 9. Back' = ' 9. Volver'
'Remote hosts (~/.ssh/config) - optional' = 'Maquinas remotas (~/.ssh/config) - opcional'
' 1. List hosts' = ' 1. Listar las maquinas'
' 2. Add a host' = ' 2. Anadir una maquina'
' 3. Delete a host' = ' 3. Eliminar una maquina'
' 4. Test a host' = ' 4. Probar una maquina'
' 5. Connect' = ' 5. Conectarse'
' 6. known_hosts: list' = ' 6. known_hosts: listar'
' 7. known_hosts: remove a fingerprint' = ' 7. known_hosts: eliminar una huella'
' 8. Update / accept a host key' = ' 8. Actualizar / aceptar una clave de host'
'Remote host identification has changed (known_hosts conflict).' = 'La identificacion del host remoto ha cambiado (conflicto known_hosts).'
'This can happen after a reinstall, or indicate a MITM risk.' = 'Puede ocurrir tras una reinstalacion, o indicar un riesgo MITM.'
'Remove the old host key for {0} from known_hosts?' = 'Eliminar la clave de host antigua de {0} en known_hosts?'
'Fetch and accept the new host key now?' = 'Obtener y aceptar ahora la nueva clave de host?'
'New host key(s) for {0} added to known_hosts.' = 'Nueva(s) clave(s) de host para {0} anadida(s) a known_hosts.'
'Unable to fetch host keys from {0}.' = 'No se pudieron obtener las claves de host de {0}.'
'Re-run the host test after updating known_hosts.' = 'Vuelva a probar el host tras actualizar known_hosts.'
'Connecting to {0}...' = 'Conectando a {0}...'
'No known_hosts file.' = 'No hay archivo known_hosts.'
'Known fingerprints ({0}):' = 'Huellas conocidas ({0}):'
'Host to remove from known_hosts' = 'Host a eliminar de known_hosts'
'Fingerprint of {0} removed.' = 'Huella de {0} eliminada.'
'Removal failed for {0}.' = 'Fallo la eliminacion para {0}.'
'Host to scan' = 'Host a escanear'
'ssh-keyscan not found.' = 'ssh-keyscan no encontrado.'
'Announced fingerprints:' = 'Huellas anunciadas:'
'Automatic authentication failed (missing key or password required).' = 'Autenticacion no automatica (falta clave o se requiere contrasena).'
'1. Manage the local SSH server' = '1. Gestionar el servidor SSH local'
'2. Manage access to this machine' = '2. Gestionar el acceso a esta maquina'
'3. Manage my SSH keys' = '3. Gestionar mis claves SSH'
'4. Manage remote hosts' = '4. Gestionar las maquinas remotas'
'5. View connections and logs' = '5. Consultar las conexiones y registros'
'6. Run a security audit' = '6. Ejecutar una auditoria de seguridad'
'7. Back up or restore' = '7. Respaldar o restaurar'
'8. LSSHM settings' = '8. Configuracion de LSSHM'
'9. Quit' = '9. Salir'
'Unknown server subcommand: {0}' = 'Subcomando server desconocido: {0}'
'Unknown access subcommand: {0}' = 'Subcomando access desconocido: {0}'
'Unknown key subcommand: {0}' = 'Subcomando key desconocido: {0}'
'Unknown host subcommand: {0}' = 'Subcomando host desconocido: {0}'
'Unknown command: {0}' = 'Comando desconocido: {0}'
# Usage / help
'Usage:' = 'Uso:'
'CLI menu' = 'Menu CLI'
'Local SSH status' = 'Estado SSH local'
'Diagnostics' = 'Diagnostico'
'Security audit' = 'Auditoria de seguridad'
'Install into the user profile' = 'Instalar en el perfil de usuario'
'sshd service status' = 'Estado del servicio sshd'
'List local keys' = 'Listar las claves locales'
'List hosts in ~/.ssh/config' = 'Listar los hosts de ~/.ssh/config'
'This help' = 'Esta ayuda'
'Options:' = 'Opciones:'
'Assume yes (non-interactive)' = 'Responder si automaticamente (no interactivo)'
'Target user (display)' = 'Usuario objetivo (visualizacion)'
'Interface language (en, fr, es)' = 'Idioma de la interfaz (en, fr, es)'
}
function Get-LsshmText {
param([Parameter(Mandatory)][string]$Id)
$table = switch ($script:LSSHM_LANG) {
'fr' { $script:LSSHM_MSG_fr }
'es' { $script:LSSHM_MSG_es }
default { $null }
}
if ($table -and $table.ContainsKey($Id) -and $table[$Id]) { return [string]$table[$Id] }
return $Id
}
# T: translate a msgid. TF: translate then -f format with the given arguments.
function T { param([Parameter(Mandatory)][string]$Id) return (Get-LsshmText $Id) }
function TF {
param([Parameter(Mandatory)][string]$Id, [Parameter(ValueFromRemainingArguments = $true)][object[]]$FormatArgs)
$s = Get-LsshmText $Id
if ($FormatArgs -and $FormatArgs.Count -gt 0) { return ($s -f $FormatArgs) }
return $s
}
function Get-LsshmLangNativeName {
param([string]$Code)
switch ($Code) {
'en' { 'English' }
'fr' { 'Francais' }
'es' { 'Espanol' }
default { $Code }
}
}
function Get-LsshmDetectLang {
try {
$c = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName.ToLowerInvariant()
} catch {
$c = 'en'
}
switch ($c) {
'fr' { 'fr' }
'es' { 'es' }
default { 'en' }
}
}
function Get-LsshmConfiguredLang {
if ($script:LSSHM_CONFIG_FILE -and (Test-Path -LiteralPath $script:LSSHM_CONFIG_FILE)) {
try {
$j = Get-Content -LiteralPath $script:LSSHM_CONFIG_FILE -Raw -ErrorAction Stop | ConvertFrom-Json
if ($j.PSObject.Properties.Name -contains 'language' -and $j.language) {
return [string]$j.language
}
} catch { }
}
return ''
}
function Set-LsshmConfiguredLang {
param([Parameter(Mandatory)][string]$Lang)
Ensure-LsshmDirs
$obj = [ordered]@{}
if (Test-Path -LiteralPath $script:LSSHM_CONFIG_FILE) {
try {
$existing = Get-Content -LiteralPath $script:LSSHM_CONFIG_FILE -Raw -ErrorAction Stop | ConvertFrom-Json
foreach ($p in $existing.PSObject.Properties) { $obj[$p.Name] = $p.Value }
} catch { }
}
$obj['language'] = $Lang
($obj | ConvertTo-Json) | Set-Content -LiteralPath $script:LSSHM_CONFIG_FILE -Encoding UTF8
}
function Initialize-LsshmLang {
$want = ''
if ($script:LSSHM_LANG_OVERRIDE) {
$want = $script:LSSHM_LANG_OVERRIDE
} else {
$cfg = Get-LsshmConfiguredLang
if ($cfg) { $want = $cfg } else { $want = Get-LsshmDetectLang }
}
if ($script:LSSHM_LANGS -contains $want) { $script:LSSHM_LANG = $want } else { $script:LSSHM_LANG = 'en' }
}
function Test-LsshmLangConfigured {
return [bool](Get-LsshmConfiguredLang)
}
function Select-LsshmLanguage {
Write-Host ''
Write-Host 'Language / Langue / Idioma:'
$i = 0
foreach ($code in $script:LSSHM_LANGS) {
$i++
Write-Host (" {0}. {1}" -f $i, (Get-LsshmLangNativeName $code))
}
$detected = Get-LsshmDetectLang
$def = '1'
for ($j = 0; $j -lt $script:LSSHM_LANGS.Count; $j++) {
if ($script:LSSHM_LANGS[$j] -eq $detected) { $def = [string]($j + 1) }
}
$choice = Read-LsshmPrompt 'Choice / Choix / Eleccion' $def
$picked = $detected
$n = 0
if ([int]::TryParse($choice, [ref]$n) -and $n -ge 1 -and $n -le $script:LSSHM_LANGS.Count) {
$picked = $script:LSSHM_LANGS[$n - 1]
} elseif ($script:LSSHM_LANGS -contains $choice) {
$picked = $choice
}
$script:LSSHM_LANG = $picked
Set-LsshmConfiguredLang $picked
Write-LsshmOk (TF 'Language set to: {0}' (Get-LsshmLangNativeName $picked))
}
function Initialize-LsshmPaths {
$script:LSSHM_HOME = $env:USERPROFILE
if (-not $script:LSSHM_HOME) { $script:LSSHM_HOME = $HOME }
$localApp = $env:LOCALAPPDATA
if (-not $localApp) { $localApp = Join-Path $script:LSSHM_HOME 'AppData\Local' }
$script:LSSHM_CONFIG_DIR = Join-Path $localApp 'lsshm'
$script:LSSHM_DATA_DIR = Join-Path $localApp 'lsshm\data'
$script:LSSHM_STATE_DIR = Join-Path $localApp 'lsshm\state'
$script:LSSHM_CACHE_DIR = Join-Path $localApp 'lsshm\cache'
$script:LSSHM_BACKUP_DIR = Join-Path $script:LSSHM_STATE_DIR 'backups'
$script:LSSHM_CONFIG_FILE = Join-Path $script:LSSHM_CONFIG_DIR 'config.json'
$script:LSSHM_INSTALL_TARGET = Join-Path $script:LSSHM_DATA_DIR 'lsshm.ps1'
$script:LSSHM_BIN_DIR = Join-Path $script:LSSHM_HOME '.local\bin'
$script:LSSHM_BIN_LINK = Join-Path $script:LSSHM_BIN_DIR 'lsshm.ps1'
$script:LSSHM_SSH_DIR = Join-Path $script:LSSHM_HOME '.ssh'
$script:LSSHM_SSH_CONFIG = Join-Path $script:LSSHM_SSH_DIR 'config'
$script:LSSHM_KNOWN_HOSTS = Join-Path $script:LSSHM_SSH_DIR 'known_hosts'
$script:LSSHM_AUTHORIZED_KEYS = Join-Path $script:LSSHM_SSH_DIR 'authorized_keys'
$programData = $env:ProgramData
if (-not $programData) { $programData = 'C:\ProgramData' }
$script:LSSHM_SSHD_CONFIG = Join-Path $programData 'ssh\sshd_config'
$script:LSSHM_ADMIN_KEYS = Join-Path $programData 'ssh\administrators_authorized_keys'
$script:LSSHM_SSH_SERVICE = 'sshd'
}
function Ensure-LsshmDirs {
foreach ($d in @(
$script:LSSHM_CONFIG_DIR,
$script:LSSHM_DATA_DIR,
$script:LSSHM_STATE_DIR,
$script:LSSHM_CACHE_DIR,
$script:LSSHM_BACKUP_DIR
)) {
if (-not (Test-Path -LiteralPath $d)) {
New-Item -ItemType Directory -Path $d -Force | Out-Null
}
}
}
# =============================================================================
# Display / prompts
# =============================================================================
function Write-LsshmInfo { param([string]$Message) Write-Host $Message }
function Write-LsshmOk { param([string]$Message) Write-Host $Message -ForegroundColor Green }
function Write-LsshmWarn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Write-LsshmError { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Write-LsshmHeader {
Write-Host $script:LSSHM_LONG_NAME -ForegroundColor Cyan
Write-Host ("v{0}" -f $script:LSSHM_VERSION) -ForegroundColor DarkGray
Write-Host ''
}
function Test-LsshmInteractive {
if ($script:LSSHM_ASSUME_YES) { return $false }
# Prefer console attachment checks. [Environment]::UserInteractive is often
# false under OpenSSH Server (remote PowerShell) even when a PTY is
# allocated and Read-Host works — that used to make the menu auto-quit
# with the default "9" choice.
try {
if (-not [Console]::IsInputRedirected -and -not [Console]::IsOutputRedirected) {
return $true
}
if ([Console]::IsInputRedirected) {
return $false
}
} catch {
# Console API unavailable — fall through.
}
try {
return [Environment]::UserInteractive
} catch {
return $true
}
}
function Read-LsshmPrompt {
param(
[Parameter(Mandatory)][string]$Prompt,
[string]$Default = ''
)
if (-not (Test-LsshmInteractive)) {
return $Default
}
$suffix = if ($Default) { " [$Default]" } else { '' }
$answer = Read-Host "$Prompt$suffix"
if ([string]::IsNullOrWhiteSpace($answer)) { return $Default }
return $answer.Trim()
}
function Confirm-Lsshm {
param(
[Parameter(Mandatory)][string]$Prompt,
[switch]$DefaultYes
)
if ($script:LSSHM_ASSUME_YES) { return $true }
if (-not (Test-LsshmInteractive)) { return [bool]$DefaultYes }
$hint = if ($DefaultYes) { '[Y/n]' } else { '[y/N]' }
$answer = Read-Host "$Prompt $hint"
if ([string]::IsNullOrWhiteSpace($answer)) { return [bool]$DefaultYes }
switch -Regex ($answer.Trim().ToLowerInvariant()) {
'^(y|yes|o|oui|s|si)$' { return $true }
default { return $false }
}
}
function Pause-Lsshm {
if (-not (Test-LsshmInteractive)) { return }
Read-Host (T 'Press Enter to continue') | Out-Null
}
function Test-LsshmAdmin {
try {
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]$id
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
} catch {
return $false
}
}
function Assert-LsshmAdmin {
if (-not (Test-LsshmAdmin)) {
Write-LsshmError (T 'This operation requires PowerShell as administrator.')
Write-LsshmInfo (T 'Relaunch: Start-Process powershell -Verb RunAs')
throw (T 'Elevation required')
}
}
# =============================================================================
# Platform / OpenSSH detection
# =============================================================================
function Get-LsshmSshdPath {
$candidates = @(
(Join-Path $env:SystemRoot 'System32\OpenSSH\sshd.exe'),
(Join-Path $env:ProgramFiles 'OpenSSH\sshd.exe'),
'C:\Windows\System32\OpenSSH\sshd.exe'
)
foreach ($c in $candidates) {
if (Test-Path -LiteralPath $c) { return $c }
}
$cmd = Get-Command sshd -ErrorAction SilentlyContinue
if ($cmd) { return $cmd.Source }
return $null
}
function Test-LsshmServerInstalled {
return [bool](Get-LsshmSshdPath)
}
function Get-LsshmService {
Get-Service -Name $script:LSSHM_SSH_SERVICE -ErrorAction SilentlyContinue
}
function Test-LsshmServerActive {
$svc = Get-LsshmService
return ($svc -and $svc.Status -eq 'Running')
}
function Get-LsshmConfigValue {
param([Parameter(Mandatory)][string]$Key)
$keyLower = $Key.ToLowerInvariant()
# Prefer sshd -T when available and elevated enough
$sshd = Get-LsshmSshdPath
if ($sshd) {
try {
$dump = & $sshd -T 2>$null
if ($LASTEXITCODE -eq 0 -and $dump) {
foreach ($line in $dump) {
if ($line -match '^\s*(\S+)\s+(.+)$') {
if ($Matches[1].ToLowerInvariant() -eq $keyLower) {
return $Matches[2].Trim()
}
}
}
}
} catch { }
}
if (-not (Test-Path -LiteralPath $script:LSSHM_SSHD_CONFIG)) { return $null }
foreach ($line in Get-Content -LiteralPath $script:LSSHM_SSHD_CONFIG -ErrorAction SilentlyContinue) {
$trim = $line.Trim()
if ($trim -match '^\s*#' -or $trim -eq '') { continue }
if ($trim -match '^\s*(\S+)\s+(.+)$') {
if ($Matches[1].ToLowerInvariant() -eq $keyLower) {
return $Matches[2].Trim()
}
}
}
return $null
}
function Get-LsshmRootLoginLabel {
param([string]$Value)
switch -Regex ($Value) {
'^no$' { return (T 'forbidden') }
'^(prohibit-password|without-password)$' { return (T 'key only') }
'^yes$' { return (T 'key or password') }
'^forced-commands-only$' { return (T 'forced commands only') }
default { if ($Value) { return $Value } else { return (T 'not set') } }
}
}
function Get-LsshmYesNoLabel {
param([string]$Value)
switch -Regex ($Value) {
'^(yes|true|on|1)$' { return (T 'yes') }
'^(no|false|off|0)$' { return (T 'no') }
default { if ($Value) { return $Value } else { return (T 'not set') } }