143 lines
3.8 KiB
PHP
143 lines
3.8 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2006-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (GPL). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/gpl.
|
|
*
|
|
* @category Horde
|
|
* @copyright 2006-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/gpl GPL
|
|
* @package Passwd
|
|
*/
|
|
|
|
/**
|
|
* A PECL expect implementation of the Passwd system.
|
|
*
|
|
* Copyright 2006-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (GPL). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/gpl.
|
|
*
|
|
* @author Duck <duck@obala.net>
|
|
* @category Horde
|
|
* @copyright 2006-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/gpl GPL
|
|
* @package Passwd
|
|
*/
|
|
class Passwd_Driver_Expectpecl extends Passwd_Driver
|
|
{
|
|
/**
|
|
* Expect connection handle.
|
|
*
|
|
* @var resource
|
|
*/
|
|
protected $_stream;
|
|
|
|
/**
|
|
* Handles expect communication.
|
|
*
|
|
* @param string $expect String to expect.
|
|
* @param string $error Error message.
|
|
*
|
|
* @throws Passwd_Exception
|
|
*/
|
|
protected function _ctl($expect, $error)
|
|
{
|
|
$result = expect_expectl($this->_stream, array(
|
|
array(
|
|
0 => $expect,
|
|
1 => 'ok',
|
|
2 => EXP_REGEXP
|
|
)
|
|
));
|
|
|
|
switch ($result) {
|
|
case EXP_EOF:
|
|
throw new Passwd_Exception(_("End of file."));
|
|
|
|
case EXP_TIMEOUT:
|
|
throw new Passwd_Exception(_("Time out."));
|
|
|
|
case EXP_FULLBUFFER:
|
|
throw new Passwd_Exception(_("Full buffer."));
|
|
|
|
case 'ok':
|
|
return;
|
|
|
|
default:
|
|
throw new Passwd_Exception($error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*/
|
|
protected function _changePassword($user, $oldpass, $newpass)
|
|
{
|
|
if (!Horde_Util::loadExtension('expect')) {
|
|
throw new Passwd_Exception(_("expect extension cannot be loaded"));
|
|
}
|
|
|
|
// Set up parameters
|
|
foreach (array('logfile', 'loguser', 'timeout') as $val) {
|
|
if (isset($this->_params[$val])) {
|
|
ini_set('expect.' . $val, $this->_params[$val]);
|
|
}
|
|
}
|
|
|
|
// Open connection
|
|
$call = sprintf(
|
|
'ssh %s@%s %s',
|
|
$user,
|
|
$this->_params['host'],
|
|
$this->_params['program']
|
|
);
|
|
if (!($this->_stream = expect_popen($call))) {
|
|
throw new Passwd_Exception(_("Unable to open expect stream"));
|
|
}
|
|
|
|
// Log in
|
|
$this->_ctl(
|
|
'(P|p)assword.*',
|
|
_("Could not login to system (no password prompt)")
|
|
);
|
|
|
|
// Send login password
|
|
fwrite($this->_stream, $oldpass . "\n");
|
|
|
|
// Expect old password prompt
|
|
$this->_ctl(
|
|
'((O|o)ld|login|current).* (P|p)assword.*',
|
|
_("Could not start passwd program (no old password prompt)")
|
|
);
|
|
|
|
// Send old password
|
|
fwrite($this->_stream, $oldpass . "\n");
|
|
|
|
// Expect new password prompt
|
|
$this->_ctl(
|
|
'(N|n)ew.* (P|p)assword.*',
|
|
_("Could not change password (bad old password?)")
|
|
);
|
|
|
|
// Send new password
|
|
fwrite($this->_stream, $newpass . "\n");
|
|
|
|
// Expect reenter password prompt
|
|
$this->_ctl(
|
|
"((R|r)e-*enter.*(P|p)assword|Retype new( UNIX)? password|(V|v)erification|(V|v)erify|(A|a)gain).*",
|
|
_("New password not valid (too short, bad password, too similar, ...)")
|
|
);
|
|
|
|
// Send new password
|
|
fwrite($this->_stream, $newpass . "\n");
|
|
|
|
// Expect successfully message
|
|
$this->_ctl(
|
|
'((P|p)assword.* changed|successfully)',
|
|
_("Could not change password.")
|
|
);
|
|
}
|
|
|
|
}
|