/ispcp.php

https://github.com/Sweil/Roundcube-Password-Driver-for-ispCP · PHP · 183 lines · 114 code · 39 blank · 30 comment · 33 complexity · c57a7959f82ca26f0313aea15acff9dc MD5 · raw file

  1. <?php
  2. /**
  3. * ispCP Password Driver
  4. *
  5. * Driver for passwords stored in ispCP database
  6. *
  7. * @version 1.4
  8. * @author Sweil <mail@sweil.de>
  9. * @thx2 Sascha alias TheCry, Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
  10. *
  11. */
  12. class rcube_ispcp_password
  13. {
  14. function save($curpass, $passwd)
  15. {
  16. $rcmail = rcmail::get_instance();
  17. $sql = "UPDATE `mail_users` SET `mail_pass` = %p , `status` = 'change' WHERE `mail_addr` = %u AND `mail_pass` = %o LIMIT 1";
  18. if ($dsn = $rcmail->config->get('password_db_dsn')) {
  19. // #1486067: enable new_link option
  20. if (is_array($dsn) && empty($dsn['new_link']))
  21. $dsn['new_link'] = true;
  22. else if (!is_array($dsn) && !preg_match('/\?new_link=true/', $dsn))
  23. $dsn .= '?new_link=true';
  24. $db = new rcube_mdb2($dsn, '', FALSE);
  25. $db->set_debug((bool)$rcmail->config->get('sql_debug'));
  26. $db->db_connect('w');
  27. } else {
  28. $db = $rcmail->get_dbh();
  29. }
  30. if ($err = $db->is_error()) {
  31. return PASSWORD_CONNECT_ERROR;
  32. }
  33. // Make special ispCP things
  34. if ($rcmail->config->get('ispcp_db_pass_key') == "" || $rcmail->config->get('ispcp_db_pass_iv') == "") {
  35. return PASSWORD_CONNECT_ERROR;
  36. } else {
  37. $passwd = $this->encrypt_db_password($passwd);
  38. $curpass = $this->encrypt_db_password($curpass);
  39. }
  40. // at least we should always have the local part
  41. $sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
  42. $sql = str_replace('%p', $db->quote($passwd,'text'), $sql);
  43. $sql = str_replace('%o', $db->quote($curpass,'text'), $sql);
  44. // execute SQL query
  45. $res = $db->query($sql);
  46. // If ok, send request to ispcp daemon
  47. if (!$db->is_error()) {
  48. if ($db->affected_rows($res) == 1) {
  49. $this->send_request();
  50. }
  51. return PASSWORD_SUCCESS; // This is the good case: 1 row updated
  52. }
  53. return PASSWORD_ERROR;
  54. }
  55. private function encrypt_db_password($db_pass) {
  56. if (extension_loaded('mcrypt')) {
  57. $rcmail = rcmail::get_instance();
  58. $td = @mcrypt_module_open(MCRYPT_BLOWFISH, '', 'cbc', '');
  59. $key = $rcmail->config->get('ispcp_db_pass_key');
  60. $iv = $rcmail->config->get('ispcp_db_pass_iv');
  61. // compatibility with used perl pads
  62. $block_size = @mcrypt_enc_get_block_size($td);
  63. $strlen = strlen($db_pass);
  64. $pads = $block_size-$strlen % $block_size;
  65. $db_pass .= str_repeat(' ', $pads);
  66. // Initialize encryption
  67. @mcrypt_generic_init($td, $key, $iv);
  68. // Encrypt string
  69. $encrypted = @mcrypt_generic ($td, $db_pass);
  70. @mcrypt_generic_deinit($td);
  71. @mcrypt_module_close($td);
  72. $text = @base64_encode("$encrypted");
  73. // Show encrypted string
  74. return trim($text);
  75. } else {
  76. return PASSWORD_CRYPT_ERROR;
  77. }
  78. }
  79. /**
  80. * ISPcp imported functions
  81. */
  82. private function read_line(&$socket) {
  83. $ch = '';
  84. $line = '';
  85. do {
  86. $ch = socket_read($socket, 1);
  87. $line = $line . $ch;
  88. } while ($ch != "\r" && $ch != "\n");
  89. return $line;
  90. }
  91. private function send_request() {
  92. //config
  93. $url = '127.0.0.1';
  94. $port = 9876;
  95. $version = '1.0.7';
  96. @$socket = socket_create (AF_INET, SOCK_STREAM, getprotobyname('telnet'));
  97. if ($socket < 0) {
  98. $errno = "socket_create() failed.\n";
  99. return $errno;
  100. }
  101. @$result = socket_connect ($socket, $url, $port);
  102. if ($result == false) {
  103. $errno = "socket_connect() failed.\n";
  104. return $errno;
  105. }
  106. // read one line with welcome string
  107. $out = $this->read_line($socket);
  108. list($code) = explode(' ', $out);
  109. if ($code == 999) {
  110. return $out;
  111. }
  112. // send helo line
  113. $query = "helo ".$version."\r\n";
  114. socket_write ($socket, $query, strlen ($query));
  115. // read one line key replay
  116. $execute_reply = $this->read_line($socket);
  117. list($code) = explode(' ', $execute_reply);
  118. if ($code == 999) {
  119. return $out;
  120. }
  121. // send reg check query
  122. $query = "execute query\r\n";
  123. socket_write ($socket, $query, strlen ($query));
  124. // read one line key replay
  125. $execute_reply = $this->read_line($socket);
  126. list($code) = explode(' ', $execute_reply);
  127. if ($code == 999) {
  128. return $out;
  129. }
  130. // send quit query
  131. $quit_query = "bye\r\n";
  132. socket_write ($socket, $quit_query, strlen($quit_query));
  133. // read quit answer
  134. $quit_reply = $this->read_line($socket);
  135. list($code) = explode(' ', $quit_reply);
  136. if ($code == 999) {
  137. return $out;
  138. }
  139. list($answer) = explode(' ', $execute_reply);
  140. socket_close ($socket);
  141. return $answer;
  142. }
  143. }
  144. ?>