Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 27/05/2010, à 21:07

Tetsuo6995

Problème avec un "serveur netcat" simple.

Bonjour.
J'éprouve de grosses difficultés a modifier un script servant de serveur netcat très basique.

Le serveur (code à la suite) permet à un client de se connecter dessus et d'exécuter de manière distante des commandes diverses. C'est plus ou moins un shell distant très simple.

#! /bin/bash

# Ce script implémente un serveur.  
# Le script doit être invoqué avec l'argument :                                                              
# PORT   le port sur lequel le serveur attend ses clients  

if [ $# -ne 1 ]; then
    echo "usage: $(basename $0) PORT"
    exit -1
fi

PORT="$1"

# Déclaration du tube

FIFO="/tmp/$USER-fifo-$$"

# Il faut détruire le tube quand le serveur termine pour éviter de
# polluer /tmp.  On utilise pour cela une instruction trap pour être sur de
# nettoyer même si le serveur est interrompu par un signal.

function nettoyage() { rm -f "$FIFO"; }
trap nettoyage EXIT

# on crée le tube nommé

[ -e "FIFO" ] || mkfifo "$FIFO"


function accept-loop() {
    while true; do
	interaction < "$FIFO" | nc -v -l "$PORT" > "$FIFO"
    done
}

# La fonction interaction lit les commandes du client sur entrée standard 
# et envoie les réponses sur sa sortie standard. 
#
# 	CMD arg1 arg2 ... argn                   
#                     
# alors elle invoque la fonction :
#                                                                            
#         commande-CMD arg1 arg2 ... argn                                      
#                                                                              
# si elle existe; sinon elle envoie une réponse d'erreur.                     

function interaction() {
    local cmd args
    while true; do
	read cmd args || exit -1
	fun="commande-$cmd"
	if [ "$(type -t $fun)" = "function" ]; then
	    $fun $args
	else
	    commande-non-comprise $fun $args
	fi
    done
}

# Les fonctions implémentant les différentes commandes du serveur


function commande-non-comprise () {
   echo "Le serveur ne peut pas interpréter cette commande"
}

function commande-shutdown() {
       shutdown -t 10
}

# Le "touch" me sert a avoir une trace coté serveur de la bonne réception d'une commande. Il ne sert a rien d'autre.
function commande-reponse() {
       echo "reponse du serveur"
       touch yahoo
}

function commande-convert() {
       echo $1 | tr '[:lower:]' '[:upper:]'
}

# On accepte et traite les connexions

accept-loop

L'utilisation standard de ce serveur est la suivante :

Il suffit de donner en argument le port sur lequel le serveur netcat doit écouter et attendre une connexion.

Un client (en local pour l'exemple) peut ensuite venir se connecter en faisant:

nc localhost port

Mon objectif et mon plus gros problème est le suivant :
Une fois connecté il suffit alors de tapper la commande puis d'appuyer sur entrée pour que le serveur la traite. Seulement j'aimerais pouvoir envoyer une commande à ce serveur sans pour autant la taper manuellement coté client.

Pour ce faire j'ai essayé les méthodes :

echo -n "commande\r" | nc localhost 8080
nc localhost 8080 < testducat
cat testducat | nc localhost 8080

Avec un fichier texte "testducat" contenant la commande a envoyer.


Mais le serveur ne réagit absolument pas. Pourtant ce type de commande devrait imiter à la perfection une entrée au clavier non ?
De plus elle ressemble fortement à la commande d'exemple proposée dans le man de netcat...

Je suppose que le/la FIFO présente coté serveur empèche la réception de la chaîne de caractère envoyé par echo.

Étonnamment la seul fois où j'ai réussi à faire parvenir une commande sans la taper c'est de la manière suivante :

yes "reponse" | nc localhost 8080

Cette commande sature de "reponse" le serveur et celui-ci répond. Mais ce n'est évidemment pas très pratique étant donné que la commande coté serveur est exécutée une infinité de fois...

Sincèrement j'ai passé plusieurs heures cette après midi pour trouver une solution. Je vous prie de croire que ce n'est pas par fainéantise que je me permets d'appeler à l'aide tongue Mais bien parce que je ne comprends pas où est le problème smile

Hors ligne

#2 Le 28/05/2010, à 09:25

Totor

Re : Problème avec un "serveur netcat" simple.

Bonjour,

Pour envoyer des instructions à ton serveur, il faut utiliser l'option -c.
Ex : nc -c "echo reponse" localhost 8080

Dans ce contexte voici un script qui peut t'aider.

Maintenant, si tu utilises un FIFO, je pense (car je n'ai pas testé et je n'en ai pas les moyens au taf) qu'il faut l'alimenter avant de lancer ton backpipe.

Dans ton cas :

[...]
[ -e "FIFO" ] || mkfifo "$FIFO"
echo "reponse" > ${FIFO}
[...]
accept-loop

-- Lucid Lynx --

Hors ligne

#3 Le 28/05/2010, à 18:16

Tetsuo6995

Re : Problème avec un "serveur netcat" simple.

Super ! Merci pour la réponse. Je n'avais pas trop compris l'utilité de l'option -c.
Je vais tester ça tout de suite.
Par contre je ne suis pas sûr de comprendre comment fonctionne la fifo.
Comme je fais mes tests en local, dois-je prendre une fifo différente de celle utilisé sur le serveur ? En effet ce client/serveur doit pouvoir fonctionner aussi de manière réellement distante.
Mais bon je vais commencer par tester si l'option -c fonctionne avant de me tourner vers une fifo en émission..

EDIT:

nc -c "echo reponse" localhost 8080

Je ne comprends pas trop la forme de cette commande. Ne serait-ce pas plutôt:

echo "reponse" | nc -C localhost 8080

Cela ne fonctionne pas. Je me tourne vers la fifo smile

Dernière modification par Tetsuo6995 (Le 28/05/2010, à 18:25)

Hors ligne

#4 Le 29/05/2010, à 14:02

Totor

Re : Problème avec un "serveur netcat" simple.

Bonjour,

Je suis depuis peu sous Lucid et je m'aperçois que la version de netcat a bien changée. l'option -c n'existe plus.

Enfin bon, alors la forme à utiliser est la suivante :

nc localhost 8080 <<< reponse
# qui est un équivalent à echo reponse| nc localhost 8080

Cependant, cette forme n'attend pas la réponse du serveur, il faut donc feinter avec un autre backpipe (FIFO) :

reponseServeur="$({ nc localhost 8080 </tmp/bickpipeclient| { echo "ce que tu veux envoyer au serveur"; read reponse; echo "${reponse}" >&3; } >/tmp/bickpipeclient ; } 3>&1 )"
echo "${reponseServeur}"

Par contre, le serveur est à lancer avec l'option -k pour ne pas qu'il s'arrête à chaque demande client.

Dernière modification par Totor (Le 30/05/2010, à 13:02)


-- Lucid Lynx --

Hors ligne

#5 Le 01/06/2010, à 15:03

Tetsuo6995

Re : Problème avec un "serveur netcat" simple.

Ah ! Merci !
Le triple chevron <<< marche très bien smile
En particulier si on ajoute une option -q 1 à nc.

Avec cette syntaxe je reçois bien la réponse du serveur.

Hors ligne