ASX/M3U/PLS On-Demand Playlist Generator

Using a single php file and a simple rewrite rule, it is possible to turn any standard website hosting account in to a on-demand stream server with automatic playlist generation (to launch specific players, ect).

Place this into a file called playlist.php in the root folder:

  // Auto Playlist Generator by R. McAnally 6/2010
  // To be used with proper rewrite rules
  $expire = "Expires: " . gmdate("D, d M Y H:i:s", time()) . " GMT";
  header("Cache-Control: max-age=86400, must-revalidate");
  header("Content-Disposition: filename=".basename($_SERVER['REQUEST_URI']));
<?php if ( strtolower($_REQUEST['type']) == 'asx' ) {
header("Content-Type: video/x-ms-asf"); ?>
<ASX version="3.0" >
  <Repeat count="8">
    <Ref href="<?php echo 'http://'.$_SERVER['SERVER_NAME'].'/'.$_REQUEST['file'] ?>" />

<?php } elseif ( strtolower($_REQUEST['type']) == 'm3u' ) {
header("Content-Type: audio/x-mpegurl"); ?>
<?php echo 'http://'.$_SERVER['SERVER_NAME'].'/'.$_REQUEST['file'] ?>

<?php } elseif ( strtolower($_REQUEST['type']) == 'pls' ) {
header("Content-Type: audio/x-scpls"); ?>
<?php echo 'http://'.$_SERVER['SERVER_NAME'].'/'.$_REQUEST['file'] ?>


Then, add the following rewrite directives into an .htaccess file in the same location:

RewriteEngine on
RewriteRule ^(.*)\.(asx|pls|m3u)$ playlist.php?file=$1&type=$2

Now simply upload some media files (.wma, .wmv, .mp3, ect).

For example, you have set this up on and uploaded test.mp3. To access it on-demand using a standard player, use the following URL:

To access it using Windows Media Player, use the following instead:

Make sense? I hope so!

mod_security rule for e107 ‘plugindir’ and ‘ifile’ remote include vulnerability

Here are modsecurity2 rules for the latest string of vulnerabilities affecting the E107 CMS system described in the following links:

SecRule ARGS:THEMES_DIRECTORY "^http" "t:htmlEntityDecode,t:urlDecode,t:lowercase,deny,log,auditlog,msg:'Denied e107 vulnerability'"
SecRule ARGS:ifile "^http" "t:htmlEntityDecode,t:urlDecode,t:lowercase,deny,log,auditlog,msg:'Denied e107 vulnerability'"
SecRule ARGS:plugindir "^http" "t:htmlEntityDecode,t:urlDecode,t:lowercase,deny,log,auditlog,msg:'Denied e107 vulnerability'"
SecRule ARGS:author_name "\[php\]" "t:htmlEntityDecode,t:urlDecode,t:lowercase,deny,log,auditlog,msg:'Denied e107 vulnerability'"

Remotely installing PFSense to hard drive with VGA and without CD-ROM

FreeBSD is great for certain tasks (such as firewalls and other embedded devices), but has some real shortcomings when it comes to booting from attached or remote storage. This severely complicates the installation process in some cases.

In my case, I have a remote server in a rack with no CD-ROM. Pulling the server from the rack and plugging in an IDE/SATA CD-ROM is not an option, as there is no physical access at the current moment (I’m about 90 miles away on travel). So far the following methods of getting FreeBSD / PFSense installed have failed miserably:

1. Boot CD-ROM ISO over PXE (current memdisk). Negative.

2. Boot CD-ROM ISO from USB CD-ROM. Negative.

3. Boot CD-ROM ISO from virtual storage (IPMI CD-ROM). Negative.

OK, so it’s 2010 and FreeBSD can’t boot from anything other than a plain old IDE/PATA CD-ROM (which isn’t an option). Seriously, WTF?

So back to the drawing board. Let’s try some other more or less obvious options:

4. Burn PFSense embedded image directly to hard drive using the same instructions for CF memory. Negative. I even watched the serial console through IPMI – nothing.

5. Boot embedded image from network (memdisk). Negative.

All five of these methods have failed.

Time to use brute force, and if this doesn’t work I am banning FreeBSD from my life.

Yank HDD from laptop, throw in a spare, and boot the CD-ROM on the laptop.

Proceed to install PFSense.

Boot into Linux (or FreeBSD, doesn’t matter) rescue mode CD with network connectivity.

Copy the HDD image off to a remote site:

Remote machine (intermediary storage server, in this case my mirror box):

nc -l -p 2222 | dd of=pfsense.img.gz

Local machine (laptop):

dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c -9  | nc -p 2222

Once you’ve got the image, it’s time to boot the target PFSense machine into the same Linux/FreeBSD rescue mode and copy the image to the HDD. In the previous step, my working directory was the /pub folder on a public HTTP mirror. This allows me to burn the image directly over HTTP in the following step:

wget -O- | gzip -cd | dd of=/dev/sda

Much to my surprise, this actually worked! The saving grace for FreeBSD/PFSense, is that it’s able to be installed on one machine, then booted on another. Now on to learning how to use PFSense and configuring firewall rules.

If you want a copy of the HDD image to save you over half of this hassle, you can find it HERE. It was created with an 80Gb HDD so you’ll need at least an 80Gb disk for this to work. Good luck, you’ll probably need it.

Arbitrary MIME support for aacplus streaming with libshout and perl bindings

If you want to be able to support alternative stream types (such as AACplus) using libshout-2.2.2, you’ll need a patch to add a ‘mime’ method. You can then manually set the mime-type for arbitrary stream types. I also included a minor change which sends ‘content-type’ headers to Shoutcast/ICY stream servers, which is required for Shoutcast server support of AACplus streams:

libshout-2.2.2 patch

Additionally, if you’re streaming through Perl, the Perl bindings (Shout-2.1) will also have to be patched similarly both for mime support and for support of the ‘send-raw’ method which is required for non-mp3/ogg streaming. For some reason, send-raw was left out:

Shout-2.1 patch

Decrypting a SSL Server Key for importing into Cpanel

In case someone accidentally encrypts a server key (e.g. not following directions) then expects it to be accepted in to Cpanel, you’ll need to decrypt it first.

Most web hosting platforms (like Cpanel) need the server key to be in clear text. The private key can be decrypted with:

 openssl rsa -in encrypted.pem -out plaintext.key 

Make sure whomever encrypted the key provides you with the pass phrase.

Categories: Linux and Technical. Comments Off on Decrypting a SSL Server Key for importing into Cpanel

Automatically purge old voicemail on Asterisk/FreePBX/Trixbox

Run this nifty Perl script daily or weekly via cron. This will keep your voicemail from overflowing and unknowingly rejecting new voicemail.

# Script to expire voicemail after a specified number of days
# by Steve Creel

# Directory housing the voicemail spool for asterisk
$dir = "/var/spool/asterisk/voicemail";

# Context for which the script should be running
$context = "default";

# Age (Delete files older than $age days old)
$age = 31;

# Age for unheard messages (Defaults to same age for all messages)
# Set to 0 to not delete unheard messages
$unheardage = $age;

# Delete all files older than $age and $unheardage
# (named msg????.??? to get the audio and txt files,
# but we don't delete greetings or the user's name)

if($age==$unheardage) {

# Save time by doing one find if we're treating everything the same
system('find '.$dir.'/'.$context.' -name msg????.??? -mtime +'.$age.' -exec rm {} \; -exec echo Deleted {} \;');

} else {

# Find everything not in a folder called 'INBOX' and delete it after $age days
system('find '.$dir.'/'.$context.' -path \'*INBOX*\' -prune -o -name msg????.??? -mtime +'.$age.' -exec rm {} \; -exec echo Deleted {} \;');

# If unheardage is set to 0, we won't delete any unheard messages
if($unheardage > 0) {

# Delete things that are in a folder called INBOX after $unheardage days
system('find '.$dir.'/'.$context.' -path \'*INBOX*\' -name msg????.??? -mtime +'.$unheardage.' -exec rm {} \; -exec echo Deleted {} \;');


# For testing - what number to we start when we renumber?
$start = "0";

# Rename to msg and a 4 digit number, 0 padded.
$fnbase = sprintf "msg%04d", $start;

# Make $dir include the context too

mod_security rule for Joomla com_properties [aid] vulnerability

Here’s a mod_security2 rule to block the latest SQL injection vulnerability in a popular Joomla module ‘com_properties’ dated 4/10/2010:

SecRule ARGS:option "com_properties" "phase:1,chain,drop,t:htmlEntityDecode,t:urlDecode,t:lowercase,deny,log,auditlog,msg:'Denied Joomla Component com_properties[aid] SQL Injection Vulnerability'"
SecRule ARGS:aid "\D"

Don’t expect this to be a substitute for updating your vulnerable code, but it will at least buy you and your clients time.

It never ceases to amaze me how incredibly careless PHP programmers are:

Windows Vista / Windows 7 / Server 2008 R2: 0xc0000225 after resizing partition or restoring backup

So I needed to shrink a C: partition of a Windows 7 (Server 2008 R2) machine.  After shrinking with Gparted (my open-source partitioning tool of choice), Windows no longer booted, with the boot manager complaining of 0xc0000225 (awesome error message as usual, Microsoft).

To get things working again, it was necessary to execute the following BCDedit.exe commands from a rescue disk (WinPE worked fine for me):

bcdedit /set {bootmgr} device boot
bcdedit /set {default} device boot
bcdedit /set {default} osdevice boot

After that, life is again normal.

Sometimes you might need to completely reinstall the MBR — for example, you restored only the c:\ partition from backup to a new already-partitioned disk, but did not restore the original partition table and MBR. This can be accomplished as following:

bootsect /nt60 SYS /mbr

In some cases, you may also need to make sure the boot partition is flagged ‘bootable’ or any of the above commands fail. To correct it:

DISKPART (to open the partition utility)
LIST DISK (disk number(s) will be shown)
SELECT DISK n (where n is the number of the disk - probably 0)
LIST PARTITION (partition number(s) will be shown)
SELECT PARTITION n (where n is the number of the Primary partition you wish to make Active)
ACTIVE (the selected partition on the selected disk will be made Active)

Installing RED5 Server on CentOS

First, download, extract and install:

mkdir /usr/local/red5; cd /usr/local/red5
tar -zxf red5-0.8.0.tar.gz

Install JAVA:

wget -O java.rpm.bin
chmod 755 java.rpm.bin; ./java.rpm.bin

Open new init script:

nano -w /etc/init.d/red5

Paste into init script:

# For RedHat and cousins:
# chkconfig: 2345 85 85
# description: Red5 flash streaming server
# processname: red5


# Source function library
. /etc/rc.d/init.d/functions

[ -r /etc/sysconfig/red5 ] && . /etc/sysconfig/red5


case "$1" in
echo -n $"Starting $PROG: "
$DAEMON >/dev/null 2>/dev/null &
if [ $RETVAL -eq 0 ]; then
echo $! > $PIDFILE
touch /var/lock/subsys/$PROG

[ $RETVAL -eq 0 ] && success $"$PROG startup" || failure $"$PROG startup"
echo -n $"Shutting down $PROG: "
killproc -p $PIDFILE
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$PROG
$0 stop
$0 start
status $PROG -p $PIDFILE
echo $"Usage: $0 {start|stop|restart|status}"

exit $RETVAL

Activate init script:

chmod 755 /etc/init.d/red5
chkconfig red5 --add
chkconfig red5 on

Update settings which are located at:


Run it:

/etc/init.d/red5 start