SSH – Password Cli

Bonjour a tous,

Aujourd’hui, on va rester dans la même optique que l’article précédent et prouver que le libre n’est pas juste du « marketing » pour faire joli. Dernièrement, j’ai voulu modifier htop pour ajouter une sonde sur mes disques. Aujourd’hui, nous allons répondre à un besoin qu’ont eu tous les apprentis administrateurs système GNU/Linux :

Comment exécuter une commande sur un serveur distant depuis un script bash ?

En bon Linuxien, vous avez lu la doc de long en large ( RTFM ) de la commande ‘ssh‘ mais aucun moyen de passer le mot de passe à notre commande. Google et la plupart des personnes vous dirons : « Il te suffit d’ajouter ta clé publique sur le serveur et tu n’auras pas besoin du mot de passe. »

Ceci est vrai et est très simple à réaliser, mais ce n’est peut-être pas la réponse souhaitée. Une autre solution : utiliser un autre langage plus à même de répondre à votre besoin. On peut, par exemple, utiliser le python avec le module paramiko ou perl et son module Net::SSH::Perl. Ceci dit, vous avez peut-être une restriction forte sur le bash et vous ne souhaitez pas en changer.

Revenons donc a notre première idée, un argument à la commande « ssh » pour passer le mot de passe.

Cet argument n’existe pas, et alors ? Rajoutons-le ensemble.

Commençons par récupérer les sources grâce à notre Debian et son système de paquets :

$ apt-get source ssh
...
 
$ ls
openssh-6.0p1 openssh_6.0p1-4.debian.tar.gz openssh_6.0p1-4.dsc openssh_6.0p1.orig.tar.gz

On modifie le code pour ajouter notre option. Voici le patch de ma modification : ssh-password-arg.txt

Récupération des dépendances, application du patch et compilation :

sudo apt-get build-dep openssh-client
$ cd openssh-6.0p1
$ patch -p1 < ssh-password-arg.txt
patching file readconf.c
patching file readconf.h
patching file ssh.c
patching file sshconnect1.c
patching file sshconnect2.c
$sudo apt-get build-dep openssh-client
...
$ ./configure
...
$ make ssh

Et, pour finir, on essaie notre nouveau binaire tout neuf

$ ./ssh
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-I pkcs11] [-i identity_file]
[-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-W host:port] [-w local_tun[:remote_tun]]
[-B password] #This is new !!
[user@]hostname [command]
$ ./ssh user@monserv -B topmoumoute MaCommandeAExec
\o/

Par la suite, libre à vous de repackager un nouveau paquet « deb/rpm » ou d’utiliser directement le binaire.

Si vous regardez le patch, vous vous apercevrez que je n’ai modifié que quelques lignes de code (en vert ci-dessous). Nul besoin de connaissances avancées en développement.

diff -Nur openssh-6.0p1/readconf.c openssh-patch/readconf.c
--- openssh-6.0p1/readconf.c 2014-01-15 16:09:47.000000000 +0100
+++ openssh-patch/readconf.c 2014-01-15 16:06:52.846987709 +0100
@@ -1216,6 +1216,7 @@
options->host_key_alias = NULL;
options->proxy_command = NULL;
options->user = NULL;
+ options->password = NULL;
options->escape_char = -1;
options->num_system_hostfiles = 0;
options->num_user_hostfiles = 0;
diff -Nur openssh-6.0p1/readconf.h openssh-patch/readconf.h
--- openssh-6.0p1/readconf.h 2014-01-15 16:09:47.000000000 +0100
+++ openssh-patch/readconf.h 2014-01-15 11:51:21.739510883 +0100
@@ -89,6 +89,7 @@
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
char *proxy_command; /* Proxy command for connecting the host. */
char *user; /* User to log in as. */
+ char *password; /* Password User */
int escape_char; /* Escape character; -2 = none */
u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */
diff -Nur openssh-6.0p1/ssh.c openssh-patch/ssh.c
--- openssh-6.0p1/ssh.c 2014-01-15 16:09:47.000000000 +0100
+++ openssh-patch/ssh.c 2014-01-15 12:40:02.866139357 +0100
@@ -203,6 +203,7 @@
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
" [-W host:port] [-w local_tun[:remote_tun]]\n"
+" [-B password]\n"
" [user@]hostname [command]\n"
);
exit(255);
@@ -326,7 +327,7 @@
again:
while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
- "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
+ "AB:CD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@@ -536,6 +537,9 @@
case 'l':
options.user = optarg;
break;
+ case 'B':
+ options.password = optarg;
+ break;
case 'L':
if (parse_forward(&fwd, optarg, 0, 0))
diff -Nur openssh-6.0p1/sshconnect1.c openssh-patch/sshconnect1.c
--- openssh-6.0p1/sshconnect1.c 2006-11-07 13:14:42.000000000 +0100
+++ openssh-patch/sshconnect1.c 2014-01-15 16:32:45.702949080 +0100
@@ -455,7 +455,12 @@
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
- password = read_passphrase(prompt, 0);
+ if ( options.password == NULL )
+ {
+ password = read_passphrase(prompt, 0);
+ }else{
+ password = options.password;
+ }
packet_start(SSH_CMSG_AUTH_PASSWORD);
ssh_put_password(password);
memset(password, 0, strlen(password));
diff -Nur openssh-6.0p1/sshconnect2.c openssh-patch/sshconnect2.c
--- openssh-6.0p1/sshconnect2.c 2014-01-15 16:09:47.000000000 +0100
+++ openssh-patch/sshconnect2.c 2014-01-15 14:24:48.982270993 +0100
@@ -993,7 +993,13 @@
snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
authctxt->server_user, host);
- password = read_passphrase(prompt, 0);
+ if ( options.password == NULL )
+ {
+ password = read_passphrase(prompt, 0);
+ }else{
+ password = options.password;
+ }
+
packet_start(SSH2_MSG_USERAUTH_REQUEST);
packet_put_cstring(authctxt->server_user);
packet_put_cstring(authctxt->service);

 

En conclusion, n’hésitez pas/plus à adapter les outils à vos besoins et à partager vos modifications. C’est souvent loin d’être aussi complexe que ça en à l’air et cela permet aussi de faire évoluer le logiciel.

 

Download :

ssh-password-arg.txt

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *