Changeset 2491 in subversion


Ignore:
Timestamp:
May 16, 2009 9:01:49 AM (4 years ago)
Author:
alec
Message:
  • Added possibility to encrypt received header, option 'http_received_header_encrypt', added some more logic in encrypt/decrypt functions for security
Location:
trunk/roundcubemail
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r2487 r2491  
    22=========================== 
    33 
     4- Added possibility to encrypt received header, option 'http_received_header_encrypt', 
     5  added some more logic in encrypt/decrypt functions for security 
    46- Fix Answered/Forwarded flag setting for messages in subfolders 
    57- Fix autocomplete problem with capital letters (#1485792) 
  • trunk/roundcubemail/config/main.inc.php.dist

    r2437 r2491  
    229229// add a received header to outgoing mails containing the creators IP and hostname 
    230230$rcmail_config['http_received_header'] = false; 
     231 
     232// Whether or not to encrypt the IP address and the host name 
     233// these could, in some circles, be considered as sensitive information; 
     234// however, for the administrator, these could be invaluable help 
     235// when tracking down issues. 
     236$rcmail_config['http_received_header_encrypt'] = false; 
    231237 
    232238// this string is used as a delimiter for message headers when sending 
  • trunk/roundcubemail/plugins/password/password.php

    r2488 r2491  
    88 * 
    99 * @version 1.1 
    10  * @author Aleksander 'A.L.E.C' Machniak 
     10 * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl> 
    1111 * @editor Daniel Black 
    1212 * 
     
    114114      $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST); 
    115115 
    116       if ($confirm && $_SESSION['password'] !=  $rcmail->encrypt_passwd($curpwd)) 
     116      if ($confirm && $rcmail->decrypt($_SESSION['password']) != $curpwd) 
    117117        $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error'); 
    118118      else if (!($res = $this->_save($curpwd,$newpwd))) { 
    119119        $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation'); 
    120         $_SESSION['password'] = $rcmail->encrypt_passwd($newpwd); 
     120        $_SESSION['password'] = $rcmail->encrypt($newpwd); 
    121121      } else 
    122122        $rcmail->output->command('display_message', $res, 'error'); 
     
    148148    $out = '<table' . $attrib_str . ">\n\n"; 
    149149 
    150     $a_show_cols = array('newpasswd'   => array('type' => 'text'), 
    151                 'confpasswd'   => array('type' => 'text')); 
    152  
    153150    if ($confirm) { 
    154       $a_show_cols['curpasswd'] = array('type' => 'text'); 
    155151      // show current password selection 
    156152      $field_id = 'curpasswd'; 
    157       $input_newpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id, 'size' => 20)); 
     153      $input_newpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id, 
     154            'size' => 20, 'autocomplete' => 'off')); 
    158155   
    159156      $out .= sprintf("<tr><td class=\"title\"><label for=\"%s\">%s</label></td><td>%s</td></tr>\n", 
     
    165162    // show new password selection 
    166163    $field_id = 'newpasswd'; 
    167     $input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id, 'size' => 20)); 
     164    $input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id, 
     165            'size' => 20, 'autocomplete' => 'off')); 
    168166 
    169167    $out .= sprintf("<tr><td class=\"title\"><label for=\"%s\">%s</label></td><td>%s</td></tr>\n", 
     
    174172    // show confirm password selection 
    175173    $field_id = 'confpasswd'; 
    176     $input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id, 'size' => 20)); 
     174    $input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id, 
     175            'size' => 20, 'autocomplete' => 'off')); 
    177176 
    178177    $out .= sprintf("<tr><td class=\"title\"><label for=\"%s\">%s</label></td><td>%s</td></tr>\n", 
  • trunk/roundcubemail/plugins/sasl_password/sasl_password.php

    r2405 r2491  
    5252      $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST); 
    5353 
    54       if ($_SESSION['password'] != $rcmail->encrypt_passwd($curpwd)) { 
     54      if ($rcmail->decrypt($_SESSION['password']) != $curpwd) { 
    5555        $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error'); 
    5656      } 
    5757      else if ($this->_save($newpwd)) { 
    5858        $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation'); 
    59         $_SESSION['password'] = $rcmail->encrypt_passwd($newpwd); 
     59        $_SESSION['password'] = $rcmail->encrypt($newpwd); 
    6060      } 
    6161      else { 
  • trunk/roundcubemail/program/include/rcmail.php

    r2481 r2491  
    393393     
    394394    if ($_SESSION['imap_host'] && !$this->imap->conn) { 
    395       if (!($conn = $this->imap->connect($_SESSION['imap_host'], $_SESSION['username'], $this->decrypt_passwd($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl']))) { 
     395      if (!($conn = $this->imap->connect($_SESSION['imap_host'], $_SESSION['username'], $this->decrypt($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl']))) { 
    396396        if ($this->output) 
    397397          $this->output->show_message($this->imap->error_code == -1 ? 'imaperror' : 'sessionerror', 'error'); 
     
    519519      $_SESSION['imap_port'] = $imap_port; 
    520520      $_SESSION['imap_ssl']  = $imap_ssl; 
    521       $_SESSION['password']  = $this->encrypt_passwd($pass); 
     521      $_SESSION['password']  = $this->encrypt($pass); 
    522522      $_SESSION['login_time'] = mktime(); 
    523523       
     
    874874  } 
    875875 
    876   /** 
    877    * Encrypt IMAP password using DES encryption 
    878    * 
    879    * @param string Password to encrypt 
    880    * @return string Encryprted string 
    881    */ 
    882   public function encrypt_passwd($pass) 
    883   { 
    884     if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) { 
     876 
     877  /** 
     878   * Encrypt using 3DES 
     879   * 
     880   * @param string $clear clear text input 
     881   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' 
     882   * @param boolean $base64 whether or not to base64_encode() the result before returning 
     883   * 
     884   * @return string encrypted text 
     885   */ 
     886  public function encrypt($clear, $key = 'des_key', $base64 = true) 
     887  { 
     888    /*- 
     889     * Add a single canary byte to the end of the clear text, which 
     890     * will help find out how much of padding will need to be removed 
     891     * upon decryption; see http://php.net/mcrypt_generic#68082 
     892     */ 
     893    $clear = pack("a*H2", $clear, "80"); 
     894   
     895    if (function_exists('mcrypt_module_open') && 
     896        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) 
     897    { 
    885898      $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
    886       mcrypt_generic_init($td, $this->config->get_des_key(), $iv); 
    887       $cypher = mcrypt_generic($td, $pass); 
     899      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); 
     900      $cipher = $iv . mcrypt_generic($td, $clear); 
    888901      mcrypt_generic_deinit($td); 
    889902      mcrypt_module_close($td); 
    890903    } 
    891     else if (function_exists('des')) { 
    892       $cypher = des($this->config->get_des_key(), $pass, 1, 0, NULL); 
    893     } 
    894     else { 
    895       $cypher = $pass; 
    896  
     904    else if (function_exists('des')) 
     905    { 
     906      define('DES_IV_SIZE', 8); 
     907      $iv = ''; 
     908      for ($i = 0; $i < constant('DES_IV_SIZE'); $i++) 
     909        $iv .= sprintf("%c", mt_rand(0, 255)); 
     910      $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv); 
     911    } 
     912    else 
     913    { 
    897914      raise_error(array( 
    898915        'code' => 500, 
    899916        'type' => 'php', 
    900917        'file' => __FILE__, 
    901         'message' => "Could not convert encrypt password. Make sure Mcrypt is installed or lib/des.inc is available" 
    902         ), true, false); 
    903     } 
    904  
    905     return base64_encode($cypher); 
    906   } 
    907  
    908  
    909   /** 
    910    * Decrypt IMAP password using DES encryption 
    911    * 
    912    * @param string Encrypted password 
    913    * @return string Plain password 
    914    */ 
    915   public function decrypt_passwd($cypher) 
    916   { 
    917     if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) { 
    918       $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
    919       mcrypt_generic_init($td, $this->config->get_des_key(), $iv); 
    920       $pass = mdecrypt_generic($td, base64_decode($cypher)); 
     918        'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available" 
     919      ), true, true); 
     920    } 
     921   
     922    return $base64 ? base64_encode($cipher) : $cipher; 
     923  } 
     924 
     925  /** 
     926   * Decrypt 3DES-encrypted string 
     927   * 
     928   * @param string $cipher encrypted text 
     929   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' 
     930   * @param boolean $base64 whether or not input is base64-encoded 
     931   * 
     932   * @return string decrypted text 
     933   */ 
     934  public function decrypt($cipher, $key = 'des_key', $base64 = true) 
     935  { 
     936    $cipher = $base64 ? base64_decode($cipher) : $cipher; 
     937 
     938    if (function_exists('mcrypt_module_open') && 
     939        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) 
     940    { 
     941      $iv = substr($cipher, 0, mcrypt_enc_get_iv_size($td)); 
     942      $cipher = substr($cipher, mcrypt_enc_get_iv_size($td)); 
     943      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); 
     944      $clear = mdecrypt_generic($td, $cipher); 
    921945      mcrypt_generic_deinit($td); 
    922946      mcrypt_module_close($td); 
    923947    } 
    924     else if (function_exists('des')) { 
    925       $pass = des($this->config->get_des_key(), base64_decode($cypher), 0, 0, NULL); 
    926     } 
    927     else { 
    928       $pass = base64_decode($cypher); 
    929     } 
    930  
    931     return preg_replace('/\x00/', '', $pass); 
    932   } 
    933  
     948    else if (function_exists('des')) 
     949    { 
     950      define('DES_IV_SIZE', 8); 
     951      $iv = substr($cipher, 0, constant('DES_IV_SIZE')); 
     952      $cipher = substr($cipher, constant('DES_IV_SIZE')); 
     953      $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv); 
     954    } 
     955    else 
     956    { 
     957      raise_error(array( 
     958        'code' => 500, 
     959        'type' => 'php', 
     960        'file' => __FILE__, 
     961        'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available" 
     962      ), true, true); 
     963    } 
     964   
     965    /*- 
     966     * Trim PHP's padding and the canary byte; see note in 
     967     * rcmail::encrypt() and http://php.net/mcrypt_generic#68082 
     968     */ 
     969    $clear = substr(rtrim($clear, "\0"), 0, -1); 
     970   
     971    return $clear; 
     972  } 
    934973 
    935974  /** 
  • trunk/roundcubemail/program/include/rcube_config.php

    r2401 r2491  
    177177    return $this->prop; 
    178178  } 
    179    
    180    
    181   /** 
    182    * Return a 24 byte key for the DES encryption 
    183    * 
    184    * @return string DES encryption key 
    185    */ 
    186   public function get_des_key() 
    187   { 
    188     $key = !empty($this->prop['des_key']) ? $this->prop['des_key'] : 'rcmail?24BitPwDkeyF**ECB'; 
    189     $len = strlen($key); 
    190  
    191     // make sure the key is exactly 24 chars long 
    192     if ($len<24) 
    193       $key .= str_repeat('_', 24-$len); 
    194     else if ($len>24) 
    195       substr($key, 0, 24); 
     179 
     180  /** 
     181   * Return requested DES crypto key. 
     182   * 
     183   * @param string Crypto key name 
     184   * @return string Crypto key 
     185   */ 
     186  public function get_crypto_key($key) 
     187  { 
     188    // Bomb out if the requested key does not exist 
     189    if (!array_key_exists($key, $this->prop)) 
     190    { 
     191      raise_error(array( 
     192        'code' => 500, 
     193        'type' => 'php', 
     194        'file' => __FILE__, 
     195        'message' => "Request for unconfigured crypto key \"$key\"" 
     196      ), true, true); 
     197    } 
     198   
     199    $key = $this->prop[$key]; 
     200   
     201    // Bomb out if the configured key is not exactly 24 bytes long 
     202    if (strlen($key) != 24) 
     203    { 
     204      raise_error(array( 
     205        'code' => 500, 
     206        'type' => 'php', 
     207        'file' => __FILE__, 
     208        'message' => "Configured crypto key \"$key\" is not exactly 24 bytes long" 
     209      ), true, true); 
     210    } 
    196211 
    197212    return $key; 
    198213  } 
    199    
    200    
     214 
    201215  /** 
    202216   * Try to autodetect operating system and find the correct line endings 
  • trunk/roundcubemail/program/include/rcube_ldap.php

    r2401 r2491  
    106106        // No password set, use the session password 
    107107        if (empty($this->prop['bind_pass'])) { 
    108           $this->prop['bind_pass'] = $RCMAIL->decrypt_passwd($_SESSION["password"]); 
     108          $this->prop['bind_pass'] = $RCMAIL->decrypt($_SESSION['password']); 
    109109        } 
    110110 
  • trunk/roundcubemail/program/include/rcube_smtp.inc

    r2453 r2491  
    104104 
    105105      if (strstr($CONFIG['smtp_pass'], '%p')) 
    106         $smtp_pass = str_replace('%p', $RCMAIL->decrypt_passwd($_SESSION['password']), $CONFIG['smtp_pass']); 
     106        $smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']); 
    107107      else 
    108108        $smtp_pass = $CONFIG['smtp_pass']; 
  • trunk/roundcubemail/program/localization/en_GB/messages.inc

    r2237 r2491  
    9595$messages['nofromaddress'] = 'Missing e-mail address in selected identity'; 
    9696$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?'; 
     97$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>'; 
    9798 
    9899?> 
  • trunk/roundcubemail/program/localization/en_US/messages.inc

    r2237 r2491  
    9595$messages['nofromaddress'] = 'Missing e-mail address in selected identity'; 
    9696$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?'; 
     97$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>'; 
    9798 
    9899?> 
  • trunk/roundcubemail/program/localization/hu_HU/messages.inc

    r2254 r2491  
    9696$messages['nofromaddress'] = 'Hiányzó email cím a kiválasztott feladónál'; 
    9797$messages['editorwarning'] = 'Az egyszerű szöveges formátumra való váltás az összes formázás elvesztésével jár. Biztosan folytatja?'; 
     98$messages['httpreceivedencrypterror'] = 'Végzetes konfigurációs hiba történt, azonnal lépjen kapcsolatba az ÃŒzemeltetővel. <b>Az ÃŒzenet nem kÃŒldhető el.</b>'; 
    9899 
    99100?> 
  • trunk/roundcubemail/program/localization/pl_PL/messages.inc

    r2237 r2491  
    127127$messages['nofromaddress'] = 'Brak adresu e-mail w wybranej toÅŒsamości'; 
    128128$messages['editorwarning'] = 'Zmiana edytora spowoduje utratę formatowania tekstu. Czy jesteś pewien, ÅŒe chcesz to zrobić?'; 
     129$messages['httpreceivedencrypterror'] = 'WystÄ 
     130pił błĠ
     131d systemu. Skontaktuj się z administratorem. <b>Nie moÅŒna wysłać wiadomości.</b>'; 
    129132 
    130133?> 
  • trunk/roundcubemail/program/steps/mail/sendmail.inc

    r2487 r2491  
    5555 
    5656/****** message sending functions ********/ 
     57 
     58// encrypt parts of the header 
     59function rcmail_encrypt_header($what) 
     60{ 
     61  global $CONFIG, $RCMAIL; 
     62  if (!$CONFIG['http_received_header_encrypt']) 
     63  { 
     64    return $what; 
     65  } 
     66  return $RCMAIL->encrypt($what); 
     67} 
    5768 
    5869// get identity record 
     
    212223 
    213224// compose headers array 
    214 $headers = array('Date' => date('r'), 
    215                  'From' => rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset), 
    216                  'To'   => $mailto); 
     225$headers = array(); 
     226 
     227// if configured, the Received headers goes to top, for good measure 
     228if ($CONFIG['http_received_header']) 
     229{ 
     230  $nldlm = $RCMAIL->config->header_delimiter() . "\t"; 
     231  $http_header = 'from '; 
     232  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
     233    $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR'])) . 
     234      ' [' . rcmail_encrypt_header($_SERVER['HTTP_X_FORWARDED_FOR']) . ']'; 
     235    $http_header .= $nldlm . ' via '; 
     236  } 
     237  $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['REMOTE_ADDR'])) . 
     238      ' [' . rcmail_encrypt_header($_SERVER['REMOTE_ADDR']) .']'; 
     239  $http_header .= $nldlm . 'with ' . $_SERVER['SERVER_PROTOCOL'] . 
     240      ' ('.$_SERVER['REQUEST_METHOD'] . '); ' . date('r'); 
     241  $http_header = wordwrap($http_header, 69, $nldlm); 
     242  $headers['Received'] = $http_header; 
     243} 
     244 
     245$headers['Date'] = date('r'); 
     246$headers['From'] = rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset); 
     247$headers['To'] = $mailto; 
    217248 
    218249// additional recipients 
     
    258289 
    259290// additional headers 
    260 if ($CONFIG['http_received_header']) 
    261 { 
    262   $nldlm = $RCMAIL->config->header_delimiter() . "\t"; 
    263   $headers['Received'] =  wordwrap('from ' . (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? 
    264       gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR']).' ['.$_SERVER['HTTP_X_FORWARDED_FOR'].']'.$nldlm.' via ' : '') . 
    265     gethostbyaddr($_SERVER['REMOTE_ADDR']).' ['.$_SERVER['REMOTE_ADDR'].']'.$nldlm.'with ' . 
    266     $_SERVER['SERVER_PROTOCOL'].' ('.$_SERVER['REQUEST_METHOD'].'); ' . date('r'), 
    267     69, $nldlm); 
    268 } 
    269  
    270291$headers['Message-ID'] = $message_id; 
    271292$headers['X-Sender'] = $from; 
Note: See TracChangeset for help on using the changeset viewer.