Files
server/usr/share/psa-horde/passwd/lib/Driver/Expectpecl.php
2026-01-07 20:52:11 +01:00

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.")
);
}
}