Add languages to PHP Docker Container

Recently I have noticed that the output of the following code shows the month in the wrong language (English instead of German):

date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
$date_now = date('Y-m-d');
echo strftime('%B %Y', strtotime($date_now));

This can be solved by installing the required language in the docker container. Unfortunately there is a bug which prevents that the languages can be easy activated by locale-gen <lang-code>. So you have to enable them in /etc/locale.gen first and then generate them with locale-gen. This code solves the problem:

FROM php:7-apache

[...]

# install localisation
RUN apt-get update && \
    # locales
    apt-get install -y locales

# enable localisation and generates localisation files
RUN sed -i -e 's/# de_DE ISO-8859-1/de_DE ISO-8859-1/' /etc/locale.gen && \ # to uncomment the lange
    sed -i -e 's/# <your lang code from locale.gen>/<your lang code from locale.gen again>/' /etc/locale.gen && \
    locale-gen

[...]

Or you could install all available languages:

FROM php:7-apache

[...]

# install localisation
RUN apt-get update && \
    # locales
    apt-get install -y locales locales-all

[...]

If you perform a dry run in the container, you must restart Apache for see the changes.

Add password to .p12/.pfx-certificate

With following procedure you can change your password on an .p12/.pfx certificate using openssl.

Export you current certificate to a passwordless pem type:

openssl pkcs12 -in mycert.pfx/mycert.p12 -out tmpmycert.pem -nodes
Enter Import Password: <Enter no password>
MAC verified OK

Convert the passwordless pem to a new pfx file with password:

openssl pkcs12 -export -out mycert2.pfx/mycert2.p12 -in tmpmycert.pem
Enter Export Password: <Enter password here>
Verifying - Enter Export Password: <Enter password here>

Now you are done and can use the new mycert2.pfx file with your new password.

[via]http://stackoverflow.com/a/35158695[/via]

pfSense 2.2.5 CaptivePortal Patch

Patch for pfSense 2.2.5 to redirect proxy users to the authentification portal.

*** captiveportal.inc  Wed Nov 04 22:52:22 2015
--- captiveportal_patched.inc   Mon Dec 14 17:12:42 2015
***************
*** 539,544 ****
--- 539,548 ----
  EOD;
  
    $rulenum = 65310;
+   /* Deny direct access to local services before captive portal authentication */
+   $local_service_ports="3128,3129";
+   $cprules .= "add {$rulenum} skipto 65314 ip from any to table(100) {$local_service_ports} in\n";
+   $cprules .= "add {$rulenum} skipto 65314 ip from table(100) {$local_service_ports} to any out\n";
    /* These tables contain host ips */
    $cprules .= "add {$rulenum} pass ip from any to table(100) in\n";
    $rulenum++;
***************
*** 578,591 ****
        else
            $listenporthttps = 8001 + $cpzoneid;
            if (!isset($config['captiveportal'][$cpzone]['nohttpsforwards'])) {
!               $cprules .= "add 65531 fwd 127.0.0.1,{$listenporthttps} tcp from any to any dst-port 443 in\n";
            }
    }
    
    $cprules .= <<<EOD
  
  # redirect non-authenticated clients to captive portal
! add 65532 fwd 127.0.0.1,{$listenporthttp} tcp from any to any dst-port 80 in 
  # let the responses from the captive portal web server back out
  add 65533 pass tcp from any to any out
  # block everything else
--- 582,596 ----
        else
            $listenporthttps = 8001 + $cpzoneid;
            if (!isset($config['captiveportal'][$cpzone]['nohttpsforwards'])) {
!               $cprules .= "add 65530 fwd 127.0.0.1,{$listenporthttps} tcp from any to any dst-port 443 in\n";
            }
    }
    
    $cprules .= <<<EOD
  
  # redirect non-authenticated clients to captive portal
! add 65531 fwd 127.0.0.1,{$listenporthttp} tcp from any to any dst-port 80 in 
! add 65532 fwd 127.0.0.1,{$listenporthttp} tcp from any to any dst-port 3128 in 
  # let the responses from the captive portal web server back out
  add 65533 pass tcp from any to any out
  # block everything else

Diff created with WinMerge.

MySQL: UPDATE query based on SELECT query

update tableA a
left join tableB b on
    a.name_a = b.name_b
set
    validation_check = if(start_dts > end_dts, 'VALID', '')
UPDATE payments p 
    INNER JOIN users u ON
    p.pay_id=u.user_id
SET 
    p.pay_email=u.user_email, 
    p.pay_firstname=u.user_firstname, 
    p.pay_lastname=u.user_lastname, 
    p.pay_date=u.user_date

[via]http://stackoverflow.com/a/1262848[/via]

PHP Password dos and don’ts

Don'ts

  • Don't limit what characters users can enter for passwords. Only idiots do this.
  • Don't limit the length of a password. If your users want a sentence with supercalifragilisticexpialidocious in it, don't prevent them from using it.
  • Never store your user's password in plain-text.
  • Never email a password to your user except when they have lost theirs, and you sent a temporary one.
  • Never, ever log passwords in any manner.
  • Never hash passwords with SHA1 or MD5 or even SHA256! Modern crackers can exceed 60 and 180 billion hashes/second (respectively).
  • Don't mix bcrypt and with the raw output of hash(), either use hex output or base64_encode it. (This applies to any input that may have a rogue \0 in it, which can seriously weaken security.)

Dos

  • Use scrypt when you can; bcrypt if you cannot.
  • Use PBKDF2 if you cannot use either bcrypt or scrypt, with SHA2 hashes.
  • Reset everyone's passwords when the database is compromised.
  • Implement a reasonable 8-10 character minimum length, plus require at least 1 upper case letter, 1 lower case letter, a number, and a symbol. This will improve the entropy of the password, in turn making it harder to crack. (See the "What makes a good password?" section for some debate.)

PHP

// Generate or return salted passwords
function crypt2($password, $salt = "") {

    if($salt == "") {
        // A higher "cost" is more secure but consumes more processing power
        $cost = 10;
        
        // Create a random salt
        $salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');

        // Prefix information about the hash so PHP knows how to verify it later.
        // "$2a$" Means we're using the Blowfish algorithm. The following two digits are the cost parameter.
        $salt = sprintf("$2a$%02d$", $cost) . $salt;
    }
        
    // Hash the password with the salt
    $hash = crypt($password, $salt);

    return $hash;
    
}
// Save password
$hash = crypt2($user_password); // hash the password with salt
dbquery("UPDATE users SET user_hash='".$hash."' WHERE user_id='1'");
// Login
$sql = "SELECT user_hash FROM users WHERE user_loginname='Admin' LIMIT 1";
[...]
$data = dbarray($result);

if (hash_equals($data['user_hash'], crypt2($user_pass, $data['user_hash']))) {
    // Ok!
}

[via]http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords/, https://alias.io/2010/01/store-passwords-safely-with-php-and-mysql/[/via]

white-space: pre-warp don’t work at Internet Explorer

Today i noticed that our Knowledge Base looks ugly at Internet Explorer. It seems that he ignoring the following CSS attribute:

white-space: pre-warp

After a few test I found out, that by default IE use for intranet page the compatibility mode. OMG...

There are two ways to change this. First you can add a meta attribute the every page:

<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

or you can use the Apache Module mod_headers which is my choise:
1. Change Apache2 Config to load the headers_module

LoadModule headers_module modules/mod_headers.so
  1. Change now the vhost.conf and add the Header
Header set X-UA-Compatible “IE=Edge”
  1. Reload Apache2