[FIM-PHP-Shell] - Contourner l'interdiction d'exec externe

Bonjour,

Je suis toujours sur ma problématique d’exécution distante (Cf : au-menu-php-shell-fbi-omxplayer-rpi-t43105.html). J’ai maintenant la possibilité d’exécuter fim (frame buffer image improved) à distance.
Je peux donc lire mes images à distance.
Petit problème, l’exécution de la même commande en distant et en local ne donne pas le même résultat :
La commande :

/usr/local/bin/fim -a -q -c 'sleep 4; q;' /media/Images/Ski.jpg Objectif de la commande : Afficher l’image, attendre 4 secondes puis fermer proprement fim.
Utilisateur local de la commande : pi (utilisateur n’ayant pas les droits root sur le système)
Interpréteur de pi : /bin/bash
Utilisateur distant : www-data (je pense)
Interpréteur de www-data : /bin/bash (je l’ai changé)
Droits sur le fichier php : 777
Droits sur le fichier script.sh : 777

Méthode d’exécution à distance :
Dans un navigateur je lance : 192.168.1.20/test.php
Test.php lance la commande : shell_exec("/var/www/script.sh");
script.sh lance la commande susnommé.

Problématique :

En local, je lance la commande et tout fonctionne.
En distant, je lance la commande, et au moment de quitter, l’image reste figé sur les 3/4 de l’écran, et je peux alors écrire dans mon shell sans soucis. Comme si fim n’avait pas été bien fermé.

Solutions tentés :

  • Changement de l’interpréteur par défaut de www-data.
  • Changement de la méthode de fermeture de fim (fim -a -q image.jpg + killall fim)
  • Changement de la méthode de fermeture de fim(fim -a -q image.jpg + kill $(pgrep fim))
    A chaque fois, la méthode de fermeture fonctionne en local mais plante en distant.
  • Exécution du php en local (php5-cgi test.php) depuis www-data et pi

Donc : Qu’est ce qui fait que la commande s’exécute parfaitement en local mais pas bien en distant ?
Début de réponse : La fermeture doit s’effectuer d’une certaine manière, l’utilisateur étant différent en local et en distant le framebuffer ne gère peut être pas bien cette fermeture…

Avez-vous des suggestions ?

Merci de m’avoir lu,

JayGr

Edit : 11:20 : 17-05-2013
En enlevant le q; tout se passe bien à distance.
C’est donc la fermeture de fim qui foire. A quoi fais alors appel la fermeture d’un logiciel ?

Edit : 11:27 : 17-05-2013
En essayant de l’exécuter en local et en fond de tâche, j’obtiens le même résultat qu’en distant.
Que dois-je en conclure ?
J’ai en fait l’impression que le framebuffer ne se vide pas…

Edit : 18:00 : 17-05-2013
Je me suis pencher sur autre chose aujourd’hui, mais je suis de très près le topic. Si vous avez la moindre idée dites le !
Il faut essayer !

Je me permet de relancer le sujet !
Si vous avez la moindre suggestions, n’hésitez pas à me donnez des idées, je suis un peu à court…
En vous souhaitant un bon week end pour ceux qui y sont.

JayGr

Salut,

A tout hasard et par pur raisonnement : Dès que FIM se ferme il n’a plus la main sur l’affichage et ne peut donc finir d’effacer l’écran : un clear avant le q ?

[quote=“ggoodluck47”]Salut,

A tout hasard et par pur raisonnement : Dès que FIM se ferme il n’a plus la main sur l’affichage et ne peut donc finir d’effacer l’écran : un clear avant le q ?[/quote]

Salut ggoodluck47 !

Merci d’avoir pris un peu de ton temps pour me répondre. Je n’avait pas pensé, en effet, à ajouter un clear :wink:.
Malheureusement cela ne fonctionne pas.
J’ai trouvé une alternative qui m’ira pour l’instant… Mais c’est un peu… :079 -> Barbare !
L’alternative est la suivante :

#!/bin/sh
/usr/local/bin/fim -a -q img1.jpg &
sleep 4
/usr/local/bin/fim -q black.jpg &
sleep 1
killall fim
...

Donc je lance une image de 10x10 qui me permet de ne rien avoir à l’écran quand je quitte. Malheureusement… Ce n’est pas propre et c’est une solution plutôt barbare.

Donc je suis toujours en attente de proposition… Je commence à me dire que ce n’est peut être tout simplement pas faisable…

JayGr

Bonjour à tous,

J’espère que ce WE a été bon, en attendant, je continue mes recherches en ce début de semaine. Et ça avance …
Doucement…

Bon, petite piqûre de rappel :
test.php

<?php
shell_exec("/var/www/test.sh");
?>

test.sh

#/usr/bin/sh
/usr/local/bin/fim -a -q -T 2 -c 'sleep 2;next;q;' image1.jpg image2.png

Donc, depuis le Raspberry Pi hébergeant le serveur web :

  • Tout fonctionne parfaitement, que ce sois le lancement via la commande php5-cgi test.php ou le lancement de sudo ./test.sh

Depuis un navigateur :

  • La commande n’est pas pris en compte entièrement : L’image s’affiche puis se ferme instantanément -> La fermeture ne s’effectue pas correctement…
    => A la fermeture, il y a un bandeau noir au dessus de l’image, l’image se fige et c’est terminé…

Depuis putty (en ssh) :

  • La commande php5_cgi test.php donne le même résultat que depuis un navigateur web sauf que le sleep est pris en compte avant la fermeture…
    => De plus, lors de l’exécution j’obtiens ceci :
ioctl VT_GETSTATE: Invalid Argument (not a linux console ??) 
ioctl VT_GETSTATE: Invalid Argument 

J’ai donc décidé de googler mon affaire… Mais rien n’y fait.

Bilan :
Je pense que le fait d’exécuter le php5 à distance fait appel à mon serveur web (lighttpd) d’une manière différente. Il n’exécute pas alors complètement la commande…
Donc : Comment préciser clairement la manière dont mon serveur doit exécuter les scripts shell ?
-> J’ai en parti répond en cherchant sur google. Mais la plupart des serveurs ne sont pas des serveurs lighttpd… Alors je ne suis pas sûr.

Je m’y perd !

Venez moi en aide messieurs dames !

Merci de m’avoir lu,
JayGr.

NB : Mon “alternative” du post précédent ne fonctionne en fait pas du tout…

Bonjour à tous…

fim also needs access to the linux console (i.e. /dev/ttyN) for sane console switch handling. That is obviously no problem for console logins, but any kind of a pseudo tty (xterm, ssh, screen, ...) will not work.
-> RTFM
Bon…
J’ai perdu pas mal de temps. Bizarrement, fim est exécutable à distance mais plante. Donc bon… Je pense que le problème reste le même, quand on exécute fim depuis un script php enchaîné à un script shell ça ne fonctionne pas.
Donc, j’ai discuté avec enikar sur le chat debian-fr. Il m’a été de très bon conseil.

Il a d’abord eu l’idée de créer un daemon qui ferais le boulot. En fait, de cette manière nous pensions pouvoir avoir la main complète sur le tty. Puisque c’est ça qui pose problème à fim.
Malheureusement… Cela ne fonctionne pas non plus.
Le daemon n’utilise pas directement le tty puisque qu’il ne lui est pas “alloué”.
Donc : J’ai discuté une fois de plus avec enikar, et il m’a parlé de ceci (c’est openvt, il ouvre des console donc il alloue une console à un programme) : fossies.org/dox/console-tools-0 … ource.html :041
Bref…
L’objectif étant d’allouer un vt (virtual terminal) à mon script. De cette manière, nous écririons directement dans une console virtuel qui serait détruite à la fin de la session d’exécution. On pourrait alors créer et détruire des vt.
En regardant un peu le code (c’est du c => :038 ) j’ai découvert qu’on utilisait différentes fonctions :

Qu’en pensez-vous ?
Réalisable ?

Si vous ne m’avez pas suivi (ce qui est possible :118 ) :
L’algorithme de mon script ressemblerais à ça :

Création de la console virtuelle
tant que (condition)
  if (condition de fichier)
    je lis le fichier avec fim -> J'ECRIS DANS LA CONSOLE VIRTUELLE
  fi
fin de tant que

C’est grossier mais le principe y est…

S’il vous plaît ! Donner moi votre avis :wink:

JayGr.

Bonjour à tous,

Ci-dessous, vous trouverez la solution complète pour installer et exécuter fim à distance.

Installation de fim :

  • Désinstallation d’une version fim antérieure
    Tout d’abord, pour éviter les anomalies et problèmes, vous devez désinstaller toute version antérieure de fim

sudo apt-get remove fim

  • Installation fim 4.0
    Nous devons installer la dernière version de fim disponible ici : download.savannah.gnu.org/releases/fbi-improved/
    Télécharger là et mettez là sur votre Debian (vous pouvez aussi la télécharger directement depuis votre Debian)
    L’installation doit s’effectuer manuellement, la version disponible avec les dépôts n’est pas la dernière, veuillez donc suivre les étapes suivantes :
    Pour comprendre ces étapes, rendez-vous ici : linux-attitude.fr/post/utilisati … ke-install

sudo apt-get update && upgrade

sudo apt-get install subversion automake autoconf libtool libreadline6-dev libjpeg-dev libpng-dev libtiff-dev libgif-dev libsdl-dev libaa1-dev libpoppler-dev libdjvulibre-dev libspectre-dev bison flex

sudo xzf /fim-0.4-trunk.tar.gz

cd /fim-0.4-trunk.tar.gz

sudo ./configure

sudo make install

Vérifier ensuite que vous pouvez lancer la commande fim :

fim -a -q /monimage.jpg

Les options a et q permettent, respectivement, d’afficher correctement et sans légende l’image qui suit.
Vous devriez alors pouvoir afficher une image dans votre console (ah… les joies du framebuffer).
Afin de nous faciliter l’accès externe, vous pouvez mettre des droits sur le binaire de fim dans :

/usr/local/bin/

A vous de choisir pour les droits (chmod).

  • Installation de openvt
    Pour la suite, vous devez installer openvt, je reviendrais sur son utilisation.
    Openvt est une commande permet de lancer des terminaux virtuels (intriguant hein…).

sudo apt-get install console-tools

  • Installation de l’interpréteur Perl (il est nativement intégré à Debian mais on ne sais jamais)

  • Installation Lighttpd correctement configuré pour permettre l’utilisation
    Je n’expliquerais pas comment configurer un serveur web. Ce n’est ni le lieu ni le moment, il existe cependant beaucoup de documentation à ce sujet :
    debianhelp.co.uk/lighttpd.htm (par exemple)

  • www-data doit être un sudoers
    Pour la suite des événements, j’ai eu besoin de mettre www-data en sudoers. Pour ceux qui ne sauraient pas ce qu’est un sudoers :
    debian-easy.lavazzo.net/index.ph … -un-sudoer
    Modifier donc le fichier pour que l’utilisateur www-data (le serveur web pour ceux qui n’aurait pas compris ça) puisse effectuer des sudo sans mot de passe.

Principe de fonctionnement de l’accès externe à fim :

Afin d’être compris de tous, j’ai schématisé le fonctionnement de l’accès externe.
img4.hostingpics.net/pics/187200 … nement.png
:041 Grosse flemme de diminuer la taille de l’image :041

Bon, vous avez tout compris ?
Non…

Je vais y aller par étape :

  • Démarrage du Raspberry Pi
  • Création d’un pipe (ou tube nommée)
  • Lancement du script qui lancera les commandes fim par openvt
    Je fais une pause.
    Le principe de fonctionnement est le suivant, nous allons lancer un script qui, tout au long va attendre des commandes.
    Ces commandes lui seront envoyés par un pipe qui recevra les commandes d’une page php.
    Ce script est lancé avec openvt depuis inittab ---- > Mais pourquoi ???
    Pour la simple et bonne raison qu’en lancant mon script avec openvt (et la jolie commande du schéma) je permet à mon script d’être “propriétaire” de ce terminal virtual (ici le 12).
    Mon script est donc le fils de celui qui l’a lancé, il a donc les droits de son père (tel père tel fils :laughing: )
    Bref… Ce script recevra des commandes depuis le pipe (ou FIFO : First In First Out) et devra écrire dans la console (avec un exec ou autre).
    Fin de la pause.
  • Le serveur Web est lancé
  • Je suis sur mon navigateur sur mon tout moche pc windows et je lance la page suivante : monrpi.php?act=supercooljafficheuneimage
  • Le serveur web du rpi est contacté sur sa page php : monrpi.php
  • Il traite l’argument ?act=supercooljafficheuneimage qui lance la commande fim -a -q -c ‘sleep 2;q;’ image.jpg dans le pipe
  • Mon script lancé depuis le début détecte qu’il y a une commande dans le pipe
  • Mon script exécute cette dernière depuis son terminal (donc le terminal openvt)
    Voilà ! Vous avez lancé une image à distance !

Je ne fournirais pas, volontairement, le code perl du script qui exécute les commandes dans le terminal virtuel.
Je ne fournirais pas non plus le traitement php. C’est quelque chose que toute personne qui a compris ce qui précède peut faire.
Mais vous disposez maintenant du principe d’exécution de fim à distance !!

:violin: :violin: :violin: :violin: :violin: :violin: :violin:

Génial…

Voilà, j’ai réussi le plus difficile.

A vous de jouer,

JayGr.

PS : Pour ceux qui ont tout lu merci.

Remerciements :
enikar - Chat #Debian-fr
Sans lui… Je n’aurais pas réussi.