From 0d9a9de558fa80166f2915821cbfd11fc96c8036 Mon Sep 17 00:00:00 2001 From: Daniel Winzen Date: Fri, 12 Aug 2016 13:28:54 +0200 Subject: [PATCH] Allow configuring password and nickname regex --- CHANGELOG | 1 + chat.php | 54 +++++++++++++++++++++++++++++++++++--------------- lang_de.php | 14 ++++++++----- lang_en.php | 10 +++++++--- lang_es_AR.php | 2 -- lang_es_ES.php | 2 -- lang_fr.php | 2 -- lang_id.php | 2 -- lang_ru.php | 2 -- 9 files changed, 55 insertions(+), 34 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4d52b62..f749160 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ Allow ignoring incognito chatters Prevent posting the same message twice, if no other message was posted in-between Instruct browser not to send referrer. Enable image embedding without cookies as there is no more risk of session leakage. +Allow configuring password and nickname regex Version 1.20.6 - Jul. 23, 2016 Simplify ignore logic + disallow ignoring chatters with higher status diff --git a/chat.php b/chat.php index fc12477..e9af79b 100644 --- a/chat.php +++ b/chat.php @@ -74,7 +74,7 @@ function route(){ send_waiting_room(); }elseif($_REQUEST['action']==='post'){ check_session(); - if(isSet($_REQUEST['kick']) && isSet($_REQUEST['sendto']) && valid_nick($_REQUEST['sendto'])){ + if(isSet($_REQUEST['kick']) && isSet($_REQUEST['sendto']) && $_REQUEST['sendto']!=='&'){ if($U['status']>=5 || ($U['status']>=3 && $countmods===0 && get_setting('memkick'))){ if(isSet($_REQUEST['what']) && $_REQUEST['what']==='purge'){ kick_chatter(array($_REQUEST['sendto']), $_REQUEST['message'], true); @@ -234,7 +234,7 @@ function route_setup(){ $C['msg_settings']=array('msgenter', 'msgexit', 'msgmemreg', 'msgsureg', 'msgkick', 'msgmultikick', 'msgallkick', 'msgclean', 'msgsendall', 'msgsendmem', 'msgsendmod', 'msgsendadm', 'msgsendprv'); $C['number_settings']=array('memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes'); $C['textarea_settings']=array('rulestxt', 'css', 'disabletext'); - $C['text_settings']=array('dateformat', 'captchachars', 'redirect', 'chatname', 'mailsender', 'mailreceiver'); + $C['text_settings']=array('dateformat', 'captchachars', 'redirect', 'chatname', 'mailsender', 'mailreceiver', 'nickregex', 'passregex'); $C['settings']=array_merge(array('guestaccess', 'englobalpass', 'globalpass', 'captcha', 'dismemcaptcha', 'topic', 'guestreg', 'defaulttz'), $C['bool_settings'], $C['colour_settings'], $C['msg_settings'], $C['number_settings'], $C['textarea_settings'], $C['text_settings']); // All settings in the database if(!isSet($_REQUEST['do'])){ }elseif($_REQUEST['do']==='save'){ @@ -1082,8 +1082,7 @@ function check_filter_match(&$reg){ global $I; $_REQUEST['match']=htmlspecialchars($_REQUEST['match']); if(isSet($_REQUEST['regex']) && $_REQUEST['regex']==1){ - $_REQUEST['match']=preg_replace('~(^|[^\\\\])/~', "$1\/", $_REQUEST['match']); // Escape "/" if not yet escaped - if(@preg_match("/$_REQUEST[match]/", '')===false){ + if(!valid_regex($_REQUEST['match'])){ return "$I[incorregex]
$I[prevmatch]: $_REQUEST[match]"; } $reg=1; @@ -2042,10 +2041,10 @@ function create_session($setup){ if($U['status']==1){ $ga=(int) get_setting('guestaccess'); if(!valid_nick($U['nickname'])){ - send_error(sprintf($I['invalnick'], get_setting('maxname'))); + send_error(sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex'))); } if(!valid_pass($_REQUEST['pass'])){ - send_error(sprintf($I['invalpass'], get_setting('minpass'))); + send_error(sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex'))); } if($ga===0){ send_error($I['noguests']); @@ -2422,9 +2421,9 @@ function register_new($nick, $pass){ }elseif(isSet($P[$nick])){ return sprintf($I['cantreg'], $nick); }elseif(!valid_nick($nick)){ - return sprintf($I['invalnick'], get_setting('maxname')); + return sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex')); }elseif(!valid_pass($pass)){ - return sprintf($I['invalpass'], get_setting('minpass')); + return sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex')); } read_members(); if(isSet($A[$nick])){ @@ -2605,7 +2604,7 @@ function save_profile(){ } if($U['status']>1 && !empty($_REQUEST['newpass'])){ if(!valid_pass($_REQUEST['newpass'])){ - return sprintf($I['invalpass'], get_setting('minpass')); + return sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex')); } if(!isSet($_REQUEST['oldpass'])){ $_REQUEST['oldpass']=''; @@ -2640,7 +2639,7 @@ function save_profile(){ function set_new_nickname(){ global $I, $U, $db; if(!valid_nick($_REQUEST['newnickname'])){ - return sprintf($I['invalnick'], get_setting('maxname')); + return sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex')); } $U['passhash']=md5(sha1(md5($_REQUEST['newnickname'].$_REQUEST['newpass']))); $stmt=$db->prepare('SELECT id FROM ' . PREFIX . 'sessions WHERE nickname=? UNION SELECT id FROM ' . PREFIX . 'members WHERE nickname=?;'); @@ -3099,6 +3098,7 @@ function send_headers(){ function save_setup(){ global $C, $db; + //sanity checks and escaping foreach($C['msg_settings'] as $setting){ $_REQUEST[$setting]=htmlspecialchars($_REQUEST[$setting]); } @@ -3153,6 +3153,13 @@ function save_setup(){ if($_REQUEST['numnotes']<1){ $_REQUEST['numnotes']=1; } + if(!valid_regex($_REQUEST['nickregex'])){ + unset($_REQUEST['nickregex']); + } + if(!valid_regex($_REQUEST['passregex'])){ + unset($_REQUEST['passregex']); + } + //save values foreach($C['settings'] as $setting){ if(isSet($_REQUEST[$setting])){ update_setting($setting, $_REQUEST[$setting]); @@ -3177,11 +3184,23 @@ function valid_admin(){ } function valid_nick($nick){ - return preg_match('/^[a-z0-9]{1,'.get_setting('maxname').'}$/i', $nick); + $len=strlen($nick); + if($len<1 || $len>get_setting('maxname')){ + return false; + } + return preg_match('/'.get_setting('nickregex').'/', $nick); } function valid_pass($pass){ - return preg_match('/^.{'.get_setting('minpass').',}$/', $pass); + if(strlen($pass)exec('CREATE INDEX ' . PREFIX . 'incognito ON ' . PREFIX . 'sessions(incognito);'); $db->exec('CREATE TABLE ' . PREFIX . "settings (setting varchar(50) NOT NULL PRIMARY KEY, value varchar(20000) NOT NULL);"); } - $settings=array(array('guestaccess', '0'), array('globalpass', ''), array('englobalpass', '0'), array('captcha', '0'), array('dateformat', 'm-d H:i:s'), array('rulestxt', ''), array('msgencrypted', '0'), array('dbversion', DBVERSION), array('css', 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} input,select,textarea{color:#FFFFFF;background-color:#000000;} a img{width:15%} a:hover img{width:35%} .error{color:#FF0033;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} .center-table{margin-left:auto;margin-right:auto;} body{text-align:center;} .left-table{width:100%;text-align:left;} .right{text-align:right;} .left{text-align:left;} .right-table{border-spacing:0px;margin-left:auto;} .padded{padding:5px;} #chatters{max-height:100px;overflow-y:auto;} .center{text-align:center;}'), array('memberexpire', '60'), array('guestexpire', '15'), array('kickpenalty', '10'), array('entrywait', '120'), array('messageexpire', '14400'), array('messagelimit', '150'), array('maxmessage', 2000), array('captchatime', '600'), array('colbg', '000000'), array('coltxt', 'FFFFFF'), array('maxname', '20'), array('minpass', '5'), array('defaultrefresh', '20'), array('dismemcaptcha', '0'), array('suguests', '0'), array('imgembed', '1'), array('timestamps', '1'), array('trackip', '0'), array('captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), array('memkick', '1'), array('forceredirect', '0'), array('redirect', ''), array('incognito', '1'), array('chatname', 'My Chat'), array('topic', ''), array('msgsendall', $I['sendallmsg']), array('msgsendmem', $I['sendmemmsg']), array('msgsendmod', $I['sendmodmsg']), array('msgsendadm', $I['sendadmmsg']), array('msgsendprv', $I['sendprvmsg']), array('msgenter', $I['entermsg']), array('msgexit', $I['exitmsg']), array('msgmemreg', $I['memregmsg']), array('msgsureg', $I['suregmsg']), array('msgkick', $I['kickmsg']), array('msgmultikick', $I['multikickmsg']), array('msgallkick', $I['allkickmsg']), array('msgclean', $I['cleanmsg']), array('numnotes', '3'), array('mailsender', 'www-data '), array('mailreceiver', 'Webmaster '), array('sendmail', '0'), array('modfallback', '1'), array('guestreg', '0'), array('disablepm', '0'), array('disabletext', "

$I[disabledtext]

"), array('defaulttz', '0'), array('eninbox', '0')); + $settings=array(array('guestaccess', '0'), array('globalpass', ''), array('englobalpass', '0'), array('captcha', '0'), array('dateformat', 'm-d H:i:s'), array('rulestxt', ''), array('msgencrypted', '0'), array('dbversion', DBVERSION), array('css', 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} input,select,textarea{color:#FFFFFF;background-color:#000000;} a img{width:15%} a:hover img{width:35%} .error{color:#FF0033;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} .center-table{margin-left:auto;margin-right:auto;} body{text-align:center;} .left-table{width:100%;text-align:left;} .right{text-align:right;} .left{text-align:left;} .right-table{border-spacing:0px;margin-left:auto;} .padded{padding:5px;} #chatters{max-height:100px;overflow-y:auto;} .center{text-align:center;}'), array('memberexpire', '60'), array('guestexpire', '15'), array('kickpenalty', '10'), array('entrywait', '120'), array('messageexpire', '14400'), array('messagelimit', '150'), array('maxmessage', 2000), array('captchatime', '600'), array('colbg', '000000'), array('coltxt', 'FFFFFF'), array('maxname', '20'), array('minpass', '5'), array('defaultrefresh', '20'), array('dismemcaptcha', '0'), array('suguests', '0'), array('imgembed', '1'), array('timestamps', '1'), array('trackip', '0'), array('captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), array('memkick', '1'), array('forceredirect', '0'), array('redirect', ''), array('incognito', '1'), array('chatname', 'My Chat'), array('topic', ''), array('msgsendall', $I['sendallmsg']), array('msgsendmem', $I['sendmemmsg']), array('msgsendmod', $I['sendmodmsg']), array('msgsendadm', $I['sendadmmsg']), array('msgsendprv', $I['sendprvmsg']), array('msgenter', $I['entermsg']), array('msgexit', $I['exitmsg']), array('msgmemreg', $I['memregmsg']), array('msgsureg', $I['suregmsg']), array('msgkick', $I['kickmsg']), array('msgmultikick', $I['multikickmsg']), array('msgallkick', $I['allkickmsg']), array('msgclean', $I['cleanmsg']), array('numnotes', '3'), array('mailsender', 'www-data '), array('mailreceiver', 'Webmaster '), array('sendmail', '0'), array('modfallback', '1'), array('guestreg', '0'), array('disablepm', '0'), array('disabletext', "

$I[disabledtext]

"), array('defaulttz', '0'), array('eninbox', '0'), array('passregex', '.*'), array('nickregex', '^[A-Za-z0-9]*$')); $stmt=$db->prepare('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (?, ?);'); foreach($settings as $pair){ $stmt->execute($pair); @@ -3524,6 +3543,9 @@ function update_db(){ if($dbversion<25){ $db->exec('DELETE FROM ' . PREFIX . "settings WHERE setting='keeplimit';"); } + if($dbversion<26){ + $db->exec('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (\'passregex\', \'.*\'), (\'nickregex\', \'^[A-Za-z0-9]*$\');'); + } update_setting('dbversion', DBVERSION); if(get_setting('msgencrypted')!=MSGENCRYPTED){ if(!extension_loaded('openssl')){ @@ -3713,7 +3735,7 @@ function load_lang(){ function load_config(){ date_default_timezone_set('UTC'); define('VERSION', '1.20.6'); // Script version - define('DBVERSION', 25); // Database version + define('DBVERSION', 26); // Database version define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing! define('ENCRYPTKEY', 'MY_KEY'); // Encryption key for messages define('DBHOST', 'localhost'); // Database host diff --git a/lang_de.php b/lang_de.php index c0f50d8..8c3c270 100644 --- a/lang_de.php +++ b/lang_de.php @@ -25,9 +25,9 @@ $T=array( 'changelang' => 'Sprache ändern:', 'expire' => 'Ungültige/abgelaufene Sitzung', 'kicked' => 'Rausgeschmissen!', - 'invalnick' => 'Ungültiger Nickname (Maximal %d Zeichen, keine Sonderzeichen erlaubt)', - 'invalpass' => 'Ungültiges Passwort (Mindestens %d Zeichen)', - 'noconfirm' => 'Passwordbestätigung stimmt nicht überein!', + 'invalnick' => 'Ungültiger Nickname (Maximal %1$d Zeichen und muss dem regulären Ausdruck "%2$s" entsprechen)', + 'invalpass' => 'Ungültiges Passwort (Mindestens %1$d Zeichen und muss dem regulären Ausdruck "%2$s" entsprechen)', + 'noconfirm' => 'Passwortbestätigung stimmt nicht überein!', 'incorregex' => 'Ungültiger regulärer Ausdruck!', 'bottom' => 'Unten', 'top' => 'Oben', @@ -282,7 +282,7 @@ $T=array( 'topic' => 'Thema', 'passreset' => 'Passwort zurücksetzen', 'cantresetpass' => 'Passwort kann nicht zurückgesetzt werden', - 'succpassreset' => 'Password erfolgreich zurückgesetzt', + 'succpassreset' => 'Passwort erfolgreich zurückgesetzt', 'entermsg' => '%s hat den Chat betreten.', 'exitmsg' => '%s hat den Chat verlassen.', 'memregmsg' => '%s ist jetzt ein registriertes Mitglied.', @@ -342,8 +342,12 @@ $T=array( 'inboxmsgs' => '%d Nachrichten im Posteingang lesen', 'offline' => '(offline)', 'deleteacc' => 'Konto löschen', + 'eninnone' => 'Für niemanden', 'eninall' => 'Für jeden', 'eninmem' => 'Nur für Mitglieder', - 'eninstaff' => 'Nur für Moderatoren' + 'eninstaff' => 'Nur für Moderatoren', + 'eninadmin' => 'Nur für Administratoren', + 'nickregex' => 'Nickname-Regex', + 'passregex' => 'Passwort-Regex', ); ?> diff --git a/lang_en.php b/lang_en.php index 6d4a97c..6023a87 100644 --- a/lang_en.php +++ b/lang_en.php @@ -25,8 +25,8 @@ $I=array( 'changelang' => 'Change language:', 'expire' => 'Invalid/expired session', 'kicked' => 'Kicked!', - 'invalnick' => 'Invalid nickname (%d characters maximum, no special characters allowed)', - 'invalpass' => 'Invalid password (At least %d characters)', + 'invalnick' => 'Invalid nickname (%1$d characters maximum and has to match the regular expression "%2$s")', + 'invalpass' => 'Invalid password (At least %1$d characters and has to match the regular expression "%2$s")', 'noconfirm' => 'Password confirmation does not match!', 'incorregex' => 'Incorrect regular expression!', 'bottom' => 'Bottom', @@ -342,8 +342,12 @@ $I=array( 'inboxmsgs' => 'Read %d messages in your inbox', 'offline' => '(offline)', 'deleteacc' => 'Delete account', + 'eninnone' => 'For no one', 'eninall' => 'For everyone', 'eninmem' => 'For members only', - 'eninstaff' => 'For staff only' + 'eninstaff' => 'For staff only', + 'eninadmin' => 'For admins only', + 'nickregex' => 'Nickname regex', + 'passregex' => 'Password regex', ); ?> diff --git a/lang_es_AR.php b/lang_es_AR.php index 71fd04b..f2c407c 100644 --- a/lang_es_AR.php +++ b/lang_es_AR.php @@ -25,8 +25,6 @@ $T=array( 'changelang' => 'Cambiar idioma:', 'expire' => 'La sesión es inválida o expiró', 'kicked' => '¡Te expulsaron!', - 'invalnick' => 'Apodo incorrecto (%d caracteres como máximo, no se permiten caracteres especiales)', - 'invalpass' => 'Contraseña inválida (como mínimo %d caracteres)', 'noconfirm' => '¡La contraseña y su confirmación no coinciden!', 'incorregex' => '¡Expresión regular incorrecta!', 'bottom' => 'Inicio', diff --git a/lang_es_ES.php b/lang_es_ES.php index 1dc5964..86978c6 100644 --- a/lang_es_ES.php +++ b/lang_es_ES.php @@ -25,8 +25,6 @@ $T=array( 'changelang' => 'Cambiar idioma:', 'expire' => 'La sesión es inválida o expiró', 'kicked' => '¡Te expulsaron!', - 'invalnick' => 'Apodo incorrecto (%d caracteres como máximo, no se permiten caracteres especiales)', - 'invalpass' => 'Contraseña inválida (como mínimo %d caracteres)', 'noconfirm' => '¡La contraseña y su confirmación no coinciden!', 'incorregex' => '¡Expresión regular incorrecta!', 'bottom' => 'Inicio', diff --git a/lang_fr.php b/lang_fr.php index c12c900..8d0b178 100644 --- a/lang_fr.php +++ b/lang_fr.php @@ -25,8 +25,6 @@ $T=array( 'changelang' => 'Changer la langue:', 'expire' => 'Session invalide / expirée', 'kicked' => 'Banni / éjecté!', - 'invalnick' => 'pseudo valide (% de caractères maximum, pas de caractères spéciaux autorisés)', - 'invalpass' => 'mot de passe invalide (au moins % caractères)', 'noconfirm' => 'Confirmation mot du passe ne correspond pas! ', 'incorregex' => 'Expression régulière incorrecte!', 'bottom' => 'Bas', diff --git a/lang_id.php b/lang_id.php index a969a06..8a1738e 100644 --- a/lang_id.php +++ b/lang_id.php @@ -25,8 +25,6 @@ $T=array( 'changelang' => 'Ubah bahasa:', 'expire' => 'Sesi salah/kadaluarsa', 'kicked' => 'Diusir!', - 'invalnick' => 'Nama pengguna salah (maksimal %d karakter, karakter spesial tak diizinkan)', - 'invalpass' => 'Kata sandi salah (minimal %d karakter)', 'noconfirm' => 'Konfirmasi kata sandi tidak cocok!', 'incorregex' => 'Regular expression salah!', 'bottom' => 'Bawah', diff --git a/lang_ru.php b/lang_ru.php index be73a37..8bb648d 100644 --- a/lang_ru.php +++ b/lang_ru.php @@ -25,8 +25,6 @@ $T=array( 'changelang' => 'Изменить язык:', 'expire' => 'Недействительная/с истекшим сроком сессия', 'kicked' => 'Забанен!', - 'invalnick' => 'Недействительный ник (%d символов максимум, никакие специальные разрешенные символы)', - 'invalpass' => 'Неверный пароль (по крайней мере %d символов)', 'noconfirm' => 'Подтверждение пароля не совпадает!', 'incorregex' => 'Неправильное регулярное выражение!', 'bottom' => 'Вниз',