User:Jana Kamachi/WebDB

From Second Life Wiki
Jump to navigation Jump to search

If you like this script, or any script I've released, please post on my Talk page, or I'll most likely never see it o: If you want to improve a script, just go for it!


This first part is a PHP script. It requires a webserver with PHP 4+ & MYSQL. TODO

- Add SQLLite for flat filesystem storage where a database is not available.
- MSSQL
- Finish commands:
- - list
- - mkdir
- - rmdir
- - temp
- - commit
- Make it secure against SQL injections & Junk
<?php
	/////////////////////////////////////
	//Examples:
	// core.php?mode=list&path=_info          							<---------Shows System Files.
	// core.php?mode=list&path=_info&pass=rofl  	<---------Shows Admin Level System Files
	$settings["db"]["host"]				= "localhost";
	$settings["db"]["prefix"] 			= "public_";
	$settings["db"]["database"] 	= "<database name>";
	$settings["db"]["username"] 	= "<database username>";
	$settings["db"]["password"] 	= "<database password>";
	////////////////////////////////////
	//Don't edit below here if you don't know what your doing!!!
	///////////////////////////////////
    mysql_connect($settings["db"]["host"],$settings["db"]["username"],$settings["db"]["password"]) or die("Invalid Host/Username/Password");
    mysql_select_db($settings["db"]["database"]) or die("Database not found.");
	init();
	$headers    		= apache_request_headers();
	
	$obj["name"] 	= $headers["X-SecondLife-Object-Name"];
	$obj["key"]	   	= $headers["X-SecondLife-Object-Name"];
	$obj["oname"]	= $headers["X-SecondLife-Owner-Name"];
	$obj["okey"]		= $headers["X-SecondLife-Owner-Key"];
	$obj["region"]  = $headers["X-SecondLife-Region"];
	
	if(empty($obj["key"])) { //Should check IP's, but whatever.
		die("At the moment only in-world access is allowed. This WILL be changed soon!");
	}
	//////////////////////////////////////
	//Take all possible inputs and create a common var for all of them
	/////////////////////////////////////
		$qry["path"] 	= mysql_real_escape_string(($_GET["path"] 	? strtolower($_GET["path"]) 		: strtolower($_POST["path"])));
		$qry["mode"] 	= mysql_real_escape_string(($_GET["mode"] 	? $_GET["mode"] 	: $_POST["mode"]));
		$qry["data"] 	= mysql_real_escape_string(($_GET["data"] 	? $_GET["data"] 		: $_POST["data"]));
		$qry["pass"] 	= mysql_real_escape_string(($_GET["pass"] 	? $_GET["pass"] 	: $_POST["pass"]));
		$qry["rpass"] 	= mysql_real_escape_string(($_GET["rpass"]  ? $_GET["rpass"] 	: $_POST["rpass"]));
		$qry["flags"] 	= mysql_real_escape_string(($_GET["flags"] 	? $_GET["flags"] 	: $_POST["flags"]));
		
		switch(strtolower($qry["mode"])){
			case "get":		//<------------Gets a path's contents
				getPath($qry["path"],$qry["rpass"]);
				break;
			case "set":  	//<------------Sets a path's contents
				setPath($qry["path"],$qry["pass"],$qry["rpass"],$qry["data"]);
				break;
			case "list":  	//<------------Lists a path's contents
				break;
			case "info": 	//<-----------Gets info on a path
				getPathInfo($qry["path"],$qry["rpass"]);
				break;
			case "app": 	//<-----------Append to a path
				break;
			case "part": 	//<----------Gets only part of a path's contents
				break;
			case "delete": //<---------Delete a path
				deletePath($qry["path"],$qry["pass"]);
				break;
		}
		
		function getPathInfo($path,$rpass){
			global $settings;
			if(!pathExists($path)){
				die("BAD:NO PATH");
			}
			$sql	= "SELECT * FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '$path'";
			$row	= mysql_fetch_array(mysql_query($sql));
			if(md5($rpass) == $row["read_pwd"]){
				die("OK:" . strlen($row["data"]) . ":" . $row["modified"]);
			}else{
				die("BAD:INVALID PASSWORD");
			}
		}
		
		function deletePath($path,$pass){
			global $settings;
			if(!pathExists($path)){
				die("BAD:NO PATH");
			}
			$sql	= "SELECT * FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '$path'";
			$row	= mysql_fetch_array(mysql_query($sql));
			if(md5($pass) == $row["write_pwd"]){
				$sql = "DELETE FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '$path' LIMIT 1";
				mysql_query($sql);
				die("OK:DELETED");
			}else{
				die("BAD:INVALID PASSWORD");
			}
		}
		
		function setPath($path, $pass, $rpass, $content){
			global $settings;
			if(pathExists($path)){
				$sql	= "SELECT * FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '$path'";
				$row	= mysql_fetch_array(mysql_query($sql));
				if(md5($pass) == $row["write_pwd"]){
					$sql = "UPDATE `" . $settings["db"]["prefix"] . "values` SET `data` = '$content',`modified` = NOW( ) WHERE `path` ='$path' LIMIT 1;";
					mysql_query($sql);
					die("OK:UPDATED");
				}else{
					die("BAD:INVALID PASSWORD");
				}
			}else{
				$sql = "INSERT INTO `" . $settings["db"]["prefix"] . "values` (`id` , `path` , `data` , `read_pwd` , `write_pwd` ) VALUES ( NULL , '$path', '$content', MD5('$rpass'), MD5( '$pass' ) );";
				mysql_query($sql);
				die("OK:CREATED");
			}
		}
		
		function getPath($path,$rpass){
			global $settings;
			if(!pathExists($path)){
				die("BAD:NO PATH");
			}else{
				$sql	= "SELECT * FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '$path'";
				$row	= mysql_fetch_array(mysql_query($sql));
				if(md5($rpass) == $row["read_pwd"]){
					die("OK:" . $row["data"]);
				}else{
					die("BAD:INVALID PASSWORD");
				}
			}
		}
		
		function pathExists($path){
			global $settings;
			$sql = "SELECT * FROM `" . $settings["db"]["prefix"] . "values` WHERE `path` = '" . $path . "'";
			if(mysql_num_rows(mysql_query($sql))>0) return 1;
		}

		function init(){
			global $settings;
			$sql = "CREATE TABLE IF NOT EXISTS `" . $settings["db"]["prefix"]  . "values` (
							  `id` int(11) NOT NULL auto_increment,
							  `path` varchar(1000) NOT NULL,
							  `data` varchar(1000) NOT NULL,
							  `read_pwd` varchar(1000) NOT NULL,
							  `write_pwd` varchar(1000) NOT NULL,
							  PRIMARY KEY  (`id`)
							) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
			mysql_query($sql);
		}

?>


The next part is an example LSL script calling some of the functions.

string  url = "http://world.janashell.com/index.php?";
list    queries;


// Requests can return in different ways:
// All requests that succeded, return as "OK:"<data>
//      - For getInfo an example response is "OK:<length of the field>:<time stamp of last modified>"
//      - An example getFile is "OK:" <content>
// All requests that fail return as "BAD:" <reason>
//      - BAD PATH -> The path you requested doesn't exist.
//      - INVALID PASSWORD -> either the read or write password was invalid.
//      - SYSTEM RESERVED -> Touche pas! Me only.


appnd(key req, string path, string mode){
    queries = (queries = []) + queries + [req,mode,path];
}

integer getPos(key req){
    return llListFindList(queries,[req]);   
}

getFile(string path, string password){
    appnd(llHTTPRequest(url + "path=" + path + "&rpass=" + password + "&mode=get",[],""),"get",path);
}

setFile(string path, string pass, string rpass, string content){
    appnd(llHTTPRequest(url + "path=" + path + "&pass=" + pass + "&rpass=" + rpass + "&mode=set&data=" + llEscapeURL(content),[],""),"set",path);
}

deleteFile(string path, string pass){
    appnd(llHTTPRequest(url + "path=" + path + "&pass=" + pass + "&mode=delete",[],""),"delete",path);
}

getInfo(string path, string rpass){
    appnd(llHTTPRequest(url + "path=" + path + "&rpass=" + rpass + "&mode=info",[],""),"info",path);
}

default
{
    state_entry(){
        setFile("_sandbox/test2","<example>","<example>","This is a systems test. Test 4.");
        setFile("_sandbox/test3","<example>","<example>","This is a systems test. Test 5.");
        getInfo("_sandbox/test3","<example>");
        deleteFile("_sandbox/test3","<example>");
        getFile("_sandbox/test2","<example>");
    }
    http_response(key req, integer stat, list meta, string body){
        integer pos = llListFindList(queries,[req]);
        llSay(0,llList2CSV([llList2String(queries,pos+1),llList2String(queries,pos+2),body]));
    }
}