Skip to content

Commit 959f5b7

Browse files
committed
Add more ways for logs to be sent
1 parent dfa14ea commit 959f5b7

2 files changed

Lines changed: 132 additions & 3 deletions

File tree

docs/authproc_fticks.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ The filter supports the following configuration options:
2828
`exclude`
2929
: An array of F-ticks attributes to exclude/filter from the output.
3030

31+
`logdest`
32+
: Destination for F-ticks logs. Must be one of the following options:
33+
* `simplesamlphp` - use SimpleSAMLphp's built-in logging mechanism (this is the default).
34+
* `local` - log using the PHP [syslog](http://php.net/manual/en/function.syslog.php) functions, potentially avoiding some of the extra information SimpleSAMLphp includes in logs.
35+
* `remote` - log to a remote RFC 5424 syslog server using UDP.
36+
* `errorlog` - log using PHP's [error_log](http://php.net/manual/en/function.error-log.php) function, probably into the web server logs.
37+
* `stdout` - write to standard out, primarily for debugging.
38+
39+
`logconfig`
40+
: An array of configuration options for the logging method. The exact values supported depend on the specific `logdest`, but the following are understood:
41+
* `priority` - the syslog priority or severity as a PHP constant, defaulting to `LOG_INFO`. _[local, remote]_
42+
* `facility` - the syslog facility, defaulting to `logging.facility` from the main config. _[local, remote]_
43+
* `processname` - the syslog process name, defaulting to `logging.processname` from the main config. _[local, remote]_
44+
* `host` - the hostname of the remote syslog server, defaulting to `localhost`. _[remote]_
45+
* `port` - the port of the remote syslog server, defaulting to `514`. _[remote]_
46+
3147
Examples
3248
--------
3349

@@ -54,6 +70,20 @@ A more complete example looks like:
5470
),
5571
),
5672

73+
Remote logging can be done like this:
74+
75+
'authproc' => array(
76+
50 => array(
77+
'class' => 'fticks:Fticks',
78+
'federation' => 'ACME',
79+
'logdest' => 'remote',
80+
'logconfig' => array(
81+
'host' => '90.147.166.156',
82+
'port' => 514,
83+
),
84+
),
85+
),
86+
5787
F-ticks output
5888
--------------
5989

lib/Auth/Process/Fticks.php

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ class sspmod_fticks_Auth_Process_Fticks extends SimpleSAML_Auth_ProcessingFilter
2020
/** @var string A salt to apply when digesting usernames (defaults to config file salt) */
2121
private $salt;
2222

23+
/** @var string The logging backend */
24+
private $logdest = 'simplesamlphp';
25+
26+
/** @var string Backend specific logging config */
27+
private $logconfig = array();
28+
2329
/** @var string The username attribute to use */
2430
private $userId = false;
2531

@@ -32,6 +38,67 @@ class sspmod_fticks_Auth_Process_Fticks extends SimpleSAML_Auth_ProcessingFilter
3238
/** @var array F-ticks attributes to exclude */
3339
private $exclude = array();
3440

41+
42+
/**
43+
* Log a message to the desired destination
44+
*
45+
* @param string $msg message to log
46+
*/
47+
private function _log($msg)
48+
{
49+
switch ($this->logdest) {
50+
/* local syslog call, avoiding SimpleSAMLphp's wrapping */
51+
case 'local':
52+
case 'syslog':
53+
assert('array_key_exists("processname", $this->logconfig)');
54+
assert('array_key_exists("facility", $this->logconfig)');
55+
openlog($this->logconfig['processname'], LOG_PID, $this->logconfig['facility']);
56+
syslog(array_key_exists('priority', $this->logconfig) ? $this->logconfig['priority'] : LOG_INFO, $msg);
57+
break;
58+
59+
/* remote syslog call via UDP */
60+
case 'remote':
61+
assert('array_key_exists("processname", $this->logconfig)');
62+
assert('array_key_exists("facility", $this->logconfig)');
63+
/* assemble a syslog message per RFC 5424 */
64+
$rfc5424_message = sprintf('<%d>', ((($this->logconfig['facility'] & 0x03f8) >> 3) * 8) + (array_key_exists('priority', $this->logconfig) ? $this->logconfig['priority'] : LOG_INFO)); // pri
65+
$rfc5424_message .= '1 '; // ver
66+
$rfc5424_message .= gmdate('Y-m-d\TH:i:s.v\Z '); // timestamp
67+
$rfc5424_message .= gethostname() . ' '; // hostname
68+
$rfc5424_message .= $this->logconfig['processname'] . ' '; // app-name
69+
$rfc5424_message .= posix_getpid() . ' '; // procid
70+
$rfc5424_message .= '- '; // msgid
71+
$rfc5424_message .= '- '; // structured-data
72+
$rfc5424_message .= $msg;
73+
/* send it to the remote host */
74+
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
75+
socket_sendto(
76+
$sock,
77+
$rfc5424_message,
78+
strlen($rfc5424_message),
79+
0,
80+
gethostbyname(array_key_exists('host', $this->logconfig) ? $this->logconfig['host'] : 'localhost'),
81+
array_key_exists('port', $this->logconfig) ? $this->logconfig['port'] : 514
82+
);
83+
break;
84+
85+
case 'errorlog':
86+
error_log($msg);
87+
break;
88+
89+
/* mostly for unit testing */
90+
case 'stdout':
91+
echo $msg . "\n";
92+
break;
93+
94+
/* SimpleSAMLphp's builtin logging */
95+
case 'simplesamlphp':
96+
default:
97+
\SimpleSAML\Logger::stats($msg);
98+
break;
99+
}
100+
}
101+
35102
/**
36103
* Generate a PN hash
37104
*
@@ -69,7 +136,7 @@ private function _generatePNhash(&$state) {
69136
}
70137
return false;
71138
}
72-
139+
73140
/**
74141
* Escape F-ticks values
75142
*
@@ -148,7 +215,38 @@ public function __construct($config, $reserved)
148215
} elseif (is_string($config['exclude'])) {
149216
$this->exclude = array($config['exclude']);
150217
} else {
151-
throw new \SimpleSAML\Error\Exception('exclude must be an array');
218+
throw new \SimpleSAML\Error\Exception('F-ticks exclude must be an array');
219+
}
220+
}
221+
222+
/* match SSP config or we risk mucking up the openlog call */
223+
$globalConfig = \SimpleSAML_Configuration::getInstance();
224+
$defaultFacility = $globalConfig->getInteger('logging.facility', defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER);
225+
$defaultProcessName = $globalConfig->getString('logging.processname', 'SimpleSAMLphp');
226+
if (array_key_exists('logconfig', $config)) {
227+
if (is_array($config['logconfig'])) {
228+
$this->logconfig = $config['logconfig'];
229+
} else {
230+
throw new \SimpleSAML\Error\Exception('F-ticks logconfig must be an array');
231+
}
232+
} else {
233+
$this->logconfig['facility'] = $defaultFacility;
234+
$this->logconfig['processname'] = $defaultProcessName;
235+
}
236+
if (array_key_exists('facility', $this->logconfig) and $this->logconfig['facility'] !== $defaultFacility) {
237+
\SimpleSAML\Logger::warning('F-ticks syslog facility differs from global config');
238+
}
239+
if (array_key_exists('processname', $this->logconfig) and $this->logconfig['processname'] !== $defaultProcessName) {
240+
\SimpleSAML\Logger::warning('F-ticks syslog processname differs from global config');
241+
}
242+
243+
if (array_key_exists('logdest', $config)) {
244+
if (is_string($config['logdest']) and
245+
in_array($config['logdest'], array('local', 'remote', 'stdout', 'errorlog', 'simplesamlphp'))
246+
) {
247+
$this->logdest = $config['logdest'];
248+
} else {
249+
throw new \SimpleSAML\Error\Exception('F-ticks log destination must be one of [local, remote, stdout, errorlog, simplesamlphp]');
152250
}
153251
}
154252
}
@@ -229,7 +327,8 @@ function($k) {
229327
);
230328
}
231329

232-
\SimpleSAML\Logger::stats(
330+
/* assemble an F-ticks log string */
331+
$this->_log(
233332
'F-TICKS/'.$this->federation.'/'.self::$_fticksVersion.'#' .
234333
implode('#', array_map(
235334
function($k, $v) {

0 commit comments

Comments
 (0)