diff --git a/inc/config.php b/inc/config.php index 9dea8ad7..2c1e9dc8 100644 --- a/inc/config.php +++ b/inc/config.php @@ -23,8 +23,13 @@ define('TIME_COOKIE', 'arrived', true); // HASH_COOKIE contains an MD5 hash of TIME_COOKIE+SALT for verification. define('HASH_COOKIE', 'hash', true); + // Used for moderation login + define('MOD_COOKIE', 'mod', true); // Where to set the 'path' parameter to ROOT when creating cookies. Recommended. define('JAIL_COOKIES', true, true); + + // Whether or not to lock moderator sessions to the IP address that was logged in with. + define('MOD_LOCK_IP', true, true); // How long should the cookies last (in seconds) define('COOKIE_EXPIRE', 15778463, true); //6 months @@ -60,7 +65,12 @@ define('ERR_FILESIZE', 'Maximum file size: %maxsz% bytes
Your file\'s size: %filesz% bytes', true); define('ERR_MAXSIZE', 'The file was too big.', true); define('ERR_INVALIDZIP','Invalid archive!', true); - + + // Moderator errors + define('ERROR_INVALID', 'Invalid username and/or password.', true); + define('ERROR_INVALIDAFTER', 'Invalid username and/or password. Your user may have been deleted or changed.'); + define('ERROR_MALFORMED','Invalid/malformed cookies.', true); + // For resizing, max values define('THUMB_WIDTH', 200, true); define('THUMB_HEIGHT', 200, true); diff --git a/inc/display.php b/inc/display.php index c910e26c..29012046 100644 --- a/inc/display.php +++ b/inc/display.php @@ -34,6 +34,20 @@ ))); } + function loginForm($error=false, $username=false) { + if(function_exists('sql_close')) sql_close(); + die(Element('page.html', Array( + 'index'=>ROOT, + 'title'=>'Login', + 'body'=>Element('login.html', Array( + 'index'=>ROOT, + 'error'=>$error, + 'username'=>$username + ) + ) + ))); + } + class Post { public function __construct($id, $thread, $subject, $email, $name, $trip, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename) { $this->id = $id; diff --git a/inc/functions.php b/inc/functions.php index 4a70da32..b20ed091 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -318,7 +318,7 @@ return $result; } - function buildThread($id) { + function buildThread($id, $return=false) { global $sql, $board; $id = round($id); @@ -335,7 +335,19 @@ } else { $thread->add(new Post($post['id'], $thread->id, $post['subject'], $post['email'], $post['name'], $post['trip'], $post['body'], $post['time'], $post['thumb'], $post['thumbwidth'], $post['thumbheight'], $post['file'], $post['filewidth'], $post['fileheight'], $post['filesize'], $post['filename'])); } - @file_put_contents($board['dir'] . DIR_RES . $id . '.html', Element('thread.html', Array('button'=>BUTTON_REPLY, 'board'=>$board, 'body'=>$thread->build(), 'post_url' => POST_URL, 'index' => ROOT, 'id' => $id))) or error("Couldn't write to file."); + $body = Element('thread.html', Array( + 'button'=>BUTTON_REPLY, + 'board'=>$board, + 'body'=>$thread->build(), + 'post_url' => POST_URL, + 'index' => ROOT, + 'id' => $id + )); + + if($return) + return $body; + else + @file_put_contents($board['dir'] . DIR_RES . $id . '.html', $body) or error("Couldn't write to file."); } mysql_free_result($query); } diff --git a/inc/instance-config.php b/inc/instance-config.php index 1ae82a3f..1c433a9c 100644 --- a/inc/instance-config.php +++ b/inc/instance-config.php @@ -8,16 +8,16 @@ * You can copy values from config.php (defaults) and paste them here. */ - /* + // Database stuff - define('MY_SERVER', 'localhost'); - define('MY_USER', ''); - define('MY_PASSWORD', ''); - define('MY_DATABASE', ''); + define('MY_SERVER', '127.0.0.1'); + define('MY_USER', 'imgboard'); + define('MY_PASSWORD', 'DF3uHz4vvhUM6rCq'); + define('MY_DATABASE', 'imgboard'); - define('ROOT', '/'); + define('ROOT', '/board/'); // define('FOO', 'bar'); - */ + ?> \ No newline at end of file diff --git a/inc/user.php b/inc/user.php index 2bdf5c05..05deb0e3 100644 --- a/inc/user.php +++ b/inc/user.php @@ -15,9 +15,97 @@ if(!isset($_COOKIE[HASH_COOKIE]) || !isset($_COOKIE[TIME_COOKIE]) || $_COOKIE[HASH_COOKIE] != md5($_COOKIE[TIME_COOKIE].SALT)) { $time = time(); setcookie(TIME_COOKIE, $time, time()+COOKIE_EXPIRE, JAIL_COOKIES?ROOT:'/', null, false, true); - setcookie(HASH_COOKIE, md5(time().SALT), time()+COOKIE_EXPIRE, JAIL_COOKIES?ROOT:'/', null, false, true); + setcookie(HASH_COOKIE, md5($time.SALT), $time+COOKIE_EXPIRE, JAIL_COOKIES?ROOT:'/', null, false, true); $user = Array('valid' => false, 'appeared' => $time); } else { $user = Array('valid' => true, 'appeared' => $_COOKIE[TIME_COOKIE]); } + + // 'false' means that the user is not logged in as a moderator + $mod = false; + + // Creates a small random string for validating moderators' cookies + function mkhash($length=12) { + // The method here isn't really important, + // but I think this generates a relatively + // unique string that looks cool. + // If you choose to change this, make sure it cannot include a ':' character. + return substr(base64_encode(sha1(rand() . time(), true)), 0, $length); + } + + function login($username, $password, $makehash=true) { + global $sql, $mod; + + // SHA1 password + if($makehash) { + $password = sha1($password); + } + + $res = mysql_query(sprintf( + "SELECT `id`,`type` FROM `mods` WHERE `username` = '%s' AND `password` = '%s' LIMIT 1", + mysql_real_escape_string($username), + $password + ), $sql) or error(mysql_error($sql)); + + if($user = mysql_fetch_array($res)) { + return $mod = Array( + 'id' => $user['id'], + 'type' => $user['type'], + 'username' => $username, + 'password' => $password, + 'hash' => mkhash() + ); + } else return false; + } + + function setCookies() { + global $mod; + if(!$mod) error('setCookies() was called for a non-moderator!'); + + // MOD_COOKIE contains username:hash + setcookie(MOD_COOKIE, $mod['username'] . ':' . $mod['hash'], time()+COOKIE_EXPIRE, JAIL_COOKIES?ROOT:'/', null, false, true); + + // Put $mod in the session + $_SESSION['mod'] = $mod; + + // Lock sessions to IP addresses + if(MOD_LOCK_IP) + $_SESSION['mod']['ip'] = $_SERVER['REMOTE_ADDR']; + } + + function destroyCookies() { + // Delete the cookies + setcookie(MOD_COOKIE, 'deleted', time()-COOKIE_EXPIRE, JAIL_COOKIES?ROOT:'/', null, false, true); + + // Unset the session + unset($_SESSION['mod']); + } + + if(isset($_COOKIE['mod']) && isset($_SESSION['mod']) && is_array($_SESSION['mod'])) { + // Should be username:session hash + $cookie = explode(':', $_COOKIE['mod']); + if(count($cookie) != 2) { + destroyCookies(); + error(ERROR_MALFORMED); + } + + // Validate session + if( $cookie[0] != $_SESSION['mod']['username'] || + $cookie[1] != $_SESSION['mod']['hash']) { + // Malformed cookies + destroyCookies(); + error(ERROR_MALFORMED); + } + + // Open connection + sql_open(); + + // Check username/password + if(!login($_SESSION['mod']['username'], $_SESSION['mod']['password'], false)) { + destroyCookies(); + error(ERROR_INVALIDAFTER); + } + + $mod = $_SESSION['mod']; + } ?> \ No newline at end of file