1<?php 2/** 3 * Copyright 2000-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file COPYING for license information (GPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/gpl. 7 * 8 * @category Horde 9 * @copyright 2000-2017 Horde LLC 10 * @license http://www.horde.org/licenses/gpl GPL 11 * @package Passwd 12 */ 13 14/** 15 * Changes a password via the SITE PSWD command used by Serv-u ftpd for 16 * Windows. 17 * 18 * @author Lucas Nelan (screen@brainkrash.com) 19 * @category Horde 20 * @copyright 2000-2017 Horde LLC 21 * @license http://www.horde.org/licenses/gpl GPL 22 * @package Passwd 23 */ 24class Passwd_Driver_Servuftp extends Passwd_Driver 25{ 26 const CONNECTED = '220'; 27 const GOODBYE = '221'; 28 const PASSWORDOK = '230'; 29 const USERNAMEOK = '331'; 30 const PASSWORDBAD = '530'; 31 32 /** 33 */ 34 protected $_fp; 35 36 /** 37 */ 38 public function __construct(array $params = array()) 39 { 40 if (empty($params['host']) || empty($params['port'])) { 41 throw new Passwd_Exception(_("Password module is missing required parameters.")); 42 } 43 44 parent::__construct(array_merge(array( 45 'timeout' => 30 46 ), $params)); 47 } 48 49 /** 50 */ 51 protected function _changePassword($user, $oldpass, $newpass) 52 { 53 if ($this->_connect() != self::CONNECTED) { 54 throw new Passwd_Exception(_("Connection failed")); 55 } 56 57 if ($this->_sendCommand('user', $user) != self::USERNAMEOK) { 58 $this->_disconnect(); 59 throw new Passwd_Exception(_("Unknown user")); 60 } 61 62 if ($this->_sendCommand('pass', $oldpass) != self::PASSWORDOK) { 63 $this->_disconnect(); 64 throw new Passwd_Exception(_("Incorrect password")); 65 } 66 67 if ($this->_sendCommand('site pswd', '"' . $oldpass. '" "' . $newpass. '"') != self::PASSWORDOK) { 68 $this->_disconnect(); 69 throw new Passwd_Exception(_("Cannot change password")); 70 } 71 72 $this->_disconnect(); 73 } 74 75 /** 76 * @throws Passwd_Exception 77 */ 78 protected function _connect() 79 { 80 $this->_fp = fsockopen( 81 $this->_params['host'], 82 $this->_params['port'], 83 $errno, 84 $errstr, 85 $this->_params['timeout'] 86 ); 87 if (!$this->_fp) { 88 throw new Passwd_Exception($errstr); 89 } 90 return $this->_getPrompt(); 91 } 92 93 /** 94 * @throws Passwd_Exception 95 */ 96 protected function _disconnect() 97 { 98 if ($this->_fp) { 99 fputs($this->_fp, "quit\n"); 100 fclose($this->_fp); 101 } 102 } 103 104 /** 105 * @throws Passwd_Exception 106 */ 107 protected function _getPrompt() 108 { 109 $prompt = fgets($this->_fp, 4096); 110 111 if (preg_match('/^[1-5][0-9][0-9]/', $prompt, $res)) { 112 return $res[1]; 113 } 114 } 115 116 /** 117 * @throws Passwd_Exception 118 */ 119 protected function _sendCommand($cmd, $arg) 120 { 121 $line = $cmd . ' ' . $arg . "\r\n"; 122 fputs($this->_fp, $line); 123 return $this->_getPrompt(); 124 } 125 126} 127