- Examples
- Only allow login during office hours
- Only allow upload of specific file types
- Only allow SAP users to download SAP-documents
- Extreme login security using SMS audit (2FA / MFA - Multi Factor Authentication)
- Changing destination location on file upload
- Getting additional information from users using form input
- Control file types with PHP
The Proactive features essentially lets the server react to events before they happen.
Following a request to e.g. login or upload a file the server can for instance verify login or upload operations against external databases or check whether the user is permitted to upload a file of that specific type. We can for instance enforce that a specific user only be able to upload .doc-files.
In combination with the Reactive module we can script more advanced business applications rules verifying a user login against a SAP database and subsequently when the user is allowed to login, run scripts that execute financial reporting in SAP, directly posted and available to the specific user on the fly (reports are then automatically removed after logout).
Examples #
Only allow login during office hours #
Event in ProVide:
BeforeConnect
Script in ProVide:
C:\Scripts\OfficeHours.cmd
Error message in ProVide:
You're not allowed to login outside office hours.
Contents of file “C:\Scripts\OfficeHours.cmd”:
@echo off rem Extract current hour for /f "tokens=1-2 delims=: " %%a in ('time/t') do ( set hour=%%a set minute=%%b ) rem Deny access outside office hours if /I %hour% LSS 8 exit 1 if /I %hour% GEQ 18 exit 1
Only allow upload of specific file types #
Event in ProVide:
BeforeUpload
Script in ProVide:
C:\Scripts\CheckFileType.cmd "%LOCAL_FILENAME%"
Error message in ProVide:
Access denied
Contents of file “C:\Scripts\CheckFileType.cmd”:
@echo off rem Extract file information and remove quotes set FILE=%1 for /f "useback tokens=*" %%a in ('%FILE%') do set FILE=%%~a rem Only allow uploading of certain file extensions if /I "%FILE:~-4%" == ".jpg" exit 0 if /I "%FILE:~-4%" == ".gif" exit 0 if /I "%FILE:~-4%" == ".tif" exit 0 if /I "%FILE:~-4%" == ".pdf" exit 0 if /I "%FILE:~-4%" == ".php" exit 0 if /I "%FILE:~-4%" == ".css" exit 0 rem Nothing else is allowed exit 1
Only allow SAP users to download SAP-documents #
Event in ProVide:
BeforeDownload
Script in ProVide:
C:\Scripts\BusinessUser.cmd %USERNAME% "%LOCAL_FILENAME%"
Error message in ProVide:
Access denied
Contents of file “C:\Scripts\BusinessUser.cmd”:
@echo off rem Extract file information and remove quotes set FILE=%2 for /f "useback tokens=*" %%a in ('%FILE%') do set FILE=%%~a rem Allow access if not SAP document if /I not "%FILE:~0,17%" == "C:\SAP Documents\" exit 0 rem Search for current user in the SAP database, we can ignore SQL injections since the user has logged in correctly osql -d <database> -U <user> -P <pass> -Q "select 'ACCESS OK' from OUSR where USER_CODE='%1'" | find "ACCESS OK" >NUL rem Deny access if user not in SAP database if ERRORLEVEL 1 exit 1 rem All is OK exit 0
Extreme login security using SMS audit (2FA / MFA – Multi Factor Authentication) #
Event in ProVide:
BeforeLoggedIn
Script in ProVide:
C:\Scripts\SMSAudit.cmd %USERNAME% %IP%
Error message in ProVide:
Access denied
Contents of file “C:\Scripts\SMSAudit.cmd”:
@echo off rem Setup variables set USER=<sms username> set PASS=<sms password> rem Url-encode question to be sent "Allow user to login: %1 (%2)?" set TEXT=Allow%%20user%%20to%%20login%%3A%%20%1%%20%%28%2%%29%%3F set TO=555123456 set FROM=ProVideAudit set PARAMS=acc=%USER%^^^&pass=%PASS%^^^&msg=%TEXT%^^^&to=%TO%^^^&from=%FROM%^^^&prio=3 rem Send question to administrator wget --delete-after http://smsgateway/send.php?%PARAMS% >NUL rem Wait for answer via SMS or timeout after two minutes WaitForSMSOrTimeout.exe --timeout 120 rem Only allow login if no error level reported if ERRORLEVEL 1 exit 1 rem All is OK, go ahead with login exit 0
Changing destination location on file upload #
Event in ProVide:
BeforeUpload
Script in ProVide:
"C:\cygwin64\bin\perl.exe" "C:\Scripts\beforeUpload.pl" "%LOCAL_FILENAME%"
Error message in ProVide:
Access denied
Contents of file “C:\Scripts\beforeUpload.pl”:
use LWP::Simple; use File::Basename; $source = "/cygdrive/e/DATA/"; $target = "/cygdrive/e/SomePublicFolder/"; ($file) = @ARGV; if (defined $file) { $file =~ tr/"//d; ($filename, $path, $suffix) = fileparse($file, qr/\.[^.]*/); if ($path eq "./" && index($filename, ':\\') != -1) { $file =~ s/\\/\//g; $file =~ s/(.+?):\//\/cygdrive\/$1\//ig; ($filename, $path, $suffix) = fileparse($file, qr/\.[^.]*/); if (index(lc $path, lc $target) == 0) { my $counter = 0; do { $counter++; $file = "$source$filename-$counter$suffix"; } while (-e $file); $file =~ s/\/cygdrive\/(.?)\//$1:\//ig; $file =~ s/\//\\/g; utf8::decode($file); print "$file\n"; exit 2; } } }
Returning code 2 tells ProVide to use the returned destination path/filename instead… making sure no files are overwritten.
Getting additional information from users using form input #
This example shows how to request additional information when uploading files using receive links. This particular example requests the user to enter the correct code in all input boxes for the upload to be accepted.
Event in ProVide:
BeforeUpload
Script in ProVide:
"C:\Scripts\beforeUpload.cmd" "%LINK_TYPE%" "%FORM%"
Error message in ProVide:
Access denied
Contents of file “C:\Scripts\beforeUpload.cmd”:
@if (@CodeSection == @Batch) @then @echo off rem Only check uploads comming in through a receive link if NOT (%1) == ("ltReceive") exit /B 0 rem Convert URI code to string for /f "delims=" %%a in ('cscript /nologo /e:JScript "%~f0" %2') do set FORM=%%a rem Only allow if correct answers has been entered if ("%FORM%") == ("-1") exit /B 0 rem Otherwise we deny this upload exit /B 1 @end // JavaScript for easy URI conversion WSH.Echo(decodeURIComponent(WSH.Arguments(0)) == "foo=0&bar=xx&this=ho");
Override default receive text to display:
Enter <b>secret code</b> to upload files...<br> <form> <input type="radio" name="foo" value="1" checked="checked" /> <input type="radio" name="foo" value="0" /> <input name="bar" value="xxx" /> <select name="this"> <option value="hi" selected="selected">Hi</option> <option value="ho">Ho</option> </select> </form>
Control file types with PHP #
This example shows how to restrict which file types users are allowed to work with by using php scripts. Descriptions for configuring each script is in the code comments.
PHP-Script “BeforeUpload.php”:
<?PHP /** * @author Photonensammler */ //pass the username, and the extension of the file to upload //check whether the upload of this filetype is allowed for user //be passed as first Parameter the user name and as the 2nd Parameter the filename //Usage example BeforeUpload.php Username Filename /* command line in ProVide event "BeforeUpload" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeUpload.php" "%USERNAME%" "%LOCAL_FILENAME%" */ /* for the user is evaluated the allowed file extension if the extension is listed in the array, for the user the upload of this filetype is allowed for users with the extension '*' is the upload of arbitrary files allowed */ $allow['User_1'] = array('txt'); //rights for user_1 $allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2 $allow['User_x'] = array('*'); //all rights for User_x $allow['Administrator'] = array('*'); //all rights for Administrator if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) { $user = $_SERVER['argv'][1]; //username if (isset($allow[$user])) {//test whether user exists if ($allow[$user][0] == '*') { die(0); //everything is allowed, exit with errorlevel 0 } else { $ext = preg_split('/\./', $_SERVER['argv'][2]); if (count($ext) == 1) { $ext[1] = ''; //for files without extension } $ext = strtolower($ext[count($ext) - 1]); foreach ($allow[$user] as $test_ext) { if (strtolower($test_ext) == $ext) { die(0); //is allowed for this user, terminate with errorlevel 0 } } } } } die(1); //not allowed ?>
PHP-Script “BeforeRename.php”:
<?PHP /** * @author Photonensammler */ //pass the username, and the extension of the old filename and the new filename to rename //check whether the rename of this filetype is allowed for user //be passed as first Parameter the user name, as the 2nd Parameter the old filename and as the 3td parameter the new filename //Usage example BeforeRename.php Username Filenameold Filenamenew /* command line in ProVide event "BeforeRename" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeRename.php" "%USERNAME%" "%LOCAL_FILENAME%" "%LOCAL_FILENAME_NEW%" */ /* for the user is evaluated the allowed file extension if the extension is listed in the array, for the user the rename of this filetype is allowed for users with the extension '*' is the rename of arbitrary files allowed */ $allow['User_1'] = array('txt'); //rights for user_1 $allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2 $allow['User_x'] = array('*'); //all rights for User_x $allow['Administrator'] = array('*'); //all rights for Administrator if (isset($_SERVER['argc']) && $_SERVER['argc'] > 3) { $user = $_SERVER['argv'][1]; //username if (isset($allow[$user])) {//test whether user exists if ($allow[$user][0] == '*') { die(0); //everything is allowed, exit with errorlevel 0 } else { $ext_old = preg_split('/\./', $_SERVER['argv'][2]); if (count($ext_old) == 1) { $ext_old[1] = ''; //for files without extension } $ext_new = preg_split('/\./', $_SERVER['argv'][3]); if (count($ext_new) == 1) { $ext_new[1] = ''; //for files without extension } $ext_old = strtolower($ext_old[count($ext_old) - 1]); $ext_new = strtolower($ext_new[count($ext_new) - 1]); foreach ($allow[$user] as $test_ext) { if (strtolower($test_ext) == $ext_old) { foreach ($allow[$user] as $test_ext) { if (strtolower($test_ext) == $ext_new) { die(0); //is allowed for this user, terminate with errorlevel 0 } } die(1); //not allowed } } } } } die(1); //not allowed ?>
PHP-Script “BeforeRemoveFile.php”:
<?PHP /** * @author Photonensammler */ //pass the username, and the extension of the file to delete //check whether the deleting of this filetype is allowed for user //be passed as first Parameter the user name and as the 2nd Parameter the filename //Usage example BeforeRemoveFile.php Username Filename /* command line in ProVide event "BeforeRemoveFile" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeRemoveFile.php" "%USERNAME%" "%LOCAL_FILENAME%" */ /* for the user is evaluated the allowed file extension if the extension is listed in the array, for the user the deleting of this filetype is allowed for users with the extension '*' is the deleting of arbitrary files allowed */ $allow['User_1'] = array('txt'); //rights for user_1 $allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2 $allow['User_x'] = array('*'); //all rights for User_x $allow['Administrator'] = array('*'); //all rights for Administrator if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) { $user = $_SERVER['argv'][1]; //username if (isset($allow[$user])) {//test whether user exists if ($allow[$user][0] == '*') { die(0); //everything is allowed, exit with errorlevel 0 } else { $ext = preg_split('/\./', $_SERVER['argv'][2]); if (count($ext) == 1) { $ext[1] = ''; //for files without extension } $ext = strtolower($ext[count($ext) - 1]); foreach ($allow[$user] as $test_ext) { if (strtolower($test_ext) == $ext) { die(0); //is allowed for this user, terminate with errorlevel 0 } } } } } die(1); //not allowed ?>
PHP-Script “BeforeDownload.php”:
<?PHP /** * @author Photonensammler */ //pass the username, and the extension of the file to download //check whether the download of this filetype is allowed for user //be passed as first Parameter the user name and as the 2nd Parameter the filename //Usage example BeforeDownload.php Username Filename /* command line in ProVide event "BeforeDownload" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeDownload.php" "%USERNAME%" "%LOCAL_FILENAME%" */ /* for the user is evaluated the allowed file extension if the extension is listed in the array, for the user the download of this filetype is allowed for users with the extension '*' is the download of arbitrary files allowed */ $allow['User_1'] = array('txt'); //rights for user_1 $allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2 $allow['User_x'] = array('*'); //all rights for User_x $allow['Administrator'] = array('*'); //all rights for Administrator if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) { $user = $_SERVER['argv'][1]; //username if (isset($allow[$user])) {//test whether user exists if ($allow[$user][0] == '*') { die(0); //everything is allowed, exit with errorlevel 0 } else { $ext = preg_split('/\./', $_SERVER['argv'][2]); if (count($ext) == 1) { $ext[1] = ''; //for files without extension } $ext = strtolower($ext[count($ext) - 1]); foreach ($allow[$user] as $test_ext) { if (strtolower($test_ext) == $ext) { die(0); //is allowed for this user, terminate with errorlevel 0 } } } } } die(1); //not allowed ?>
PHP-Script “BeforeCreateDirectory.php”:
<?PHP /** * @author Photonensammler */ //pass the username, check whether the creation of Directorys is allowed for this user /* command line in ProVide event "BeforeCreateDirectory" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeCreateDirectory.php" "%USERNAME%" */ /* for the user is only evaluated '*', for users with '*' is the creation of Directorys allowed users without '*' dont have authorization to create Directorys */ $allow['User_1'] = ''; //no rights for user_1 $allow['User_2'] = ''; //no rights for User_2 $allow['User_x'] = '*'; //all rights for User_x $allow['Administrator'] = '*'; //all rights for Administrator //this is the compact code die(isset($_SERVER['argc']) ? (isset($allow[$_SERVER['argv'][1]]) ? ($allow[$_SERVER['argv'][1]] == '*' ? 0 : 1) : 1) : 1); /* This is the clear code if(!isset($_SERVER['argc'])){ die(1); //errorlevel 1 -> called without parameters } $user=$_SERVER['argv'][1]; //username if(!isset($allow[$user])){//test whether user exists die(1); //no user }else{ if($allow[$user]=='*'){ die(0); //is allowed to exit with errorlevel 0 } } die(1); //not allowed */ ?>
PHP-Script “BeforeRemoveDirectory.php”:
<?PHP /** * @author Photonensammler */ //pass the username, check whether the deletion of Directorys is allowed for this user /* command line in ProVide event "BeforeRemoveDirectorys" "C:/PHP/php-win.exe" "C:/Program Files/ProVide/Scripts/BeforeRemoveDirectory.php" "%USERNAME%" */ /* for the user is only evaluated '*', for users with '*' is the deletion of Directorys allowed users without '*' dont have authorization to delete Directorys */ $allow['User_1'] = ''; //no rights for user_1 $allow['User_2'] = ''; //no rights for User_2 $allow['User_x'] = '*'; //all rights for User_x $allow['Administrator'] = '*'; //all rights for Administrator //this is the compact code die(isset($_SERVER['argc']) ? (isset($allow[$_SERVER['argv'][1]]) ? ($allow[$_SERVER['argv'][1]] == '*' ? 0 : 1) : 1) : 1); /* This is the clear code if(!isset($_SERVER['argc'])){ die(1); //errorlevel 1 -> called without parameters } $user=$_SERVER['argv'][1]; //username if(!isset($allow[$user])){//test whether user exists die(1); //no user }else{ if($allow[$user]=='*'){ die(0); //is allowed to exit with errorlevel 0 } } die(1); //not allowed */ ?>