How to run mplayer from PHP exec() www-data - php

I have a home server with some GUI to play internet radio using mplayer. But when I play it from the server, it wouldn't play and apache error log said access denied to to home directory.
I also use a exec(pkill mplayer) to stop a service before creating a new one.
So currently I have to add www-data to /etc/sudoer with ALL access and it worked. I tried to did /home/ but it won't start either.
So I want to know what is the best way to start mplayer from webserver without security risks.
This is my code
exec("pkill mplayer");
exec("mplayer -slave -quiet http://iedm-fl.akacast.akamaistream.net/7/293/156397/v1/auth.akacast.akamaistream.net/iedm-fl </dev/null >/dev/null 2>&1 &");

If you want the sound to come out of the server:
Run sudo adduser www-data audio and reboot your server. This will give the user www-data permission to produce audio. After that, your original code should work. If it doesn't, try something simpler:
exec("pkill mplayer");
exec("mplayer http://iedm-fl.akacast.akamaistream.net/7/293/156397/v1/auth.akacast.akamaistream.net/iedm-fl&");

I guess when you try to run something from your /home www-data probably doesn't have rights for this location.
About security i'm not so sure but you are giving www-data users rights to run mplayer as root. Therefor mplayer becomes vulnerable to exploitation.
maybe you can isolate rights to a single script to run mplayer for them. Than give this script only execute rights so it can't be eddited so easy.

I've been trying to do this with video, but I just couldn't get the permissions right to display mplayer on the screen. So I created a BASH script to wait for a file change with inotifywait and then run mplayer as a user with permission to use it.
#!/bin/bash
# Mplayer server
# Watches for a file to be populated; then launches mplayer
PLAYFILE=/tmp/mserver_play.txt
CONTROL=/tmp/mserver_control
if [ -f $PLAYFILE ] ; then rm -f $PLAYFILE ; fi
while true ; do
touch $PLAYFILE
chmod a+w $PLAYFILE
r="$(inotifywait $PLAYFILE 2> /dev/null)"
if [ "$(echo $r | tail -1 | cut -d' ' -f2)" != "MODIFY" ] ; then
echo File removed or changed, exiting
exit 1
fi
# The wait is over! Play the file.
PLAYPATH="$(head -1 $PLAYFILE)"
rm $PLAYFILE
# TODO: Put in security checks on PLAYPATH.
if [[ -p $CONTROL ]]; then
rm -f $CONTROL
fi
mkfifo $CONTROL
chmod a+w $CONTROL
mplayer -autosync 30 -mc 2 -cache 10240 -cache-min 50 -ao sdl -lavdopts skiploopfilter=all -vf cropdetect -quiet -slave -input file=$CONTROL "$PLAYPATH" 2> /dev/null > /dev/null
done
Run that script as a user with permissions to run mplayer. mplayer probably has more tags here than are necessary for either of our purposes, but it works for both video and audio. Then in PHP you just write the path you want to play into the $PLAYFILE, e.g. with file_put_contents('/tmp/mserver_play.txt', $the_file_to_play).
Security, of course, is relative. Any user can write to the file to launch mplayer, and I couldn't find an easy way to restrict that; but adding www-data to your group and removing the chmods should probably work. You might, for example, want to restrict files to play to local files with test -f $PLAYPATH, but I want the ability to use http URLs there.

Related

Wordpress/PHP create a static copy of the page

I need to make a static page from the dynamic one with all assets downloaded and all the links converted to local ones and download it in some tmp folder. Like when you press Ctrl+S in a browser. I tried using wget with shell_exec:
shell_exec("wget -E -H -k -p http://youmightnotneedjquery.com/ 2>&1");
The problem is that it works perfectly when I run it from console, but when I use shell_exec, I get an error
Permission denied youmightnotneedjquery.com/index.html: No such file
or directory Cannot write to 'youmightnotneedjquery.com/index.html'
(No such file or directory).
As I understand, there is some problem with permissions, I tried to create a seperate directory
with some high permissions and www-data as owner and specify it in the command using -O flag, but I get an error that I can't use -k and -O flags at the same time. So I hope to solve that issue with permission, but I still have to specify the destination folder somehow. Or maybe there's a php solution without wget that I can use, as it seems not quite hard but a lot of work to do.
You may try something like
shell_exec("cd some_nice_dir && wget ...")
You may also want to read up on man wget as it has a lot to say about interferences between -O and several of the other options you specify.
Helped using -P flag and creating a folder with owned www-data
shell_exec("wget -E -H -k -p http://mysite.local/ -P some-temp-folder 2>&1")

Permission denied when logging on /var/log from a php script

I found my crontab scripts do not work as expected because they cannot write on /var/log. I tried executing command:
sudo /usr/bin/php /var/www/html/iPhone/inarrivo/php/rome/process.php >>
/var/log/romeLoading.log 2>&1
by hand and got:
-bash: /var/log/romeLoading.log: Permission Denied
/var/log permissions are:
drwxr-xr-x. 13 root root 4096 15 ago 16.20 .
If I conversely execute:
sudo touch /var/log/loadRome.log
I get no error whatsoever.
What could be the issue?
Please note Apache is not at stake: I am calling those scripts from the root crontab and from the shell with sudo as a test.
best guess: the user running the shell doesn't have write access to /var/log/romeLoading.log , and the stdout redirect (>>) is redirected by the shell user, not the sudo user, thus the access denied on >> , but not on sudo touch. maybe try
sudo sh -c '/usr/bin/php /var/www/html/iPhone/inarrivo/php/rome/process.php >> /var/log/romeLoading.log 2>&1'
that should run sh as root, and have the root-sh do the redirect with root permissions. untested though.
and next time you want to post permissions for debugging, post the namei -l path/to/file output, it gives much more info than stating the single file itself when debugging permission issues, as the issue can be higher up than the file itself, like the folder its in, or the folder that the folder it's in, is in, etc~ and namei gives you, recursively, detailed permission information on all of them.
It's a permissions issue as the log file belongs to root user and apache runs off www-data. Try chown www-data:www-data /var/log/loadRome.log.

HDD temp won't show via web

I'm trying to display my PIs temperatures in a website that I can access anywhere at any time.
So far I've been able to get the CPU and GPU temps working. However my HDD temp won't show in the browser. It works fine in terminal.
Here is a pic:
As you'll notice I didn't have the GPU temp showing either, however this was fixed by using the following command:
sudo usermod -G video www-data
I haven't been successful in getting this to work for smartmoxntools, though.
Does anyone know how to make it work?
Also, is it safe to have these in an external website? Can hackers inject php code to run shell commands using it?
in order to run some root privileged command in website, you need to put www-data in your /etc/sudoers to allow the www-data to run as root for the command, here is the line you need in /etc/sudoers:
www-data ALL=(root) NOPASSWD: /usr/sbin/smartctl
When executing under your web server, your script will probably have a different PATH configured, so it will run differently from how it runs in the Terminal.
Try putting the full path to smartctl in your script, e.g.
sudo /usr/local/bin/smartctl -A -d sat /dev/sda | awk '/^194/ {print $10}'

Run root script with Telegram Bot

I have a WebHook configured to commuticate with Telegram Bot, and I want to run some root commands when bot command arrives. As we know the Telegram Bot sends https request to our web hook, so I can only run shell script as www-data user. But I actually want to run it as root.
My script kill.sh:
#!/bin/bash
kill -9 $1
From php I run:
exec('kill.sh ' . $pidFromTelegramMessage);
Rights:
$ ls -al kill.sh
-r-xr-x--- 1 root www-data 24 Dec 16 15:27 kill.sh*
I even tried to put this script in /tmp directory but i does not work either. A always gets:
/tmp/kill.sh: 3: kill: Operation not permitted
I found only one way to do this. I put this line into /etc/sudoers by run visudo command:
www-data ALL = NOPASSWD: /bin/kill, /usr/bin/tail, /tmp/run.sh
Add execute permissions to /tmp/run.sh:
chmod a+x /tmp/run.sh
Now you can run these three commands as www-data user:
sudo kill -9 32233
sudo /tmp/run.sh
But you must think twice before allow anyone execute /tmp/run.sh script.

Running command-line application from PHP as specific user

I am running Apache on my localhost. From a PHP script run as www-user I would like to control Rhythmbox playback on my machine. So far I have a simple command in my PHP script:
exec('rhythmbox-client --pause');
This works great when I run it from the command-line as me, but if it runs as www-user I guess rhythmbox-client doesn't know/can't access my instance of Rhythmbox.
Is there an easy way for that PHP script to run as my user rather than www-user, or to tell rhythmbox-client which instance to control?
The overall application is that when my phone goes off-hook it calls my PHP script which pauses music, and resumes playback when the phone is on-hook. I love VoIP phones!
Solution:
Thanks to Carpetsmoker and Tarek I used sudo as the answer but there was a couple of problems. To overcome them I did the following:
Created a bash script to call rhythmbox-client. This bash script was executed using sudo in PHP as described in the answer below. Unfortunately rhythmbox-client didn't know what environment to control, so the bash script looks like this:
#! /bin/bash
DBUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/*/environ 2> /dev/null| sed 's/DBUS/\nDBUS/g' | tail -n 1`
if [ "x$DBUS_ADDRESS" != "x" ]; then
export $DBUS_ADDRESS
/usr/bin/rhythmbox-client --pause
fi
Now that bash script can be executed by PHP and wwwuser, and my phone can pause/play my music!
One solution is using sudo(8):
exec('sudo -u myuser ls /');
You will, obviously, need to setup sudo(8) to allow the user running your webserver to invoke it. Editing the sudoers file with visudo(8), you can use something like:
wwwuser ALL=/usr/bin/rhythmbox-client
To prevent Apache from being able to run other commands and only the rythymbox command.
In my case, the solution came this way:
Added this lines to sudoers file:
myuser ALL=(ALL) NOPASSWD: /usr/bin/prlctl
_www ALL=(ALL) NOPASSWD: /usr/bin/prlctl # IMPORTANT!!!
The EXEC() command in PHP was changed to:
exec("sudo -u myuser prlctl list -a", $out, $r);
If a process can be run by any user it can be run by PHP. Example is fortune command
-rwxr-xr-x 1 root root 18816 Oct 1 2009 /usr/games/fortune
Look at the x permission for every user. But this some times doesn't at all work and you may have to let the user, www-data or apache etc, run the program. You can sudo www-data and try to run the command. If it works then Apache/PHP should be able to run it.

Categories