NineChime forum

Furry stuff, oekaki stuff, and other stuff.

You are not logged in.

#1 10-13-2008 01:02:37

rainbow
Member

Alphanumeric username issue.

Okay, I have a problem here.

When people register for my oekaki, I hard coded the registration system to only allow alphanumeric characters to only allow usernames that have upper and lowercase letters (A-Z, a-z) as well as numbers (0-9). And everything has been working quite well for a couple of years.

Now, today. Somehow, someone somehow used some sort of trick to try to bypass the alphanumeric character limits on their username upon registration by a entering a "_" in the middle part of their username as I already informed the user that their username has been automatically changed. I'm hoping that they're not upset about this.

Anyways, Here's the code to the username part of the registration that prevents the usage of non-alphanumeric characters in their username:

Code:

<script type="text/javascript">
    <!--
        function letternumber(e)
        {
        var key;
        var keychar;

        if (window.event)
            key = window.event.keyCode;
        else if (e)
            key = e.which;
        else
            return true;
            keychar = String.fromCharCode(key);
            keychar = keychar.toLowerCase();

        // control keys
        if ((key==null) || (key==0) || (key==8) ||
            (key==9) || (key==13) || (key==27) )
        return true;

        // alphas and numbers
        else if ((("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").indexOf(keychar) > -1))
            return true;
        else
            return false;
        }
    //-->
</script>

Is there a way to fix this issue to disalllow bypassing the usage of nonalphanumeric characters? If so, how would it be done. The area had been unaffected since the oekaki upgrade earlier this year.

Also, does the issue of entering nonalphanumeric characters in their username have to do with the Javascript being turned off?

Offline

#2 10-14-2008 05:07:24

Waccoon
Administrator

Re: Alphanumeric username issue.

You can only use JavaScript to inform the user if they didn't follow the requirement.  If they have JavaScript turned off, or use some kinds of ad blockers, the code won't work.

You can't rely on JavaScript to filter user data, and you must always verify the POST data on the server with PHP.

I already have a function to test for alphanumeric strings (with spaces and underscores) in common.php:

Code:

function w_toalpha ($in) {
    // Note underscore
    return (preg_replace ("/[^a-zA-Z0-9s_]/", '', $in));
}

USAGE:

if ($test != w_toalpha($test)) {
   // Not alphanumeric!
}

This function allows underscores and spaces.  To change that, remove the underscore and trailing "s" from the regular expression, as follows:

Code:

function w_strictalpha ($in) {
    return (preg_replace ("/[^a-zA-Z0-9]/", '', $in));
}

There's really no need to ban underscores, though.  Only backslahes, quotes, and some rare UTF-8 characters might cause problems.

Offline

#3 10-14-2008 07:53:20

rainbow
Member

Re: Alphanumeric username issue.

Waccoon wrote:

You can only use JavaScript to inform the user if they didn't follow the requirement.  If they have JavaScript turned off, or use some kinds of ad blockers, the code won't work.

You can't rely on JavaScript to filter user data, and you must always verify the POST data on the server with PHP.

I already have a function to test for alphanumeric strings (with spaces and underscores) in common.php:

Code:

function w_toalpha ($in) {
    // Note underscore
    return (preg_replace ("/[^a-zA-Z0-9s_]/", '', $in));
}

USAGE:

if ($test != w_toalpha($test)) {
   // Not alphanumeric!
}

This function allows underscores and spaces.  To change that, remove the underscore and trailing "s" from the regular expression, as follows:

Code:

function w_strictalpha ($in) {
    return (preg_replace ("/[^a-zA-Z0-9]/", '', $in));
}

There's really no need to ban underscores, though.  Only backslahes, quotes, and some rare UTF-8 characters might cause problems.

It's not working at all Wac. I even inserted this code in the common.php file:

Code:

if ($in != w_toalpha($in)) {
    // Not alphanumeric!
    report_err('Your user name contains illegal characters!');
}

I even changed the variable from $test to $in and it had no effect at all. I even tried the noscript tag and it had no effect at all.


Also, I did some checking in the functions.php file that references to the register.php file and this is what I found:

Code:

if ($action == 'register') {
    $username = w_gpc('username');
    $email    = w_gpc('email', 'email');
    $age      = decode_birthday($_POST['age_year'], $_POST['age_month'], $_POST['age_day']);
    $pass     = w_gpc('pass');
    $pass2    = w_gpc('pass2');
    $artURL   = w_gpc('artURL', 'url');
    $comment  = w_gpc('comments');

    if (empty ($username)) {
        all_done();
    }

    // Humanity test
    $x_test = w_gpc('x_test', 'i');
    $y_test = w_gpc('y_test', 'i');
    $e_test = w_gpc('e_test', 'i');
    if ($x_test + $y_test != $e_test || $e_test < 2) {
        w_exit('Humanity test failed.');
    }

    // Age verification?
    if ($cfg['op_adult'] == 'yes') {
        if (intval ($_POST['age_year']) < 1900 || intval ($_POST['age_year']) > 1999) {
            report_err('You must submit a valid age declaration (birth year).');
        }

        if (get_age($age) < MIN_AGE_ADULT) {
            report_err('Your age declaration could not be accepted.');
        }
    }

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        report_err('Your user name contains illegal characters: '.make_list($bad, ', ', '"'));
    }

Somehow, the $bad variable is ignoring the references to characters that are not allowed in a username.

I wonder if there is a way to fix that?

Offline

#4 10-15-2008 06:44:25

Waccoon
Administrator

Re: Alphanumeric username issue.

It's not working at all Wac. I even inserted this code in the common.php file:

Code:

if ($in != w_toalpha($in)) {
    // Not alphanumeric!
    report_err('Your user name contains illegal characters!');
}

Wait... did you literally put this in common.php?  Why?  The "$test" and "$in" variables do not contain any user or POST data.

Don't mess with the w_toalpha() function.  Its functionality must be left alone, because it is used by w_gpc().  You have to make a new function name for the "strict" alphanumeric function that does not allow underscores.

Somehow, the $bad variable is ignoring the references to characters that are not allowed in a username.

Which characters?  I just tested it and it seems to be working fine.

The code block if ($action == 'register') { is what receives the registration submission.  The registration name is assigned to $username in the line $username = w_gpc('username'); .  If you want to test that the username does not contain illegal characters, you have to test the $username variable in that section.

Before you edit the functions file any more, you may want to set up a test file so you can check what's really going on.  Here is a basic test file:

Code:

<?php
// Test file


// Bootstrap
define ('BOOT', 1);
require ('boot.php');


// Init -- use addslashes() to simulate input from w_gpc()
$username = addslashes ('#my$name*is/terribly_invalid');


// Test 1
if ($username != stripslashes (w_toalpha($username))) {
    w_exit('toalpha(): username invalid');
}

// Test 2
if ($bad = badChars(stripslashes ($username))) {
    w_exit('badChars(): username invalid -- '.make_list($bad, ', ', '"'));
}


w_exit('username &ldquo;'.w_html_chars($username).'&rdquo; passed!)');

?>

Offline

#5 10-15-2008 08:14:54

rainbow
Member

Re: Alphanumeric username issue.

First of all, I didn't know where I put the code...so I wound up putting it in the common.php file and I shouldn't do that.

Now, I set up the test file called test-alphanumeric.php and the result was this message:

Code:

toalpha(): username invalid

Now, I'm gonna try testing the registration system to see if non-alphanumeric characters return a error. I did a backup of the function.php and register.php files and named the as functions-backup.php and register-backup.php respectively incase these functions either do not work or return a parse error.

Edit: It seems that I'm stuck now. sad

Somehow, the <b>toalpha(): username invalid</b> error is occurring not just when I attempted to enter a username with illegal characters, such as "#my$name*is/terribly_invalid", but legit usernames that have alphanumeric characters as well. This is what I got in the functions.php file so far:

Code:

    // Init -- use addslashes() to simulate input from w_gpc()
    $username = addslashes ('#my$name*is/terribly_invalid');

    if ($username != stripslashes (w_toalpha($username))) {
          w_exit('toalpha(): username invalid');
    }

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        w_exit('badChars(): your username contains illegal characters: '.make_list($bad, ', ', '"'));
    }

I'm pretty lucky that I have backup copies of both files, just in case such functions are not working properly.

How can I make the $username variable to input only alphanumeric characters? instead of the "#my$name*is/terribly_invalid" username that always return a invalid username?


Edit: Wac, I think that I found a solution to the alphanumeric username/JavaScript issue:

Code:

<noscript>
    <meta http-equiv="refresh" content="0;url=javascript_disabled.php">
</noscript>

I had to create a javascript_disabled.php file to redirect users with JavaScript disabled or have a ad-blocker that interferes with the JavaScript functionality to redirect to that page instead of the registration page.

The noscript tag and redirection will somehow prevent database vomiting if some user attempt to enter non-alphanumeric characters that could cause the database to vomit. If the user has JavaScript enabled, it should automatically redirect to the front page where as if the user has JavaScript enabled, they will have to hit the Register URL link once again.

It might not be a permanent solution for Windows, Mac OS X and Linux users, but it should help solve the non-alphanumeric problem since it relies solely on JavaScript.

I'm gonna do some revision to the javascript_disabled.php file to include instructions on how to enable JavaScript on their browser. big_smile

Additionally, I will also place a warning on the front page where as if the user has JavaScript disabled, they must enable it before accessing some of the features on my oekaki site.

Last edited by rainbow (10-18-2008 17:37:45)

Offline

#6 10-19-2008 03:01:01

Waccoon
Administrator

Re: Alphanumeric username issue.

Edit: Wac, I think that I found a solution to the alphanumeric username/JavaScript issue:

This will not work.

You are not allowed to do that.  The "meta http-equiv" is a server-level tag (as it states, it is an "HTTP" equivalent header).  Only "meta name" is reliably visible to the browser.  Furthermore, the <noscript> tag cannot be used in certain contexts, and meta tags are one such invalid context.  Some browsers will allow it, but only if they disobey/ignore W3C recommendations.  Strict browsers will either be confused or will happily ignore the noscript tags in that context (at least, that's what they are supposed to do).

How can I make the $username variable to input only alphanumeric characters?

Technically, you should not convert anything directly into alphanumeric without the knowledge of the registrant.  You are supposed to provide information to the person submitting the registration, so he or she knows that such a name is not permitted.  You can use JavaScript to alert the person right away before they click the "Submit" button, but you cannot rely on JavaScript to actually perform the filtering.  That is a security threat.

JavaScript is a client-side technology.  Any filtering solution that uses JavaScript is not a solution.

If you want to really fix this, do the following:

1) Add this to common.php.  Do not change the name of the function:

Code:

function w_strict_alpha ($in) {
    return (preg_replace ("/[^a-zA-Z0-9]/", '', $in));
}

2) Look for this part of functions.php:

Code:

if ($action == 'register') {
    $username = w_gpc('username');
    $email    = w_gpc('email', 'email');
    $age      = decode_birthday($_POST['age_year'], $_POST['age_month'], $_POST['age_day']);
    $pass     = w_gpc('pass');
    $pass2    = w_gpc('pass2');
    $artURL   = w_gpc('artURL', 'url');
    $comment  = w_gpc('comments');

    if (empty ($username)) {
        all_done();
    }

    // Humanity test
    $x_test = w_gpc('x_test', 'i');
    $y_test = w_gpc('y_test', 'i');
    $e_test = w_gpc('e_test', 'i');
    if ($x_test + $y_test != $e_test || $e_test < 2) {
        w_exit('Humanity test failed.');
    }

    // Age verification?
    if ($cfg['op_adult'] == 'yes') {
        if (intval ($_POST['age_year']) < 1900 || intval ($_POST['age_year']) > 3000) {
            report_err('You must submit a valid age declaration (birth year).');
        }

        if (get_age($age) < MIN_AGE_ADULT) {
            report_err('Your age declaration could not be accepted.');
        }
    }

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        report_err('Your user name contains illegal characters: '.make_list($bad, ', ', '"'));
    }

Replace the last four lines (the badChars() code block) with this:

Code:

        CUT THIS:

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        report_err('Your user name contains illegal characters: '.make_list($bad, ', ', '"'));
    }

        REPLACE WITH THIS:

    if ($username != stripslashes (w_strict_alpha($username))) {
        report_err('Username must contain only letters and numbers');
    }

If you want to do some kind of JavaScript thing on the registration screen to prevent people from even entering non-alphanumeric characters, that's great.  It's better to prevent people from doing things wrong than to beat them over the head with an error message.  However, you cannot rely on JavaScript in any way or form as a replacement for server-side filtering.

Not to be terribly condescending, but I'd like to remind you that due to these types of modifications, your board went offline for weeks and you lost a lot of data.  You may want to ask yourself why you need to keep making these modifications in the first place.

Offline

#7 10-19-2008 06:09:57

rainbow
Member

Re: Alphanumeric username issue.

Waccoon wrote:

Edit: Wac, I think that I found a solution to the alphanumeric username/JavaScript issue:

This will not work.

You are not allowed to do that.  The "meta http-equiv" is a server-level tag (as it states, it is an "HTTP" equivalent header).  Only "meta name" is reliably visible to the browser.  Furthermore, the <noscript> tag cannot be used in certain contexts, and meta tags are one such invalid context.  Some browsers will allow it, but only if they disobey/ignore W3C recommendations.  Strict browsers will either be confused or will happily ignore the noscript tags in that context (at least, that's what they are supposed to do).

How can I make the $username variable to input only alphanumeric characters?

Technically, you should not convert anything directly into alphanumeric without the knowledge of the registrant.  You are supposed to provide information to the person submitting the registration, so he or she knows that such a name is not permitted.  You can use JavaScript to alert the person right away before they click the "Submit" button, but you cannot rely on JavaScript to actually perform the filtering.  That is a security threat.

I seriously didn't know that attempting to rely on JavaScript to filter out the vulnerability is seen as a security threat. I should be very careful of what I put into the code. Using the noscript tag didn't work. If I get done attempting to fix this vulnerability, I will at least use the noscript tag on the front page to alert the user that they don't have JavaScript enabled.

JavaScript is a client-side technology.  Any filtering solution that uses JavaScript is not a solution.

If you want to really fix this, do the following:

1) Add this to common.php.  Do not change the name of the function:

Code:

function w_strict_alpha ($in) {
    return (preg_replace ("/[^a-zA-Z0-9]/", '', $in));
}

2) Look for this part of functions.php:

Code:

if ($action == 'register') {
    $username = w_gpc('username');
    $email    = w_gpc('email', 'email');
    $age      = decode_birthday($_POST['age_year'], $_POST['age_month'], $_POST['age_day']);
    $pass     = w_gpc('pass');
    $pass2    = w_gpc('pass2');
    $artURL   = w_gpc('artURL', 'url');
    $comment  = w_gpc('comments');

    if (empty ($username)) {
        all_done();
    }

    // Humanity test
    $x_test = w_gpc('x_test', 'i');
    $y_test = w_gpc('y_test', 'i');
    $e_test = w_gpc('e_test', 'i');
    if ($x_test + $y_test != $e_test || $e_test < 2) {
        w_exit('Humanity test failed.');
    }

    // Age verification?
    if ($cfg['op_adult'] == 'yes') {
        if (intval ($_POST['age_year']) < 1900 || intval ($_POST['age_year']) > 3000) {
            report_err('You must submit a valid age declaration (birth year).');
        }

        if (get_age($age) < MIN_AGE_ADULT) {
            report_err('Your age declaration could not be accepted.');
        }
    }

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        report_err('Your user name contains illegal characters: '.make_list($bad, ', ', '"'));
    }

Replace the last four lines (the badChars() code block) with this:

Code:

        CUT THIS:

    // Prevent database from vomiting
    if ($bad = badChars(stripslashes ($username))) {
        report_err('Your user name contains illegal characters: '.make_list($bad, ', ', '"'));
    }

        REPLACE WITH THIS:

    if ($username != stripslashes (w_strict_alpha($username))) {
        report_err('Username must contain only letters and numbers');
    }

If you want to do some kind of JavaScript thing on the registration screen to prevent people from even entering non-alphanumeric characters, that's great.  It's better to prevent people from doing things wrong than to beat them over the head with an error message.  However, you cannot rely on JavaScript in any way or form as a replacement for server-side filtering.

That correct. Relying on JavaScript in anyway or form as a replacement for server-side filtering, is definitely not a way to go. Infact, attempting to rely on the w_strict_alpha function resulted in this fatal error message referencing to the common.php file when attempting to add or remove picture thumbnails or when attempting to login or out of my account:

Fatal error: Call to undefined function w_toalpha() in /home/rainbow/public_html/common.php on line 68

I managed to correct it by replacing the w_toa_alpha function with the w_strict_alpha function on lines 67 and 68 in the common.php file. But this is the result when I attempt to add or remove thumbnails:

Code:

No mode. Is a server filter being used?

When I looked at the URL address I found that the make_thumb mode has a underscore in it and when the oekaki attempts to perform functions when the underscores (_) are stripped out, the "No mode" error can occur like this.

Now, how can I prevent $action functions ("pass_reset", "mail_check_delete" "res_msg") and $mode functions (such as "make_thumb") mode from being affected by this restriction to disallow the usage of the underscore (_)  and other non-alphanumeric usernames?


Not to be terribly condescending, but I'd like to remind you that due to these types of modifications, your board went offline for weeks and you lost a lot of data.  You may want to ask yourself why you need to keep making these modifications in the first place.

Well...the database itself remained intact during the upgrade, but keep in mind that because of the changes to the way how the piccount and pic_id variables are being handled, the data and the pictures had to be wiped out. I'm trying to recover from all of this mess that I've gotten into over the past two months and at the rate that I'm going, I expect that it'll take several more months to get the oekaki filled up with pictures once again.

So, why have I been making modifications in the first place? While WaxPoteto and Wacintaki are based on the OekakiPoteto 5.x codebase, there were still some bugs that were need to be fixed up. Most of the bugs are easy enough to fix, but some of the them cannot be done without requiring technical support. A site owner like me attempting to further fix or even rewrite parts of the code where the bugs have been found can be time consuming.

It's been a rough two months trying to get my oekaki board back online and I'm almost done. I just need to do a logo for the front page of my oekaki and that's it. I probably might not do further work on my oekaki for a while. wink


Edit: By the way, on the bright side, attempting to enter non-alphanumeric characters with Javascript disabled returns a error...so it appears to be working now. smile

Last edited by rainbow (10-19-2008 06:30:08)

Offline

#8 10-20-2008 05:03:24

Waccoon
Administrator

Re: Alphanumeric username issue.

Now, how can I prevent $action functions ("pass_reset", "mail_check_delete" "res_msg") and $mode functions (such as "make_thumb") mode from being affected by this restriction to disallow the usage of the underscore (_)  and other non-alphanumeric usernames?

Go back to the original Wax Poteto "common.php" file and copy the "w_toalpha()" function to your modified "common.php" file.  That will fix the "no mode" problem.  Do not modify the "w_toalpha()" function in the future.

Now, use the "w_strict_alpha()" function I made for you to filter usernames.  If you want to customize a function, make a copy of it and leave the original alone.

While WaxPoteto and Wacintaki are based on the OekakiPoteto 5.x codebase, there were still some bugs that were need to be fixed up. Most of the bugs are easy enough to fix, but some of the them cannot be done without requiring technical support.

I understand there are still some odd problems here and there, but many of the things you're trying to fix are not bugs, but rather design limitations.  It's not a big deal, for example, if the online list fails to specify animated applets or not, or if the index page does not positively highlight administrators.  I tend to avoid fixing these limitations because there are often performance issues, bloat, or secondary effects to consider.  For example, I'm loath to make changes to the database to convert usernames to user IDs, because in-place database conversion is a very dangerous thing to do.  Things can easily get lost, especially since MySQL is infamous for corrupting data when you change too many things at once.  It's better to do a database export and then re-import all the data.  That's a lot of work for only a few features, and I think many people who use the oekaki would simply not bother updating to new versions if this were to happen.

The oekaki is long overdue for a rewrite, but I don't have much time to do that.  Sadly, there doesn't seem to be all that many people out there willing to work on new oekaki boards, either.

Offline

#9 10-20-2008 14:26:02

rainbow
Member

Re: Alphanumeric username issue.

Waccoon wrote:

Now, how can I prevent $action functions ("pass_reset", "mail_check_delete" "res_msg") and $mode functions (such as "make_thumb") mode from being affected by this restriction to disallow the usage of the underscore (_)  and other non-alphanumeric usernames?

Go back to the original Wax Poteto "common.php" file and copy the "w_toalpha()" function to your modified "common.php" file.  That will fix the "no mode" problem.  Do not modify the "w_toalpha()" function in the future.

Now, use the "w_strict_alpha()" function I made for you to filter usernames.  If you want to customize a function, make a copy of it and leave the original alone.

While WaxPoteto and Wacintaki are based on the OekakiPoteto 5.x codebase, there were still some bugs that were need to be fixed up. Most of the bugs are easy enough to fix, but some of the them cannot be done without requiring technical support.

I understand there are still some odd problems here and there, but many of the things you're trying to fix are not bugs, but rather design limitations.  It's not a big deal, for example, if the online list fails to specify animated applets or not, or if the index page does not positively highlight administrators.  I tend to avoid fixing these limitations because there are often performance issues, bloat, or secondary effects to consider.  For example, I'm loath to make changes to the database to convert usernames to user IDs, because in-place database conversion is a very dangerous thing to do.  Things can easily get lost, especially since MySQL is infamous for corrupting data when you change too many things at once.  It's better to do a database export and then re-import all the data.  That's a lot of work for only a few features, and I think many people who use the oekaki would simply not bother updating to new versions if this were to happen.

The oekaki is long overdue for a rewrite, but I don't have much time to do that.  Sadly, there doesn't seem to be all that many people out there willing to work on new oekaki boards, either.

That has gotta suck. Based on the fixes that you made as well as the fixes that I made to the files that makes the oekaki function, the oekaki product is long overdue for a complete rewrite. The last time the MySQL mishap and corruption occured on my oekaki was more than two years ago.

As a temporary measure I managed to fix it by removing the _ in the pass_reset, mail_check_delete, res_msg and make_thumb...thus it became "passreset", "mailcheckdelete", "resmsg" and "makethumb". The oekaki is working as it is now and I have backed up the files incase I need to change it back.

Speaking of that, where can I use the "w_strict_alpha()" function to filter usernames without having to interfere with the pass_reset, mail_check_delete, res_msg and make_thumb actions? I've noticed that you can only use it in the commons.php file and the registration part of the functions.php file, but that might not be the case.

I might want to do a backup of my modified files just incase I screw things up again.

Offline

#10 10-22-2008 06:02:35

Waccoon
Administrator

Re: Alphanumeric username issue.

As a temporary measure I managed to fix it by removing the _ in the pass_reset, mail_check_delete, res_msg and make_thumb...thus it became "passreset", "mailcheckdelete", "resmsg" and "makethumb". The oekaki is working as it is now and I have backed up the files incase I need to change it back.

I sure hope that's temporary, because there's more places in the code where the filtering system will cause problems.  LOTS more places.

You need to change the w_toalpha() function back to the way it was with the original Wax Poteto release.  Otherwise, you will continue to have problems.

Speaking of that, where can I use the "w_strict_alpha()" function to filter usernames without having to interfere with the pass_reset, mail_check_delete, res_msg and make_thumb actions?

See above.  It only needs to be used in one place, in the section that accepts registrations.

Offline

#11 10-22-2008 06:34:51

rainbow
Member

Re: Alphanumeric username issue.

Waccoon wrote:

As a temporary measure I managed to fix it by removing the _ in the pass_reset, mail_check_delete, res_msg and make_thumb...thus it became "passreset", "mailcheckdelete", "resmsg" and "makethumb". The oekaki is working as it is now and I have backed up the files incase I need to change it back.

I sure hope that's temporary, because there's more places in the code where the filtering system will cause problems.  LOTS more places.

Sadly, I have no intention to fool around with the common.php file anymore, because attempts to change it back to w_toalpha() only resulted in a fatal error referencing to common.php on line 67. So my final say is that I have resolved the "No mode" as the way it is when trying to log out by keeping it as w_strict_alpha in the commons.php file and in the functions.php file as well as removing the _ character in the mode functions.

However, be advised that in the near future that if people start complaining that some of the functions are not working after this change, I'll try to get things all sorted out. smile

Last edited by rainbow (10-23-2008 05:42:54)

Offline

Board footer

Yep, still running PunBB
© Copyright 2002–2008 PunBB