Ticket #132 (assigned feature)

Opened 9 months ago

Last modified 8 weeks ago

Streaming songs for unauthorized users but only via flash player.

Reported by: CoF Owned by: vollmerk
Priority: minor Milestone: 3.5 Beta Release
Component: Streaming / Playback Version: SVN
Keywords: Cc:

Description

So, the idea was to put a small flash player with ability to play only one song at the time on my forum. For example, you can use tag [song]ID/song and after posting you will see flash player (XSPF). But there were two problems: 1. How to stream music for unauthorized users. 2. Everyone would be able to look at HTML code and see the URL which allow to stream any song, so it would be potentially

possible to grab music even if you're not logged in. So I've solved both problems. For the first one I modified lib/init.php and placed the code which allow to stream music via special file (analogue of play/index.php). This file (named flash.php) queries the DB and return XSPF-formated playlist for requested song. But you still can not see music library in main Ampache interface if you're not logged in.

But there was still the second problem: you could request URL like http://ampache/play/flash.php?play=any_id and you would get a playlist where would be real song URL using which it was possible to grab the song. But I dealt with it too and I'd explain my algorithm if there was a need...

To summarize: I've modified Ampache to stream songs even for not logged users via a tiny flash player bar. At the same time there's no way to grab the music by using brute force, simple changing songs ID's. I hope you've got the idea...

So, let's see what shall we do to make it work. Make sure you're using Apache web-server with MOD-REWRITE enabled. I wasn't able to make it work without mod-rewrite because of XSPF stupidnes (it doesn't send query_uri to playlist creation script)...

After that we should create play/flash.php file with the code:

<?php

/* Getting hashes */

$encrypted_id = $_GET['id'];
$hash1 = $_GET['hash1'];
$hash2 = $_GET['hash2'];

/* ==== */

/* Checking hashes */

function doDecrypt($hash1, $encrypted_id, $hash2)
        {

        $hash_parts = explode("_", $hash);
        $decrypted_id = HexDec($encrypted_id)-15; //Getting the real ID
        $real_hash = md5($decrypted_id."My_Secret_Word");

        if ($real_hash == $hash1.$hash2)
                return $decrypted_id;
                else return 0;
        }


$real_id = doDecrypt($hash1, $encrypted_id, $hash2);

/* === */

define('FLASHPLAYER', true);
require_once '../lib/init.php';

$stream = new Stream('xspf',array($real_id));
$stream->start();


?>

The idea is: even if you know song ID you won't be able to grab it as you can not generate check-hashes yourself. Don't forget to change "My_Secret_Word" to something else!

Create play/.htaccess and put into:

RewriteEngine On

RewriteRule ^(play+)-([0-9A-z]*)-([0-9A-z]*)-([0-9A-z]*)$ flash.php?hash1=$2&id=$3&hash2=$4

So you have the ability to use URLs like: http://ampache/play/play-hash1-encrypted_id-hash2

Now open lib/init.php and find:

if (NO_SESSION != '1' AND Config::get('use_auth')) {

Add BEFORE:

if (!defined('FLASHPLAYER'))
        {

Find:

}
        $GLOBALS['user'] = User::get_from_username($sess_results['username']);
}

Add AFTER:

        }
elseif (defined('FLASHPLAYER'))
{
        if (vauth::check_session())
        {
        
        //If we're already logged in then use current login
        
        $GLOBALS['user'] = User::get_from_username($_SESSION['userdata']['username']);
        /* If they user ID doesn't exist deny them */
        if (!$GLOBALS['user']->id AND !Config::get('demo_mode')) { vauth::logout(session_id()); exit; }
        }
        else
        {
        //Or use default flash player user.
        $GLOBALS['user']                 = new User(4); //!!!!! DON'T FORGET TO CHANGE USER ID!!
        $GLOBALS['user']->offset_limit = 50;
        }
        
 
}

Be careful! You should create a new user named, for example, Flash Player User and then set its ID in

$GLOBALS['user']                 = new User(ID);

line. So if an unauthorized user play the song via flash-player it will seems like the song is played by Flash Player User.

Ok, now we have the ability to stream song through our flash player even if we're not logged in. Going on.

Here's the function which will give you encrypted URL to create playlist with one song which you request:

function doEncrypt($id)
        {
        $crypted_id = DecHex($id+15);
        $hash = md5($id."My_Secret_Word"); //Don't forget to change!
        $part1 = substr($hash, 0, 16);
        $part2 = substr($hash, 16, 32);
        return $part1."-".$crypted_id."-".$part2;
        }
        /* End */

Example: echo doEncrypt(340);

This function will decrypt the string like hash1-encrypted_id-hash2 to real id and "0" if the hashes are wrong:

/* Returns real id by full hash */

function doDecryptFullHash($fullhash)
        {

        $hash_parts = explode("-", $fullhash);
        $decrypted_id = HexDec($hash_parts[1])-15; //Getting the real ID
        $real_hash = md5($decrypted_id."My_Secret_Word"); //Don't forget to change! Should be the same as in encryption procedure

        if ($real_hash == $hash_parts[0].$hash_parts[2])
                return $decrypted_id;
                else return 0;
        }
        /* End */

At last, the skin for XSPF. Create new folder name "Slim" in modules/flash/ and place skin.xml with the code:

<?xml version="1.0" encoding="UTF-8"?> 
<skin version="0" xmlns="http://xsml.org/ns/0/"> 
<width>460</width>
<height>16</height>
<name>
Slim
</name> 
<author>
CoF
</author> 
<email>
netultima@gmail.com
</email> 
<website>
http://code.pp.ru
</website> 
<objects>
<shape shape="rectangle" width="458" height="14" color="EAEAEA" />
<object label="playButton" x="5" y="3" width="9" height="9" color="999999" />
<object label="loadBar" x="20" y="2" width="268" height="11" alpha="80" color="BBBBBB" />
<object label="timeBar" x="20" y="2" width="268" height="11" alpha="70" color="999999" />
<object label="trackDisplay" x="20" y="" width="268" size="9" font="Arial" color="333333" align="center" />
<object label="timeDisplay" x="296" y="" size="9" font="Arial" color="333333" />
<object label="volumeDisplay" x="325" y="4" width="15" height="7" color="444444" />
<object label="infoButton" x="350" y="-1" size="-2" color="333333" text="Album info" font="Arial" bold="1" hoverMessage="Album info" />
<object label="startButton" width="460" height="16" alpha="0" />
</objects>
</skin>

What's now? Now you can generate encrypted hash by the song id and request the URL: http://ampache/play/play-your-full-hash and the script will return you the XSPF formatted playlist which you can you:

http://ampache/modules/flash/xspf_jukebox.swf?repeat_playlist=false&crossFade=false&shuffle=false&skin_url=http://ampache/modules/flash/slim_gray/&playlist_url=http://ampache/play/play-your-full-hash

And of course you can put it into web page:

<object type="application/x-shockwave-flash" width="460" height="16" data="http://ampache/modules/flash/xspf_jukebox.swf?repeat_playlist=false&crossFade=false&shuffle=false&skin_url=http://ampache/modules/flash/slim_gray/&playlist_url=http://ampache/play/play-your-full-hash"><param name="movie" value="http://ampache/modules/flash/xspf_jukebox.swf?repeat_playlist=false&crossFade=false&shuffle=false&skin_url=http://ampache/modules/flash/slim_gray/&playlist_url=http://ampache/play/play-your-full-hash" /></object>

If you're going to integrate the script into your forum/blog/cms engine - you should do it yourself. You have encryption and decryption functions so you should only create the function which what replace [song]/song tag to HTML code and inversely...

So if anyone was able to realize what I had written - that's just great...

Attachments

screen.jpg (33.3 kB) - added by CoF 9 months ago.
That's how it looks on my forum…

Change History

Changed 9 months ago by CoF

That's how it looks on my forum...

Changed 6 months ago by vollmerk

  • status changed from new to assigned
  • version set to SVN
  • milestone set to 3.5 Beta Release

Add/Change #132 (Streaming songs for unauthorized users but only via flash player.)

Author



Action
as assigned
 
Note: See TracTickets for help on using tickets.