#!/usr/bin/php
<?php

function cred_encrypt($input, $password, $cipher = "aes-256-ecb") {
  if (in_array($cipher, openssl_get_cipher_methods())) {
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = "";
    if ($ivlen > 0) {
       // fallback to a cipher that can handle empty iv strings
       // we cannot handle IVs currently, as we need to store them somewhere persistently
       // between encryption and decryption
       $cipher = "aes-256-ecb";
    }

    echo "$input, $cipher, $password\n";
    $encrypted = openssl_encrypt($input, $cipher, $password, $options=0, $iv);
    if ($encrypted == false) return null;

    echo $encrypted."\n";
    echo bin2hex($encrypted)."\n";
    return bin2hex($encrypted);
  }

  return null;
}


function get_random_char() {
  $randno = rand (0, 63);
  if ($randno < 12) {
    return (chr ($randno + 46)); // Digits, '/' and '.'
  } else if ($randno < 38) {
    return (chr ($randno + 53)); // Uppercase
  } else {
    return (chr ($randno + 59)); // Lowercase
  }
}


function get_random_string($size= 32){
  $str= "";
  for ($i = 0; $i < $size; $i++) {
    $str .= get_random_char();
  }
  return $str;
}


# We need to have access to gosa.secrets
if (posix_getuid() != 0){
  die ("This program needs to be called by root!\n");
}

# Do we have a valid gosa.conf?
if (!file_exists("/etc/gosa/gosa.conf")){
  die ("Cannot find a valid /etc/gosa/gosa.conf!\n");
}

echo "Starting password encryption\n";
echo "* generating random master key\n";
$master_key= get_random_string();

# Do we have a valid gosa.secrets, already? 
if (file_exists("/etc/gosa/gosa.secrets")){
  die ("There's already a /etc/gosa/gosa.secrets. Cannot convert your existing gosa.conf - aborted\n");
} else {
  echo "* creating /etc/gosa/gosa.secrets\n";
  $fp = fopen("/etc/gosa/gosa.secrets", 'w') or die("Cannot open /etc/gosa/gosa.secrets for writing - aborted");
  fwrite($fp, "RequestHeader set GOSAKEY $master_key\n");
  fclose($fp);
  chmod ("/etc/gosa/gosa.secrets", 0600);
  chown ("/etc/gosa/gosa.secrets", "root");
  chgrp ("/etc/gosa/gosa.secrets", "root");
}

# Locate all passwords inside the gosa.conf
echo "* loading /etc/gosa/gosa.conf\n";
$conf = new DOMDocument();
$conf->load("/etc/gosa/gosa.conf") or die ("Cannot read /etc/gosa/gosa.conf - aborted\n");
$conf->encoding = 'UTF-8';
$referrals= $conf->getElementsByTagName("referral");
foreach($referrals as $referral){
  $user = $referral->attributes->getNamedItem("adminDn");
  echo "* encrypting GOsa password for: ".$user->nodeValue."\n";
  $pw= $referral->attributes->getNamedItem("adminPassword");

  $encryptedSecret = cred_encrypt($pw->nodeValue, $master_key);

  if($encryptedSecret !== NULL) {
    $pw->nodeValue = $encryptedSecret;
  }
}

# Encrypt the snapshot passwords 
$locations= $conf->getElementsByTagName("location");
foreach($locations as $location){
  $name = $location->attributes->getNamedItem("name"); 
  $node = $location->attributes->getNamedItem("snapshotAdminPassword"); 
  if($node->nodeValue){
    echo "* encrypting snapshot pasword for location: ".$name->nodeValue."\n";
    $encryptedSecret = cred_encrypt($node->nodeValue, $master_key);
    if($encryptedSecret !== NULL) {
      $node->nodeValue = $encryptedSecret;
    }
  }
}

# Move original gosa.conf out of the way and make it unreadable for the web user
echo "* creating backup in /etc/gosa/gosa.conf.orig\n";
rename("/etc/gosa/gosa.conf", "/etc/gosa/gosa.conf.orig");
chmod("/etc/gosa/gosa.conf.orig", 0600);
chown ("/etc/gosa/gosa.conf.orig", "root");
chgrp ("/etc/gosa/gosa.conf.orig", "root");

# Save new passwords
echo "* saving modified /etc/gosa/gosa.conf\n";
$conf->save("/etc/gosa/gosa.conf") or die("Cannot write modified /etc/gosa/gosa.conf - aborted\n");
chmod("/etc/gosa/gosa.conf", 0640);
chown ("/etc/gosa/gosa.conf", "root");
chgrp ("/etc/gosa/gosa.conf", "www-data");
echo "OK\n\n";

# Print reminder
echo<<<EOF
Please adapt your http gosa location declaration to include the newly
created "/etc/gosa/gosa.secrets".

Example:

Alias /gosa /usr/share/gosa/html

<Location /gosa>
  php_admin_flag engine on
  php_admin_value open_basedir "/etc/gosa/:/usr/share/gosa/:/var/cache/gosa/:/var/spool/gosa/"
  php_admin_flag register_globals off
  php_admin_flag allow_call_time_pass_reference off
  php_admin_flag expose_php off
  php_admin_flag zend.ze1_compatibility_mode off
  include /etc/gosa/gosa.secrets
</Location>


Please reload your httpd configuration after you've modified anything.


EOF;
?>
