This commit is contained in:
Amberstone 2024-10-12 13:34:19 +09:00
parent 7fa0609ac5
commit b905c326c2
Signed by: amber
GPG key ID: 094B0E55F98D8BF1
16 changed files with 4711 additions and 4629 deletions

View file

@ -6,3 +6,15 @@ insert_final_newline = true
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
[*.php]
indent_style = space
indent_size = 2
[composer.json]
indent_style = space
indent_size = 2
[*.yml]
indent_style = space
indent_size = 2

View file

@ -23,16 +23,16 @@
*/ */
function PHPMailerAutoload($classname) function PHPMailerAutoload($classname)
{ {
//Can't use __DIR__ as it's only in PHP 5.3+ //Can't use __DIR__ as it's only in PHP 5.3+
$filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php'; $filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'class.' . strtolower($classname) . '.php';
if (is_readable($filename)) { if (is_readable($filename)) {
require $filename; require $filename;
} }
} }
//SPL autoloading was introduced in PHP 5.1.2 //SPL autoloading was introduced in PHP 5.1.2
if (version_compare(PHP_VERSION, '5.3.0', '>=')) { if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
spl_autoload_register('PHPMailerAutoload', true, true); spl_autoload_register('PHPMailerAutoload', true, true);
} else { } else {
spl_autoload_register('PHPMailerAutoload'); spl_autoload_register('PHPMailerAutoload');
} }

View file

@ -25,173 +25,174 @@
*/ */
class PHPMailerOAuth extends PHPMailer class PHPMailerOAuth extends PHPMailer
{ {
/** /**
* The OAuth user's email address * The OAuth user's email address
* @var string * @var string
*/ */
public $oauthUserEmail = ''; public $oauthUserEmail = '';
/** /**
* The OAuth refresh token * The OAuth refresh token
* @var string * @var string
*/ */
public $oauthRefreshToken = ''; public $oauthRefreshToken = '';
/** /**
* The OAuth client ID * The OAuth client ID
* @var string * @var string
*/ */
public $oauthClientId = ''; public $oauthClientId = '';
/** /**
* The OAuth client secret * The OAuth client secret
* @var string * @var string
*/ */
public $oauthClientSecret = ''; public $oauthClientSecret = '';
/** /**
* An instance of the PHPMailerOAuthGoogle class. * An instance of the PHPMailerOAuthGoogle class.
* @var PHPMailerOAuthGoogle * @var PHPMailerOAuthGoogle
* @access protected * @access protected
*/ */
protected $oauth = null; protected $oauth = null;
/** /**
* Get a PHPMailerOAuthGoogle instance to use. * Get a PHPMailerOAuthGoogle instance to use.
* @return PHPMailerOAuthGoogle * @return PHPMailerOAuthGoogle
*/ */
public function getOAUTHInstance() public function getOAUTHInstance()
{ {
if (!is_object($this->oauth)) { if (!is_object($this->oauth)) {
$this->oauth = new PHPMailerOAuthGoogle( $this->oauth = new PHPMailerOAuthGoogle(
$this->oauthUserEmail, $this->oauthUserEmail,
$this->oauthClientSecret, $this->oauthClientSecret,
$this->oauthClientId, $this->oauthClientId,
$this->oauthRefreshToken $this->oauthRefreshToken
); );
} }
return $this->oauth; return $this->oauth;
}
/**
* Initiate a connection to an SMTP server.
* Overrides the original smtpConnect method to add support for OAuth.
* @param array $options An array of options compatible with stream_context_create()
* @uses SMTP
* @access public
* @return bool
* @throws phpmailerException
*/
public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
} }
/** if (is_null($this->oauth)) {
* Initiate a connection to an SMTP server. $this->oauth = $this->getOAUTHInstance();
* Overrides the original smtpConnect method to add support for OAuth.
* @param array $options An array of options compatible with stream_context_create()
* @uses SMTP
* @access public
* @return bool
* @throws phpmailerException
*/
public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}
if (is_null($this->oauth)) {
$this->oauth = $this->getOAUTHInstance();
}
// Already connected?
if ($this->smtp->connected()) {
return true;
}
$this->smtp->setTimeout($this->Timeout);
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$hosts = explode(';', $this->Host);
$lastexception = null;
foreach ($hosts as $hostentry) {
$hostinfo = array();
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
// Not a valid host entry
continue;
}
// $hostinfo[2]: optional ssl or tls prefix
// $hostinfo[3]: the hostname
// $hostinfo[4]: optional port number
// The host string prefix can temporarily override the current setting for SMTPSecure
// If it's not specified, the default value is used
$prefix = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
// tls doesn't use a prefix
$secure = 'tls';
}
//Do we need the OpenSSL extension?
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
}
}
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer)$hostinfo[4];
if ($tport > 0 and $tport < 65536) {
$port = $tport;
}
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
try {
if ($this->Helo) {
$hello = $this->Helo;
} else {
$hello = $this->serverHostname();
}
$this->smtp->hello($hello);
//Automatically enable TLS encryption if:
// * it's not disabled
// * we have openssl extension
// * we are not already using SSL
// * the server offers STARTTLS
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
// We must resend HELO after tls negotiation
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation,
$this->oauth
)
) {
throw new phpmailerException($this->lang('authenticate'));
}
}
return true;
} catch (phpmailerException $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
// We must have connected, but then failed TLS or Auth, so close connection nicely
$this->smtp->quit();
}
}
}
// If we get here, all connection attempts have failed, so close connection hard
$this->smtp->close();
// As we've caught all exceptions, just report whatever the last one was
if ($this->exceptions and !is_null($lastexception)) {
throw $lastexception;
}
return false;
} }
// Already connected?
if ($this->smtp->connected()) {
return true;
}
$this->smtp->setTimeout($this->Timeout);
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$hosts = explode(';', $this->Host);
$lastexception = null;
foreach ($hosts as $hostentry) {
$hostinfo = array();
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
// Not a valid host entry
continue;
}
// $hostinfo[2]: optional ssl or tls prefix
// $hostinfo[3]: the hostname
// $hostinfo[4]: optional port number
// The host string prefix can temporarily override the current setting for SMTPSecure
// If it's not specified, the default value is used
$prefix = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
// tls doesn't use a prefix
$secure = 'tls';
}
//Do we need the OpenSSL extension?
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
}
}
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer) $hostinfo[4];
if ($tport > 0 and $tport < 65536) {
$port = $tport;
}
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
try {
if ($this->Helo) {
$hello = $this->Helo;
} else {
$hello = $this->serverHostname();
}
$this->smtp->hello($hello);
//Automatically enable TLS encryption if:
// * it's not disabled
// * we have openssl extension
// * we are not already using SSL
// * the server offers STARTTLS
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
// We must resend HELO after tls negotiation
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
if (
!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation,
$this->oauth
)
) {
throw new phpmailerException($this->lang('authenticate'));
}
}
return true;
} catch (phpmailerException $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
// We must have connected, but then failed TLS or Auth, so close connection nicely
$this->smtp->quit();
}
}
}
// If we get here, all connection attempts have failed, so close connection hard
$this->smtp->close();
// As we've caught all exceptions, just report whatever the last one was
if ($this->exceptions and !is_null($lastexception)) {
throw $lastexception;
}
return false;
}
} }

View file

@ -26,52 +26,52 @@
*/ */
class PHPMailerOAuthGoogle class PHPMailerOAuthGoogle
{ {
private $oauthUserEmail = ''; private $oauthUserEmail = '';
private $oauthRefreshToken = ''; private $oauthRefreshToken = '';
private $oauthClientId = ''; private $oauthClientId = '';
private $oauthClientSecret = ''; private $oauthClientSecret = '';
/** /**
* @param string $UserEmail * @param string $UserEmail
* @param string $ClientSecret * @param string $ClientSecret
* @param string $ClientId * @param string $ClientId
* @param string $RefreshToken * @param string $RefreshToken
*/ */
public function __construct( public function __construct(
$UserEmail, $UserEmail,
$ClientSecret, $ClientSecret,
$ClientId, $ClientId,
$RefreshToken $RefreshToken
) { ) {
$this->oauthClientId = $ClientId; $this->oauthClientId = $ClientId;
$this->oauthClientSecret = $ClientSecret; $this->oauthClientSecret = $ClientSecret;
$this->oauthRefreshToken = $RefreshToken; $this->oauthRefreshToken = $RefreshToken;
$this->oauthUserEmail = $UserEmail; $this->oauthUserEmail = $UserEmail;
} }
private function getProvider() private function getProvider()
{ {
return new League\OAuth2\Client\Provider\Google([ return new League\OAuth2\Client\Provider\Google([
'clientId' => $this->oauthClientId, 'clientId' => $this->oauthClientId,
'clientSecret' => $this->oauthClientSecret 'clientSecret' => $this->oauthClientSecret
]); ]);
} }
private function getGrant() private function getGrant()
{ {
return new \League\OAuth2\Client\Grant\RefreshToken(); return new \League\OAuth2\Client\Grant\RefreshToken();
} }
private function getToken() private function getToken()
{ {
$provider = $this->getProvider(); $provider = $this->getProvider();
$grant = $this->getGrant(); $grant = $this->getGrant();
return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]); return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
} }
public function getOauth64() public function getOauth64()
{ {
$token = $this->getToken(); $token = $this->getToken();
return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001"); return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001");
} }
} }

View file

@ -29,379 +29,380 @@
*/ */
class POP3 class POP3
{ {
/** /**
* The POP3 PHPMailer Version number. * The POP3 PHPMailer Version number.
* @var string * @var string
* @access public * @access public
*/ */
public $Version = '5.2.28'; public $Version = '5.2.28';
/** /**
* Default POP3 port number. * Default POP3 port number.
* @var integer * @var integer
* @access public * @access public
*/ */
public $POP3_PORT = 110; public $POP3_PORT = 110;
/** /**
* Default timeout in seconds. * Default timeout in seconds.
* @var integer * @var integer
* @access public * @access public
*/ */
public $POP3_TIMEOUT = 30; public $POP3_TIMEOUT = 30;
/** /**
* POP3 Carriage Return + Line Feed. * POP3 Carriage Return + Line Feed.
* @var string * @var string
* @access public * @access public
* @deprecated Use the constant instead * @deprecated Use the constant instead
*/ */
public $CRLF = "\r\n"; public $CRLF = "\r\n";
/** /**
* Debug display level. * Debug display level.
* Options: 0 = no, 1+ = yes * Options: 0 = no, 1+ = yes
* @var integer * @var integer
* @access public * @access public
*/ */
public $do_debug = 0; public $do_debug = 0;
/** /**
* POP3 mail server hostname. * POP3 mail server hostname.
* @var string * @var string
* @access public * @access public
*/ */
public $host; public $host;
/** /**
* POP3 port number. * POP3 port number.
* @var integer * @var integer
* @access public * @access public
*/ */
public $port; public $port;
/** /**
* POP3 Timeout Value in seconds. * POP3 Timeout Value in seconds.
* @var integer * @var integer
* @access public * @access public
*/ */
public $tval; public $tval;
/** /**
* POP3 username * POP3 username
* @var string * @var string
* @access public * @access public
*/ */
public $username; public $username;
/** /**
* POP3 password. * POP3 password.
* @var string * @var string
* @access public * @access public
*/ */
public $password; public $password;
/** /**
* Resource handle for the POP3 connection socket. * Resource handle for the POP3 connection socket.
* @var resource * @var resource
* @access protected * @access protected
*/ */
protected $pop_conn; protected $pop_conn;
/** /**
* Are we connected? * Are we connected?
* @var boolean * @var boolean
* @access protected * @access protected
*/ */
protected $connected = false; protected $connected = false;
/** /**
* Error container. * Error container.
* @var array * @var array
* @access protected * @access protected
*/ */
protected $errors = array(); protected $errors = array();
/** /**
* Line break constant * Line break constant
*/ */
const CRLF = "\r\n"; const CRLF = "\r\n";
/** /**
* Simple static wrapper for all-in-one POP before SMTP * Simple static wrapper for all-in-one POP before SMTP
* @param $host * @param $host
* @param integer|boolean $port The port number to connect to * @param integer|boolean $port The port number to connect to
* @param integer|boolean $timeout The timeout value * @param integer|boolean $timeout The timeout value
* @param string $username * @param string $username
* @param string $password * @param string $password
* @param integer $debug_level * @param integer $debug_level
* @return boolean * @return boolean
*/ */
public static function popBeforeSmtp( public static function popBeforeSmtp(
$host, $host,
$port = false, $port = false,
$timeout = false, $timeout = false,
$username = '', $username = '',
$password = '', $password = '',
$debug_level = 0 $debug_level = 0
) { ) {
$pop = new POP3; $pop = new POP3;
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
}
/**
* Authenticate with a POP3 server.
* A connect, login, disconnect sequence
* appropriate for POP-before SMTP authorisation.
* @access public
* @param string $host The hostname to connect to
* @param integer|boolean $port The port number to connect to
* @param integer|boolean $timeout The timeout value
* @param string $username
* @param string $password
* @param integer $debug_level
* @return boolean
*/
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
{
$this->host = $host;
// If no port value provided, use default
if (false === $port) {
$this->port = $this->POP3_PORT;
} else {
$this->port = (integer) $port;
} }
// If no timeout value provided, use default
/** if (false === $timeout) {
* Authenticate with a POP3 server. $this->tval = $this->POP3_TIMEOUT;
* A connect, login, disconnect sequence } else {
* appropriate for POP-before SMTP authorisation. $this->tval = (integer) $timeout;
* @access public }
* @param string $host The hostname to connect to $this->do_debug = $debug_level;
* @param integer|boolean $port The port number to connect to $this->username = $username;
* @param integer|boolean $timeout The timeout value $this->password = $password;
* @param string $username // Reset the error log
* @param string $password $this->errors = array();
* @param integer $debug_level // connect
* @return boolean $result = $this->connect($this->host, $this->port, $this->tval);
*/ if ($result) {
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) $login_result = $this->login($this->username, $this->password);
{ if ($login_result) {
$this->host = $host;
// If no port value provided, use default
if (false === $port) {
$this->port = $this->POP3_PORT;
} else {
$this->port = (integer)$port;
}
// If no timeout value provided, use default
if (false === $timeout) {
$this->tval = $this->POP3_TIMEOUT;
} else {
$this->tval = (integer)$timeout;
}
$this->do_debug = $debug_level;
$this->username = $username;
$this->password = $password;
// Reset the error log
$this->errors = array();
// connect
$result = $this->connect($this->host, $this->port, $this->tval);
if ($result) {
$login_result = $this->login($this->username, $this->password);
if ($login_result) {
$this->disconnect();
return true;
}
}
// We need to disconnect regardless of whether the login succeeded
$this->disconnect(); $this->disconnect();
return false; return true;
}
}
// We need to disconnect regardless of whether the login succeeded
$this->disconnect();
return false;
}
/**
* Connect to a POP3 server.
* @access public
* @param string $host
* @param integer|boolean $port
* @param integer $tval
* @return boolean
*/
public function connect($host, $port = false, $tval = 30)
{
// Are we already connected?
if ($this->connected) {
return true;
} }
/** //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
* Connect to a POP3 server. //Rather than suppress it with @fsockopen, capture it cleanly instead
* @access public set_error_handler(array($this, 'catchWarning'));
* @param string $host
* @param integer|boolean $port
* @param integer $tval
* @return boolean
*/
public function connect($host, $port = false, $tval = 30)
{
// Are we already connected?
if ($this->connected) {
return true;
}
//On Windows this will raise a PHP Warning error if the hostname doesn't exist. if (false === $port) {
//Rather than suppress it with @fsockopen, capture it cleanly instead $port = $this->POP3_PORT;
set_error_handler(array($this, 'catchWarning'));
if (false === $port) {
$port = $this->POP3_PORT;
}
// connect to the POP3 server
$this->pop_conn = fsockopen(
$host, // POP3 Host
$port, // Port #
$errno, // Error Number
$errstr, // Error Message
$tval
); // Timeout (seconds)
// Restore the error handler
restore_error_handler();
// Did we connect?
if (false === $this->pop_conn) {
// It would appear not...
$this->setError(array(
'error' => "Failed to connect to server $host on port $port",
'errno' => $errno,
'errstr' => $errstr
));
return false;
}
// Increase the stream time-out
stream_set_timeout($this->pop_conn, $tval, 0);
// Get the POP3 server response
$pop3_response = $this->getResponse();
// Check for the +OK
if ($this->checkResponse($pop3_response)) {
// The connection is established and the POP3 server is talking
$this->connected = true;
return true;
}
return false;
} }
/** // connect to the POP3 server
* Log in to the POP3 server. $this->pop_conn = fsockopen(
* Does not support APOP (RFC 2828, 4949). $host, // POP3 Host
* @access public $port, // Port #
* @param string $username $errno, // Error Number
* @param string $password $errstr, // Error Message
* @return boolean $tval
*/ ); // Timeout (seconds)
public function login($username = '', $password = '') // Restore the error handler
{ restore_error_handler();
if (!$this->connected) {
$this->setError('Not connected to POP3 server');
}
if (empty($username)) {
$username = $this->username;
}
if (empty($password)) {
$password = $this->password;
}
// Send the Username // Did we connect?
$this->sendString("USER $username" . self::CRLF); if (false === $this->pop_conn) {
$pop3_response = $this->getResponse(); // It would appear not...
if ($this->checkResponse($pop3_response)) { $this->setError(array(
// Send the Password 'error' => "Failed to connect to server $host on port $port",
$this->sendString("PASS $password" . self::CRLF); 'errno' => $errno,
$pop3_response = $this->getResponse(); 'errstr' => $errstr
if ($this->checkResponse($pop3_response)) { ));
return true; return false;
}
}
return false;
} }
/** // Increase the stream time-out
* Disconnect from the POP3 server. stream_set_timeout($this->pop_conn, $tval, 0);
* @access public
*/ // Get the POP3 server response
public function disconnect() $pop3_response = $this->getResponse();
{ // Check for the +OK
$this->sendString('QUIT'); if ($this->checkResponse($pop3_response)) {
//The QUIT command may cause the daemon to exit, which will kill our connection // The connection is established and the POP3 server is talking
//So ignore errors here $this->connected = true;
try { return true;
@fclose($this->pop_conn); }
} catch (Exception $e) { return false;
//Do nothing }
};
/**
* Log in to the POP3 server.
* Does not support APOP (RFC 2828, 4949).
* @access public
* @param string $username
* @param string $password
* @return boolean
*/
public function login($username = '', $password = '')
{
if (!$this->connected) {
$this->setError('Not connected to POP3 server');
}
if (empty($username)) {
$username = $this->username;
}
if (empty($password)) {
$password = $this->password;
} }
/** // Send the Username
* Get a response from the POP3 server. $this->sendString("USER $username" . self::CRLF);
* $size is the maximum number of bytes to retrieve $pop3_response = $this->getResponse();
* @param integer $size if ($this->checkResponse($pop3_response)) {
* @return string // Send the Password
* @access protected $this->sendString("PASS $password" . self::CRLF);
*/ $pop3_response = $this->getResponse();
protected function getResponse($size = 128) if ($this->checkResponse($pop3_response)) {
{ return true;
$response = fgets($this->pop_conn, $size); }
if ($this->do_debug >= 1) {
echo "Server -> Client: $response";
}
return $response;
} }
return false;
}
/** /**
* Send raw data to the POP3 server. * Disconnect from the POP3 server.
* @param string $string * @access public
* @return integer */
* @access protected public function disconnect()
*/ {
protected function sendString($string) $this->sendString('QUIT');
{ //The QUIT command may cause the daemon to exit, which will kill our connection
if ($this->pop_conn) { //So ignore errors here
if ($this->do_debug >= 2) { //Show client messages when debug >= 2 try {
echo "Client -> Server: $string"; @fclose($this->pop_conn);
} } catch (Exception $e) {
return fwrite($this->pop_conn, $string, strlen($string)); //Do nothing
}
return 0;
} }
;
}
/** /**
* Checks the POP3 server response. * Get a response from the POP3 server.
* Looks for for +OK or -ERR. * $size is the maximum number of bytes to retrieve
* @param string $string * @param integer $size
* @return boolean * @return string
* @access protected * @access protected
*/ */
protected function checkResponse($string) protected function getResponse($size = 128)
{ {
if (substr($string, 0, 3) !== '+OK') { $response = fgets($this->pop_conn, $size);
$this->setError(array( if ($this->do_debug >= 1) {
'error' => "Server reported an error: $string", echo "Server -> Client: $response";
'errno' => 0,
'errstr' => ''
));
return false;
} else {
return true;
}
} }
return $response;
}
/** /**
* Add an error to the internal error store. * Send raw data to the POP3 server.
* Also display debug output if it's enabled. * @param string $string
* @param $error * @return integer
* @access protected * @access protected
*/ */
protected function setError($error) protected function sendString($string)
{ {
$this->errors[] = $error; if ($this->pop_conn) {
if ($this->do_debug >= 1) { if ($this->do_debug >= 2) { //Show client messages when debug >= 2
echo '<pre>'; echo "Client -> Server: $string";
foreach ($this->errors as $error) { }
print_r($error); return fwrite($this->pop_conn, $string, strlen($string));
}
echo '</pre>';
}
} }
return 0;
}
/** /**
* Get an array of error messages, if any. * Checks the POP3 server response.
* @return array * Looks for for +OK or -ERR.
*/ * @param string $string
public function getErrors() * @return boolean
{ * @access protected
return $this->errors; */
protected function checkResponse($string)
{
if (substr($string, 0, 3) !== '+OK') {
$this->setError(array(
'error' => "Server reported an error: $string",
'errno' => 0,
'errstr' => ''
));
return false;
} else {
return true;
} }
}
/** /**
* POP3 connection error handler. * Add an error to the internal error store.
* @param integer $errno * Also display debug output if it's enabled.
* @param string $errstr * @param $error
* @param string $errfile * @access protected
* @param integer $errline */
* @access protected protected function setError($error)
*/ {
protected function catchWarning($errno, $errstr, $errfile, $errline) $this->errors[] = $error;
{ if ($this->do_debug >= 1) {
$this->setError(array( echo '<pre>';
'error' => "Connecting to the POP3 server raised a PHP warning: ", foreach ($this->errors as $error) {
'errno' => $errno, print_r($error);
'errstr' => $errstr, }
'errfile' => $errfile, echo '</pre>';
'errline' => $errline
));
} }
}
/**
* Get an array of error messages, if any.
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* POP3 connection error handler.
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
* @access protected
*/
protected function catchWarning($errno, $errstr, $errfile, $errline)
{
$this->setError(array(
'error' => "Connecting to the POP3 server raised a PHP warning: ",
'errno' => $errno,
'errstr' => $errstr,
'errfile' => $errfile,
'errline' => $errline
));
}
} }

File diff suppressed because it is too large Load diff

View file

@ -19,104 +19,104 @@
*/ */
class EasyPeasyICS class EasyPeasyICS
{ {
/** /**
* The name of the calendar * The name of the calendar
* @var string * @var string
*/ */
protected $calendarName; protected $calendarName;
/** /**
* The array of events to add to this calendar * The array of events to add to this calendar
* @var array * @var array
*/ */
protected $events = array(); protected $events = array();
/** /**
* Constructor * Constructor
* @param string $calendarName * @param string $calendarName
*/ */
public function __construct($calendarName = "") public function __construct($calendarName = "")
{ {
$this->calendarName = $calendarName; $this->calendarName = $calendarName;
}
/**
* Add an event to this calendar.
* @param string $start The start date and time as a unix timestamp
* @param string $end The end date and time as a unix timestamp
* @param string $summary A summary or title for the event
* @param string $description A description of the event
* @param string $url A URL for the event
* @param string $uid A unique identifier for the event - generated automatically if not provided
* @return array An array of event details, including any generated UID
*/
public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')
{
if (empty($uid)) {
$uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';
} }
$event = array(
'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',
'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',
'summary' => $summary,
'description' => $description,
'url' => $url,
'uid' => $uid
);
$this->events[] = $event;
return $event;
}
/** /**
* Add an event to this calendar. * @return array Get the array of events.
* @param string $start The start date and time as a unix timestamp */
* @param string $end The end date and time as a unix timestamp public function getEvents()
* @param string $summary A summary or title for the event {
* @param string $description A description of the event return $this->events;
* @param string $url A URL for the event }
* @param string $uid A unique identifier for the event - generated automatically if not provided
* @return array An array of event details, including any generated UID
*/
public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')
{
if (empty($uid)) {
$uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';
}
$event = array(
'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',
'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',
'summary' => $summary,
'description' => $description,
'url' => $url,
'uid' => $uid
);
$this->events[] = $event;
return $event;
}
/** /**
* @return array Get the array of events. * Clear all events.
*/ */
public function getEvents() public function clearEvents()
{ {
return $this->events; $this->events = array();
} }
/** /**
* Clear all events. * Get the name of the calendar.
*/ * @return string
public function clearEvents() */
{ public function getName()
$this->events = array(); {
} return $this->calendarName;
}
/** /**
* Get the name of the calendar. * Set the name of the calendar.
* @return string * @param $name
*/ */
public function getName() public function setName($name)
{ {
return $this->calendarName; $this->calendarName = $name;
} }
/** /**
* Set the name of the calendar. * Render and optionally output a vcal string.
* @param $name * @param bool $output Whether to output the calendar data directly (the default).
*/ * @return string The complete rendered vlal
public function setName($name) */
{ public function render($output = true)
$this->calendarName = $name; {
} //Add header
$ics = 'BEGIN:VCALENDAR
/**
* Render and optionally output a vcal string.
* @param bool $output Whether to output the calendar data directly (the default).
* @return string The complete rendered vlal
*/
public function render($output = true)
{
//Add header
$ics = 'BEGIN:VCALENDAR
METHOD:PUBLISH METHOD:PUBLISH
VERSION:2.0 VERSION:2.0
X-WR-CALNAME:' . $this->calendarName . ' X-WR-CALNAME:' . $this->calendarName . '
PRODID:-//hacksw/handcal//NONSGML v1.0//EN'; PRODID:-//hacksw/handcal//NONSGML v1.0//EN';
//Add events //Add events
foreach ($this->events as $event) { foreach ($this->events as $event) {
$ics .= ' $ics .= '
BEGIN:VEVENT BEGIN:VEVENT
UID:' . $event['uid'] . ' UID:' . $event['uid'] . '
DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z
@ -126,23 +126,23 @@ SUMMARY:' . str_replace("\n", "\\n", $event['summary']) . '
DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . ' DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . '
URL;VALUE=URI:' . $event['url'] . ' URL;VALUE=URI:' . $event['url'] . '
END:VEVENT'; END:VEVENT';
} }
//Add footer //Add footer
$ics .= ' $ics .= '
END:VCALENDAR'; END:VCALENDAR';
if ($output) { if ($output) {
//Output //Output
$filename = $this->calendarName; $filename = $this->calendarName;
//Filename needs quoting if it contains spaces //Filename needs quoting if it contains spaces
if (strpos($filename, ' ') !== false) { if (strpos($filename, ' ') !== false) {
$filename = '"'.$filename.'"'; $filename = '"' . $filename . '"';
} }
header('Content-type: text/calendar; charset=utf-8'); header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=' . $filename . '.ics'); header('Content-Disposition: inline; filename=' . $filename . '.ics');
echo $ics; echo $ics;
}
return $ics;
} }
return $ics;
}
} }

File diff suppressed because it is too large Load diff

View file

@ -15,171 +15,172 @@ define("SASL_CONTINUE", 1);
class ntlm_sasl_client_class class ntlm_sasl_client_class
{ {
public $credentials = array(); public $credentials = array();
public $state = SASL_NTLM_STATE_START; public $state = SASL_NTLM_STATE_START;
public function initialize(&$client) public function initialize(&$client)
{ {
if (!function_exists($function = "mcrypt_encrypt") if (
|| !function_exists($function = "mhash") !function_exists($function = "mcrypt_encrypt")
) { || !function_exists($function = "mhash")
$extensions = array( ) {
"mcrypt_encrypt" => "mcrypt", $extensions = array(
"mhash" => "mhash" "mcrypt_encrypt" => "mcrypt",
); "mhash" => "mhash"
$client->error = "the extension " . $extensions[$function] . );
" required by the NTLM SASL client class is not available in this PHP configuration"; $client->error = "the extension " . $extensions[$function] .
return (0); " required by the NTLM SASL client class is not available in this PHP configuration";
} return (0);
return (1);
} }
return (1);
}
public function ASCIIToUnicode($ascii) public function ASCIIToUnicode($ascii)
{ {
for ($unicode = "", $a = 0; $a < strlen($ascii); $a++) { for ($unicode = "", $a = 0; $a < strlen($ascii); $a++) {
$unicode .= substr($ascii, $a, 1) . chr(0); $unicode .= substr($ascii, $a, 1) . chr(0);
}
return ($unicode);
} }
return ($unicode);
}
public function typeMsg1($domain, $workstation) public function typeMsg1($domain, $workstation)
{ {
$domain_length = strlen($domain); $domain_length = strlen($domain);
$workstation_length = strlen($workstation); $workstation_length = strlen($workstation);
$workstation_offset = 32; $workstation_offset = 32;
$domain_offset = $workstation_offset + $workstation_length; $domain_offset = $workstation_offset + $workstation_length;
return ( return (
"NTLMSSP\0" . "NTLMSSP\0" .
"\x01\x00\x00\x00" . "\x01\x00\x00\x00" .
"\x07\x32\x00\x00" . "\x07\x32\x00\x00" .
pack("v", $domain_length) . pack("v", $domain_length) .
pack("v", $domain_length) . pack("v", $domain_length) .
pack("V", $domain_offset) . pack("V", $domain_offset) .
pack("v", $workstation_length) . pack("v", $workstation_length) .
pack("v", $workstation_length) . pack("v", $workstation_length) .
pack("V", $workstation_offset) . pack("V", $workstation_offset) .
$workstation . $workstation .
$domain $domain
);
}
public function NTLMResponse($challenge, $password)
{
$unicode = $this->ASCIIToUnicode($password);
$md4 = hash('md4', $unicode, true);
$padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
$iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
for ($response = "", $third = 0; $third < 21; $third += 7) {
for ($packed = "", $p = $third; $p < $third + 7; $p++) {
$packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, "0", STR_PAD_LEFT);
}
for ($key = "", $p = 0; $p < strlen($packed); $p += 7) {
$s = substr($packed, $p, 7);
$b = $s . ((substr_count($s, "1") % 2) ? "0" : "1");
$key .= chr(bindec($b));
}
$ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);
$response .= $ciphertext;
}
return $response;
}
public function typeMsg3($ntlm_response, $user, $domain, $workstation)
{
$domain_unicode = $this->ASCIIToUnicode($domain);
$domain_length = strlen($domain_unicode);
$domain_offset = 64;
$user_unicode = $this->ASCIIToUnicode($user);
$user_length = strlen($user_unicode);
$user_offset = $domain_offset + $domain_length;
$workstation_unicode = $this->ASCIIToUnicode($workstation);
$workstation_length = strlen($workstation_unicode);
$workstation_offset = $user_offset + $user_length;
$lm = "";
$lm_length = strlen($lm);
$lm_offset = $workstation_offset + $workstation_length;
$ntlm = $ntlm_response;
$ntlm_length = strlen($ntlm);
$ntlm_offset = $lm_offset + $lm_length;
$session = "";
$session_length = strlen($session);
$session_offset = $ntlm_offset + $ntlm_length;
return (
"NTLMSSP\0" .
"\x03\x00\x00\x00" .
pack("v", $lm_length) .
pack("v", $lm_length) .
pack("V", $lm_offset) .
pack("v", $ntlm_length) .
pack("v", $ntlm_length) .
pack("V", $ntlm_offset) .
pack("v", $domain_length) .
pack("v", $domain_length) .
pack("V", $domain_offset) .
pack("v", $user_length) .
pack("v", $user_length) .
pack("V", $user_offset) .
pack("v", $workstation_length) .
pack("v", $workstation_length) .
pack("V", $workstation_offset) .
pack("v", $session_length) .
pack("v", $session_length) .
pack("V", $session_offset) .
"\x01\x02\x00\x00" .
$domain_unicode .
$user_unicode .
$workstation_unicode .
$lm .
$ntlm
);
}
public function start(&$client, &$message, &$interactions)
{
if ($this->state != SASL_NTLM_STATE_START) {
$client->error = "NTLM authentication state is not at the start";
return (SASL_FAIL);
}
$this->credentials = array(
"user" => "",
"password" => "",
"realm" => "",
"workstation" => ""
);
$defaults = array();
$status = $client->GetCredentials($this->credentials, $defaults, $interactions);
if ($status == SASL_CONTINUE) {
$this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;
}
unset($message);
return ($status);
}
public function step(&$client, $response, &$message, &$interactions)
{
switch ($this->state) {
case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
$message = $this->typeMsg1($this->credentials["realm"], $this->credentials["workstation"]);
$this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;
break;
case SASL_NTLM_STATE_RESPOND_CHALLENGE:
$ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials["password"]);
$message = $this->typeMsg3(
$ntlm_response,
$this->credentials["user"],
$this->credentials["realm"],
$this->credentials["workstation"]
); );
$this->state = SASL_NTLM_STATE_DONE;
break;
case SASL_NTLM_STATE_DONE:
$client->error = "NTLM authentication was finished without success";
return (SASL_FAIL);
default:
$client->error = "invalid NTLM authentication step state";
return (SASL_FAIL);
} }
return (SASL_CONTINUE);
public function NTLMResponse($challenge, $password) }
{
$unicode = $this->ASCIIToUnicode($password);
$md4 = hash('md4', $unicode, true);
$padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
$iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
for ($response = "", $third = 0; $third < 21; $third += 7) {
for ($packed = "", $p = $third; $p < $third + 7; $p++) {
$packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, "0", STR_PAD_LEFT);
}
for ($key = "", $p = 0; $p < strlen($packed); $p += 7) {
$s = substr($packed, $p, 7);
$b = $s . ((substr_count($s, "1") % 2) ? "0" : "1");
$key .= chr(bindec($b));
}
$ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);
$response .= $ciphertext;
}
return $response;
}
public function typeMsg3($ntlm_response, $user, $domain, $workstation)
{
$domain_unicode = $this->ASCIIToUnicode($domain);
$domain_length = strlen($domain_unicode);
$domain_offset = 64;
$user_unicode = $this->ASCIIToUnicode($user);
$user_length = strlen($user_unicode);
$user_offset = $domain_offset + $domain_length;
$workstation_unicode = $this->ASCIIToUnicode($workstation);
$workstation_length = strlen($workstation_unicode);
$workstation_offset = $user_offset + $user_length;
$lm = "";
$lm_length = strlen($lm);
$lm_offset = $workstation_offset + $workstation_length;
$ntlm = $ntlm_response;
$ntlm_length = strlen($ntlm);
$ntlm_offset = $lm_offset + $lm_length;
$session = "";
$session_length = strlen($session);
$session_offset = $ntlm_offset + $ntlm_length;
return (
"NTLMSSP\0" .
"\x03\x00\x00\x00" .
pack("v", $lm_length) .
pack("v", $lm_length) .
pack("V", $lm_offset) .
pack("v", $ntlm_length) .
pack("v", $ntlm_length) .
pack("V", $ntlm_offset) .
pack("v", $domain_length) .
pack("v", $domain_length) .
pack("V", $domain_offset) .
pack("v", $user_length) .
pack("v", $user_length) .
pack("V", $user_offset) .
pack("v", $workstation_length) .
pack("v", $workstation_length) .
pack("V", $workstation_offset) .
pack("v", $session_length) .
pack("v", $session_length) .
pack("V", $session_offset) .
"\x01\x02\x00\x00" .
$domain_unicode .
$user_unicode .
$workstation_unicode .
$lm .
$ntlm
);
}
public function start(&$client, &$message, &$interactions)
{
if ($this->state != SASL_NTLM_STATE_START) {
$client->error = "NTLM authentication state is not at the start";
return (SASL_FAIL);
}
$this->credentials = array(
"user" => "",
"password" => "",
"realm" => "",
"workstation" => ""
);
$defaults = array();
$status = $client->GetCredentials($this->credentials, $defaults, $interactions);
if ($status == SASL_CONTINUE) {
$this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;
}
unset($message);
return ($status);
}
public function step(&$client, $response, &$message, &$interactions)
{
switch ($this->state) {
case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
$message = $this->typeMsg1($this->credentials["realm"], $this->credentials["workstation"]);
$this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;
break;
case SASL_NTLM_STATE_RESPOND_CHALLENGE:
$ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials["password"]);
$message = $this->typeMsg3(
$ntlm_response,
$this->credentials["user"],
$this->credentials["realm"],
$this->credentials["workstation"]
);
$this->state = SASL_NTLM_STATE_DONE;
break;
case SASL_NTLM_STATE_DONE:
$client->error = "NTLM authentication was finished without success";
return (SASL_FAIL);
default:
$client->error = "invalid NTLM authentication step state";
return (SASL_FAIL);
}
return (SASL_CONTINUE);
}
} }

View file

@ -34,129 +34,129 @@ $clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
class Google extends AbstractProvider class Google extends AbstractProvider
{ {
use BearerAuthorizationTrait; use BearerAuthorizationTrait;
const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id'; const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';
/** /**
* @var string If set, this will be sent to google as the "access_type" parameter. * @var string If set, this will be sent to google as the "access_type" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline * @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
*/ */
protected $accessType; protected $accessType;
/** /**
* @var string If set, this will be sent to google as the "hd" parameter. * @var string If set, this will be sent to google as the "hd" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param * @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param
*/ */
protected $hostedDomain; protected $hostedDomain;
/** /**
* @var string If set, this will be sent to google as the "scope" parameter. * @var string If set, this will be sent to google as the "scope" parameter.
* @link https://developers.google.com/gmail/api/auth/scopes * @link https://developers.google.com/gmail/api/auth/scopes
*/ */
protected $scope; protected $scope;
public function getBaseAuthorizationUrl() public function getBaseAuthorizationUrl()
{ {
return 'https://accounts.google.com/o/oauth2/auth'; return 'https://accounts.google.com/o/oauth2/auth';
}
public function getBaseAccessTokenUrl(array $params)
{
return 'https://accounts.google.com/o/oauth2/token';
}
public function getResourceOwnerDetailsUrl(AccessToken $token)
{
return ' ';
}
protected function getAuthorizationParameters(array $options)
{
if (is_array($this->scope)) {
$separator = $this->getScopeSeparator();
$this->scope = implode($separator, $this->scope);
} }
public function getBaseAccessTokenUrl(array $params) $params = array_merge(
{ parent::getAuthorizationParameters($options),
return 'https://accounts.google.com/o/oauth2/token'; array_filter([
'hd' => $this->hostedDomain,
'access_type' => $this->accessType,
'scope' => $this->scope,
// if the user is logged in with more than one account ask which one to use for the login!
'authuser' => '-1'
])
);
return $params;
}
protected function getDefaultScopes()
{
return [
'email',
'openid',
'profile',
];
}
protected function getScopeSeparator()
{
return ' ';
}
protected function checkResponse(ResponseInterface $response, $data)
{
if (!empty($data['error'])) {
$code = 0;
$error = $data['error'];
if (is_array($error)) {
$code = $error['code'];
$error = $error['message'];
}
throw new IdentityProviderException($error, $code, $data);
} }
}
public function getResourceOwnerDetailsUrl(AccessToken $token) protected function createResourceOwner(array $response, AccessToken $token)
{ {
return ' '; return new GoogleUser($response);
} }
protected function getAuthorizationParameters(array $options)
{
if (is_array($this->scope)) {
$separator = $this->getScopeSeparator();
$this->scope = implode($separator, $this->scope);
}
$params = array_merge(
parent::getAuthorizationParameters($options),
array_filter([
'hd' => $this->hostedDomain,
'access_type' => $this->accessType,
'scope' => $this->scope,
// if the user is logged in with more than one account ask which one to use for the login!
'authuser' => '-1'
])
);
return $params;
}
protected function getDefaultScopes()
{
return [
'email',
'openid',
'profile',
];
}
protected function getScopeSeparator()
{
return ' ';
}
protected function checkResponse(ResponseInterface $response, $data)
{
if (!empty($data['error'])) {
$code = 0;
$error = $data['error'];
if (is_array($error)) {
$code = $error['code'];
$error = $error['message'];
}
throw new IdentityProviderException($error, $code, $data);
}
}
protected function createResourceOwner(array $response, AccessToken $token)
{
return new GoogleUser($response);
}
} }
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php //Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
$provider = new Google( $provider = new Google(
array( array(
'clientId' => $clientId, 'clientId' => $clientId,
'clientSecret' => $clientSecret, 'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri, 'redirectUri' => $redirectUri,
'scope' => array('https://mail.google.com/'), 'scope' => array('https://mail.google.com/'),
'accessType' => 'offline' 'accessType' => 'offline'
) )
); );
if (!isset($_GET['code'])) { if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one // If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl(); $authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->getState(); $_SESSION['oauth2state'] = $provider->getState();
header('Location: ' . $authUrl); header('Location: ' . $authUrl);
exit; exit;
// Check given state against previously stored one to mitigate CSRF attack // Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { } elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']); unset($_SESSION['oauth2state']);
exit('Invalid state'); exit('Invalid state');
} else { } else {
// Try to get an access token (using the authorization code grant) // Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken( $token = $provider->getAccessToken(
'authorization_code', 'authorization_code',
array( array(
'code' => $_GET['code'] 'code' => $_GET['code']
) )
); );
// Use this to get a new access token if the old one expires // Use this to get a new access token if the old one expires
echo 'Refresh Token: ' . $token->getRefreshToken(); echo 'Refresh Token: ' . $token->getRefreshToken();
} }

File diff suppressed because it is too large Load diff

View file

@ -16,277 +16,287 @@
# See kcaptcha_config.php for customization # See kcaptcha_config.php for customization
class KCAPTCHA{ class KCAPTCHA
{
private $keystring; private $keystring;
// generates keystring and image // generates keystring and image
function image(){ function image()
require dirname(__FILE__).'/kcaptcha_config.php'; {
require dirname(__FILE__) . '/kcaptcha_config.php';
$fonts=array(); $fonts = array();
$fontsdir_absolute=dirname(__FILE__).'/'.$fontsdir; $fontsdir_absolute = dirname(__FILE__) . '/' . $fontsdir;
if ($handle = opendir($fontsdir_absolute)) { if ($handle = opendir($fontsdir_absolute)) {
while (false !== ($file = readdir($handle))) { while (false !== ($file = readdir($handle))) {
if (preg_match('/\.png$/i', $file)) { if (preg_match('/\.png$/i', $file)) {
$fonts[]=$fontsdir_absolute.'/'.$file; $fonts[] = $fontsdir_absolute . '/' . $file;
} }
} }
closedir($handle); closedir($handle);
} }
$alphabet_length=strlen($alphabet); $alphabet_length = strlen($alphabet);
$font_file=$fonts[mt_rand(0, count($fonts)-1)]; $font_file = $fonts[mt_rand(0, count($fonts) - 1)];
$font=imagecreatefrompng($font_file); $font = imagecreatefrompng($font_file);
imagealphablending($font, true); imagealphablending($font, true);
$fontfile_width=imagesx($font); $fontfile_width = imagesx($font);
$fontfile_height=imagesy($font)-1; $fontfile_height = imagesy($font) - 1;
$font_metrics=array(); $font_metrics = array();
$symbol=0; $symbol = 0;
$reading_symbol=false; $reading_symbol = false;
// loading font // loading font
for($i=0;$i<$fontfile_width && $symbol<$alphabet_length;$i++){ for ($i = 0; $i < $fontfile_width && $symbol < $alphabet_length; $i++) {
$transparent = (imagecolorat($font, $i, 0) >> 24) == 127; $transparent = (imagecolorat($font, $i, 0) >> 24) == 127;
if(!$reading_symbol && !$transparent){ if (!$reading_symbol && !$transparent) {
$font_metrics[$alphabet[$symbol]]=array('start'=>$i); $font_metrics[$alphabet[$symbol]] = array('start' => $i);
$reading_symbol=true; $reading_symbol = true;
continue; continue;
}
if ($reading_symbol && $transparent) {
$font_metrics[$alphabet[$symbol]]['end'] = $i;
$reading_symbol = false;
$symbol++;
continue;
}
}
$img = imagecreatetruecolor($width, $height);
imagealphablending($img, true);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
imagefilledrectangle($img, 0, 0, $width - 1, $height - 1, $white);
// draw text
$x = 1;
$odd = mt_rand(0, 1);
if ($odd == 0)
$odd = -1;
for ($i = 0; $i < $length; $i++) {
if (!isset($this->keystring[$i]))
continue;
$m = $font_metrics[$this->keystring[$i]];
$y = (($i % 2) * $fluctuation_amplitude - $fluctuation_amplitude / 2) * $odd
+ mt_rand(-round($fluctuation_amplitude / 3), round($fluctuation_amplitude / 3))
+ ($height - $fontfile_height) / 2;
if ($no_spaces) {
$shift = 0;
if ($i > 0) {
$shift = 10000;
for ($sy = 3; $sy < $fontfile_height - 10; $sy += 1) {
for ($sx = $m['start'] - 1; $sx < $m['end']; $sx += 1) {
$rgb = imagecolorat($font, $sx, $sy);
$opacity = $rgb >> 24;
if ($opacity < 127) {
$left = $sx - $m['start'] + $x;
$py = $sy + $y;
if ($py > $height)
break;
for ($px = min($left, $width - 1); $px > $left - 200 && $px >= 0; $px -= 1) {
$color = imagecolorat($img, $px, $py) & 0xff;
if ($color + $opacity < 170) { // 170 - threshold
if ($shift > $left - $px) {
$shift = $left - $px;
}
break;
}
}
break;
}
} }
}
if ($shift == 10000) {
$shift = mt_rand(4, 6);
}
if($reading_symbol && $transparent){ }
$font_metrics[$alphabet[$symbol]]['end']=$i; } else {
$reading_symbol=false; $shift = 1;
$symbol++; }
continue; imagecopy($img, $font, $x - $shift, $y, $m['start'], 1, $m['end'] - $m['start'], $fontfile_height);
} $x += $m['end'] - $m['start'] - $shift;
}
//noise
$white = imagecolorallocate($font, 255, 255, 255);
$black = imagecolorallocate($font, 0, 0, 0);
for ($i = 0; $i < (($height - 30) * $x) * $white_noise_density; $i++) {
imagesetpixel($img, mt_rand(0, $x - 1), mt_rand(10, $height - 15), $white);
}
for ($i = 0; $i < (($height - 30) * $x) * $black_noise_density; $i++) {
imagesetpixel($img, mt_rand(0, $x - 1), mt_rand(10, $height - 15), $black);
}
$center = $x / 2;
// credits. To remove, see configuration file
$img2 = imagecreatetruecolor($width, $height + ($show_credits ? 12 : 0));
$foreground = imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
$background = imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($img2, 0, 0, $width - 1, $height - 1, $background);
imagefilledrectangle($img2, 0, $height, $width - 1, $height + 12, $foreground);
$credits = empty($credits) ? $_SERVER['HTTP_HOST'] : $credits;
imagestring($img2, 2, $width / 2 - imagefontwidth(2) * strlen($credits) / 2, $height - 2, $credits, $background);
// periods
$rand1 = mt_rand(750000, 1200000) / 10000000;
$rand2 = mt_rand(750000, 1200000) / 10000000;
$rand3 = mt_rand(750000, 1200000) / 10000000;
$rand4 = mt_rand(750000, 1200000) / 10000000;
// phases
$rand5 = mt_rand(0, 31415926) / 10000000;
$rand6 = mt_rand(0, 31415926) / 10000000;
$rand7 = mt_rand(0, 31415926) / 10000000;
$rand8 = mt_rand(0, 31415926) / 10000000;
// amplitudes
$rand9 = mt_rand(330, 420) / 110;
$rand10 = mt_rand(330, 450) / 110;
//wave distortion
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
if ($wave) {
$sx = $x + (sin($x * $rand1 + $rand5) + sin($y * $rand3 + $rand6)) * $rand9 - $width / 2 + $center + 1;
$sy = $y + (sin($x * $rand2 + $rand7) + sin($y * $rand4 + $rand8)) * $rand10;
} else {
$sx = $x - $width / 2 + $center + 1;
$sy = $y + (sin($x * $rand2 + $rand7) + sin($y * $rand4 + $rand8)) * 1.5;
} }
$img=imagecreatetruecolor($width, $height); if ($sx < 0 || $sy < 0 || $sx >= $width - 1 || $sy >= $height - 1) {
imagealphablending($img, true); continue;
$white=imagecolorallocate($img, 255, 255, 255); } else {
$black=imagecolorallocate($img, 0, 0, 0); $color = imagecolorat($img, (int) $sx, (int) $sy) & 0xFF;
$color_x = imagecolorat($img, (int) $sx + 1, (int) $sy) & 0xFF;
imagefilledrectangle($img, 0, 0, $width-1, $height-1, $white); $color_y = imagecolorat($img, (int) $sx, (int) $sy + 1) & 0xFF;
$color_xy = imagecolorat($img, (int) $sx + 1, (int) $sy + 1) & 0xFF;
// draw text
$x=1;
$odd=mt_rand(0,1);
if($odd==0) $odd=-1;
for($i=0;$i<$length;$i++){
if( ! isset($this->keystring[$i]) ) continue;
$m=$font_metrics[$this->keystring[$i]];
$y=(($i%2)*$fluctuation_amplitude - $fluctuation_amplitude/2)*$odd
+ mt_rand(-round($fluctuation_amplitude/3), round($fluctuation_amplitude/3))
+ ($height-$fontfile_height)/2;
if($no_spaces){
$shift=0;
if($i>0){
$shift=10000;
for($sy=3;$sy<$fontfile_height-10;$sy+=1){
for($sx=$m['start']-1;$sx<$m['end'];$sx+=1){
$rgb=imagecolorat($font, $sx, $sy);
$opacity=$rgb>>24;
if($opacity<127){
$left=$sx-$m['start']+$x;
$py=$sy+$y;
if($py>$height) break;
for($px=min($left,$width-1);$px>$left-200 && $px>=0;$px-=1){
$color=imagecolorat($img, $px, $py) & 0xff;
if($color+$opacity<170){ // 170 - threshold
if($shift>$left-$px){
$shift=$left-$px;
}
break;
}
}
break;
}
}
}
if($shift==10000){
$shift=mt_rand(4,6);
}
}
}else{
$shift=1;
}
imagecopy($img, $font, $x-$shift, $y, $m['start'], 1, $m['end']-$m['start'], $fontfile_height);
$x+=$m['end']-$m['start']-$shift;
} }
//noise if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {
$white=imagecolorallocate($font, 255, 255, 255); continue;
$black=imagecolorallocate($font, 0, 0, 0); } else if ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) {
for($i=0;$i<(($height-30)*$x)*$white_noise_density;$i++){ $newred = $foreground_color[0];
imagesetpixel($img, mt_rand(0, $x-1), mt_rand(10, $height-15), $white); $newgreen = $foreground_color[1];
} $newblue = $foreground_color[2];
for($i=0;$i<(($height-30)*$x)*$black_noise_density;$i++){ } else {
imagesetpixel($img, mt_rand(0, $x-1), mt_rand(10, $height-15), $black); $frsx = $sx - floor($sx);
} $frsy = $sy - floor($sy);
$frsx1 = 1 - $frsx;
$frsy1 = 1 - $frsy;
$center=$x/2; $newcolor = (
$color * $frsx1 * $frsy1 +
$color_x * $frsx * $frsy1 +
$color_y * $frsx1 * $frsy +
$color_xy * $frsx * $frsy);
// credits. To remove, see configuration file if ($newcolor > 255)
$img2=imagecreatetruecolor($width, $height+($show_credits?12:0)); $newcolor = 255;
$foreground=imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]); $newcolor = $newcolor / 255;
$background=imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]); $newcolor0 = 1 - $newcolor;
imagefilledrectangle($img2, 0, 0, $width-1, $height-1, $background);
imagefilledrectangle($img2, 0, $height, $width-1, $height+12, $foreground);
$credits=empty($credits)?$_SERVER['HTTP_HOST']:$credits;
imagestring($img2, 2, $width/2-imagefontwidth(2)*strlen($credits)/2, $height-2, $credits, $background);
// periods $newred = $newcolor0 * $foreground_color[0] + $newcolor * $background_color[0];
$rand1=mt_rand(750000,1200000)/10000000; $newgreen = $newcolor0 * $foreground_color[1] + $newcolor * $background_color[1];
$rand2=mt_rand(750000,1200000)/10000000; $newblue = $newcolor0 * $foreground_color[2] + $newcolor * $background_color[2];
$rand3=mt_rand(750000,1200000)/10000000; }
$rand4=mt_rand(750000,1200000)/10000000;
// phases
$rand5=mt_rand(0,31415926)/10000000;
$rand6=mt_rand(0,31415926)/10000000;
$rand7=mt_rand(0,31415926)/10000000;
$rand8=mt_rand(0,31415926)/10000000;
// amplitudes
$rand9=mt_rand(330,420)/110;
$rand10=mt_rand(330,450)/110;
//wave distortion imagesetpixel($img2, (int) $x, (int) $y, imagecolorallocate($img2, (int) $newred, (int) $newgreen, (int) $newblue));
}
}
for($x=0;$x<$width;$x++){ header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
for($y=0;$y<$height;$y++){ header('Cache-Control: no-store, no-cache, must-revalidate');
if ($wave) { header('Cache-Control: post-check=0, pre-check=0', FALSE);
$sx=$x+(sin($x*$rand1+$rand5)+sin($y*$rand3+$rand6))*$rand9-$width/2+$center+1; header('Pragma: no-cache');
$sy=$y+(sin($x*$rand2+$rand7)+sin($y*$rand4+$rand8))*$rand10;
}
else {
$sx=$x-$width/2+$center+1;
$sy=$y+(sin($x*$rand2+$rand7)+sin($y*$rand4+$rand8))*1.5;
}
if($sx<0 || $sy<0 || $sx>=$width-1 || $sy>=$height-1){ if (function_exists("imagejpeg")) {
continue; header("Content-Type: image/jpeg");
}else{ imagejpeg($img2, null, $jpeg_quality);
$color=imagecolorat($img, (int)$sx, (int)$sy) & 0xFF; } else if (function_exists("imagegif")) {
$color_x=imagecolorat($img, (int)$sx+1, (int)$sy) & 0xFF; header("Content-Type: image/gif");
$color_y=imagecolorat($img, (int)$sx, (int)$sy+1) & 0xFF; imagegif($img2);
$color_xy=imagecolorat($img, (int)$sx+1, (int)$sy+1) & 0xFF; } else if (function_exists("imagepng")) {
} header("Content-Type: image/x-png");
imagepng($img2);
}
}
if($color==255 && $color_x==255 && $color_y==255 && $color_xy==255){ // returns keystring
continue; function getKeyString()
}else if($color==0 && $color_x==0 && $color_y==0 && $color_xy==0){ {
$newred=$foreground_color[0]; return $this->keystring;
$newgreen=$foreground_color[1]; }
$newblue=$foreground_color[2];
}else{
$frsx=$sx-floor($sx);
$frsy=$sy-floor($sy);
$frsx1=1-$frsx;
$frsy1=1-$frsy;
$newcolor=( function setKeyString($str)
$color*$frsx1*$frsy1+ {
$color_x*$frsx*$frsy1+ $this->keystring = $str;
$color_y*$frsx1*$frsy+ }
$color_xy*$frsx*$frsy);
if($newcolor>255) $newcolor=255;
$newcolor=$newcolor/255;
$newcolor0=1-$newcolor;
$newred=$newcolor0*$foreground_color[0]+$newcolor*$background_color[0];
$newgreen=$newcolor0*$foreground_color[1]+$newcolor*$background_color[1];
$newblue=$newcolor0*$foreground_color[2]+$newcolor*$background_color[2];
}
imagesetpixel($img2, (int)$x, (int)$y, imagecolorallocate($img2, (int)$newred, (int)$newgreen, (int)$newblue));
}
}
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');
if(function_exists("imagejpeg")){
header("Content-Type: image/jpeg");
imagejpeg($img2, null, $jpeg_quality);
}else if(function_exists("imagegif")){
header("Content-Type: image/gif");
imagegif($img2);
}else if(function_exists("imagepng")){
header("Content-Type: image/x-png");
imagepng($img2);
}
}
// returns keystring
function getKeyString(){
return $this->keystring;
}
function setKeyString($str){
$this->keystring = $str;
}
} }
// 캡챠 HTML 코드 출력 // 캡챠 HTML 코드 출력
function captcha_html($class="captcha") function captcha_html($class = "captcha")
{ {
if(is_mobile()) if (is_mobile())
$class .= ' m_captcha'; $class .= ' m_captcha';
$html = "\n".'<script>var g5_captcha_url = "'.G5_CAPTCHA_URL.'";</script>'; $html = "\n" . '<script>var g5_captcha_url = "' . G5_CAPTCHA_URL . '";</script>';
//$html .= "\n".'<script>var g5_captcha_path = "'.G5_CAPTCHA_PATH.'";</script>'; //$html .= "\n".'<script>var g5_captcha_path = "'.G5_CAPTCHA_PATH.'";</script>';
$html .= "\n".'<script src="'.G5_CAPTCHA_URL.'/kcaptcha.js"></script>'; $html .= "\n" . '<script src="' . G5_CAPTCHA_URL . '/kcaptcha.js"></script>';
$html .= "\n".'<fieldset id="captcha" class="'.$class.'">'; $html .= "\n" . '<fieldset id="captcha" class="' . $class . '">';
$html .= "\n".'<legend><label for="captcha_key">자동등록방지</label></legend>'; $html .= "\n" . '<legend><label for="captcha_key">자동등록방지</label></legend>';
if (is_mobile()) $html .= '<audio id="captcha_audio" controls></audio>'; if (is_mobile())
//$html .= "\n".'<img src="#" alt="" id="captcha_img">'; $html .= '<audio id="captcha_audio" controls></audio>';
$html .= "\n".'<img src="'.G5_CAPTCHA_URL.'/img/dot.gif" alt="" id="captcha_img">'; //$html .= "\n".'<img src="#" alt="" id="captcha_img">';
$html .= '<input type="text" name="captcha_key" id="captcha_key" required class="captcha_box required" size="6" maxlength="6">'; $html .= "\n" . '<img src="' . G5_CAPTCHA_URL . '/img/dot.gif" alt="" id="captcha_img">';
if (!is_mobile()) $html .= "\n".'<button type="button" id="captcha_mp3"><span></span>숫자음성듣기</button>'; $html .= '<input type="text" name="captcha_key" id="captcha_key" required class="captcha_box required" size="6" maxlength="6">';
$html .= "\n".'<button type="button" id="captcha_reload"><span></span>새로고침</button>'; if (!is_mobile())
$html .= "\n".'<span id="captcha_info">자동등록방지 숫자를 순서대로 입력하세요.</span>'; $html .= "\n" . '<button type="button" id="captcha_mp3"><span></span>숫자음성듣기</button>';
$html .= "\n".'</fieldset>'; $html .= "\n" . '<button type="button" id="captcha_reload"><span></span>새로고침</button>';
return $html; $html .= "\n" . '<span id="captcha_info">자동등록방지 숫자를 순서대로 입력하세요.</span>';
$html .= "\n" . '</fieldset>';
return $html;
} }
// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함 // 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함
function chk_captcha_js() function chk_captcha_js()
{ {
return "if (!chk_captcha()) return false;\n"; return "if (!chk_captcha()) return false;\n";
} }
// 세션에 저장된 캡챠값과 $_POST 로 넘어온 캡챠값을 비교 // 세션에 저장된 캡챠값과 $_POST 로 넘어온 캡챠값을 비교
function chk_captcha() function chk_captcha()
{ {
$captcha_count = (int)get_session('ss_captcha_count'); $captcha_count = (int) get_session('ss_captcha_count');
if ($captcha_count > 5) { if ($captcha_count > 5) {
return false; return false;
} }
$post_captcha_key = (isset($_POST['captcha_key']) && $_POST['captcha_key']) ? trim($_POST['captcha_key']) : ''; $post_captcha_key = (isset($_POST['captcha_key']) && $_POST['captcha_key']) ? trim($_POST['captcha_key']) : '';
if (!trim($post_captcha_key)) return false; if (!trim($post_captcha_key))
return false;
if( $post_captcha_key && function_exists('get_string_encrypt') ){ if ($post_captcha_key && function_exists('get_string_encrypt')) {
$ip = md5(sha1($_SERVER['REMOTE_ADDR'])); $ip = md5(sha1($_SERVER['REMOTE_ADDR']));
$post_captcha_key = get_string_encrypt($ip.$post_captcha_key); $post_captcha_key = get_string_encrypt($ip . $post_captcha_key);
} }
if ($post_captcha_key != get_session('ss_captcha_key')) { if ($post_captcha_key != get_session('ss_captcha_key')) {
$_SESSION['ss_captcha_count'] = $captcha_count + 1; $_SESSION['ss_captcha_count'] = $captcha_count + 1;
return false; return false;
} }
return true; return true;
} }

View file

@ -28,9 +28,9 @@ $fluctuation_amplitude = 5; // 파동&진폭 원래대로 151029 15:00
#noise #noise
//$white_noise_density=0; // no white noise //$white_noise_density=0; // no white noise
$white_noise_density=1/6; $white_noise_density = 1 / 6;
//$black_noise_density=0; // no black noise //$black_noise_density=0; // no black noise
$black_noise_density=1/20; $black_noise_density = 1 / 20;
# increase safety by prevention of spaces between symbols # increase safety by prevention of spaces between symbols
$no_spaces = false; $no_spaces = false;

View file

@ -5,12 +5,13 @@ include_once "captcha.lib.php";
$captcha = new KCAPTCHA(); $captcha = new KCAPTCHA();
$ss_captcha_key = get_session("ss_captcha_key"); $ss_captcha_key = get_session("ss_captcha_key");
$ss_captcha_key_decrypt = ''; $ss_captcha_key_decrypt = '';
if( $ss_captcha_key && !preg_match('/^[0-9]/', $ss_captcha_key) && function_exists('get_string_decrypt') ){ if ($ss_captcha_key && !preg_match('/^[0-9]/', $ss_captcha_key) && function_exists('get_string_decrypt')) {
$ip = md5(sha1($_SERVER['REMOTE_ADDR'])); $ip = md5(sha1($_SERVER['REMOTE_ADDR']));
$ss_captcha_key_decrypt = str_replace($ip, '', get_string_decrypt($ss_captcha_key)); $ss_captcha_key_decrypt = str_replace($ip, '', get_string_decrypt($ss_captcha_key));
} }
# php 5.2 또는 5.3 버전에서 포인터처럼 해당 세션값이 변경되는 버그가 있어서 아래와 같이 조치함 # php 5.2 또는 5.3 버전에서 포인터처럼 해당 세션값이 변경되는 버그가 있어서 아래와 같이 조치함
if(! $ss_captcha_key_decrypt) $ss_captcha_key_decrypt = $ss_captcha_key; if (!$ss_captcha_key_decrypt)
$ss_captcha_key_decrypt = $ss_captcha_key;
$captcha->setKeyString($ss_captcha_key_decrypt); $captcha->setKeyString($ss_captcha_key_decrypt);
$captcha->getKeyString(); $captcha->getKeyString();
$captcha->image(); $captcha->image();

View file

@ -3,47 +3,49 @@ include_once "_common.php";
function make_mp3() function make_mp3()
{ {
global $config; global $config;
$number = get_session("ss_captcha_key"); $number = get_session("ss_captcha_key");
if ($number == "") return; if ($number == "")
$ip = md5(sha1($_SERVER['REMOTE_ADDR'])); return;
if( $number && function_exists('get_string_decrypt') ){ $ip = md5(sha1($_SERVER['REMOTE_ADDR']));
$number = str_replace($ip, '', get_string_decrypt($number)); if ($number && function_exists('get_string_decrypt')) {
$number = str_replace($ip, '', get_string_decrypt($number));
}
if ($number == get_session("ss_captcha_save"))
return;
$mp3s = array();
for ($i = 0; $i < strlen($number); $i++) {
$file = G5_CAPTCHA_PATH . '/mp3/' . $config['cf_captcha_mp3'] . '/' . $number[$i] . '.mp3';
$mp3s[] = $file;
}
$mp3_file = 'cache/kcaptcha-' . $ip . '_' . G5_SERVER_TIME . '.mp3';
$contents = '';
foreach ($mp3s as $mp3) {
$contents .= file_get_contents($mp3);
}
file_put_contents(G5_DATA_PATH . '/' . $mp3_file, $contents);
// 지난 캡챠 파일 삭제
if (rand(0, 99) == 0) {
foreach (glob(G5_DATA_PATH . '/cache/kcaptcha-*.mp3') as $file) {
if (filemtime($file) + 86400 < G5_SERVER_TIME) {
@unlink($file);
}
} }
if ($number == get_session("ss_captcha_save")) return; }
$mp3s = array(); if ($number && function_exists('get_string_encrypt')) {
for($i=0;$i<strlen($number);$i++){ $number = get_string_encrypt($ip . $number);
$file = G5_CAPTCHA_PATH.'/mp3/'.$config['cf_captcha_mp3'].'/'.$number[$i].'.mp3'; }
$mp3s[] = $file; set_session("ss_captcha_save", $number);
}
$mp3_file = 'cache/kcaptcha-'.$ip.'_'.G5_SERVER_TIME.'.mp3'; return G5_DATA_URL . '/' . $mp3_file;
$contents = '';
foreach ($mp3s as $mp3) {
$contents .= file_get_contents($mp3);
}
file_put_contents(G5_DATA_PATH.'/'.$mp3_file, $contents);
// 지난 캡챠 파일 삭제
if (rand(0,99) == 0) {
foreach (glob(G5_DATA_PATH.'/cache/kcaptcha-*.mp3') as $file) {
if (filemtime($file) + 86400 < G5_SERVER_TIME) {
@unlink($file);
}
}
}
if( $number && function_exists('get_string_encrypt') ){
$number = get_string_encrypt($ip.$number);
}
set_session("ss_captcha_save", $number);
return G5_DATA_URL.'/'.$mp3_file;
} }
echo make_mp3(); echo make_mp3();

View file

@ -4,15 +4,15 @@ include_once "_common.php";
$captcha_key = isset($_POST['captcha_key']) ? $_POST['captcha_key'] : ''; $captcha_key = isset($_POST['captcha_key']) ? $_POST['captcha_key'] : '';
$count = (int)get_session("ss_captcha_count"); $count = (int) get_session("ss_captcha_count");
if ($count >= 5) { // 설정값 이상이면 자동등록방지 입력 문자가 맞아도 오류 처리 if ($count >= 5) { // 설정값 이상이면 자동등록방지 입력 문자가 맞아도 오류 처리
echo false; echo false;
} else { } else {
set_session("ss_captcha_count", $count + 1); set_session("ss_captcha_count", $count + 1);
if( $captcha_key && function_exists('get_string_encrypt') ){ if ($captcha_key && function_exists('get_string_encrypt')) {
$ip = md5(sha1($_SERVER['REMOTE_ADDR'])); $ip = md5(sha1($_SERVER['REMOTE_ADDR']));
$captcha_key = get_string_encrypt($ip.$captcha_key); $captcha_key = get_string_encrypt($ip . $captcha_key);
} }
echo (get_session("ss_captcha_key") === $captcha_key) ? true : false; echo (get_session("ss_captcha_key") === $captcha_key) ? true : false;
} }