Project

General

Profile

Download (12.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * notices.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2005 Colin Smith (ethethlay@gmail.com)
7
 * Copyright (c) 2005-2016 Rubicon Communications, LLC (Netgate)
8
 * All rights reserved.
9
 *
10
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13
 *
14
 * http://www.apache.org/licenses/LICENSE-2.0
15
 *
16
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21
 */
22

    
23
require_once("globals.inc");
24
require_once("functions.inc");
25
require_once("led.inc");
26

    
27
$notice_path = $g['tmp_path'] . '/notices';
28
$smtp_authentication_mechanisms = array(
29
	'PLAIN' => 'PLAIN',
30
	'LOGIN' => 'LOGIN');
31
/* Other SMTP Authentication Mechanisms that could be supported.
32
 * Note that MD5 is no longer considered secure.
33
 *	'GSSAPI' => 'GSSAPI ' . gettext("Generic Security Services Application Program Interface")
34
 *	'DIGEST-MD5' => 'DIGEST-MD5 ' . gettext("Digest access authentication")
35
 *	'MD5' => 'MD5'
36
 *	'CRAM-MD5' => 'CRAM-MD5'
37
*/
38

    
39
/****f* notices/file_notice
40
 * NAME
41
 *   file_notice
42
 * INPUTS
43
 *	 $id, $notice, $category, $url, $priority, $local_only
44
 * RESULT
45
 *   Files a notice and kicks off the various alerts, smtp, growl, system log, LED's, etc.
46
 *   If $local_only is true then the notice is not sent to external places (smtp, growl)
47
 ******/
48
function file_notice($id, $notice, $category = "General", $url = "", $priority = 1, $local_only = false) {
49
	/*
50
	 * $category - Category that this notice should be displayed under. This can be arbitrary,
51
	 * 	       but a page must be set to receive this messages for it to be displayed.
52
	 *
53
	 * $priority - A notice's priority. Higher numbers indicate greater severity.
54
	 *	       0 = informational, 1 = warning, 2 = error, etc. This may also be arbitrary,
55
	 */
56
	global $notice_path;
57
	if (!$queue = get_notices()) {
58
		$queue = array();
59
	}
60
	$queuekey = time();
61
	$toqueue = array(
62
				'id'		=> htmlentities($id),
63
				'notice'	=> htmlentities($notice),
64
				'url'		=> htmlentities($url),
65
				'category'	=> htmlentities($category),
66
				'priority'	=> htmlentities($priority),
67
			);
68
	while (isset($queue[$queuekey])) {
69
		$queuekey++;
70
	}
71
	$queue[$queuekey] = $toqueue;
72
	$queueout = fopen($notice_path, "w");
73
	if (!$queueout) {
74
		log_error(sprintf(gettext("Could not open %s for writing"), $notice_path));
75
		return;
76
	}
77
	fwrite($queueout, serialize($queue));
78
	fclose($queueout);
79
	log_error(sprintf(gettext("New alert found: %s"), $notice));
80
	/* soekris */
81
	if (file_exists("/dev/led/error")) {
82
		exec("/bin/echo 1 > /dev/led/error");
83
	}
84
	/* wrap & alix */
85
	led_normalize();
86
	led_morse(1, 'sos');
87
	if (!$local_only) {
88
		notify_via_growl($notice);
89
		notify_via_smtp($notice);
90
	}
91
	return $queuekey;
92
}
93

    
94
/****f* notices/get_notices
95
 * NAME
96
 *   get_notices
97
 * INPUTS
98
 *	 $category
99
 * RESULT
100
 *   Returns a specific notices text
101
 ******/
102
function get_notices($category = "all") {
103
	global $g;
104

    
105
	if (file_exists("{$g['tmp_path']}/notices")) {
106
		$queue = unserialize(file_get_contents("{$g['tmp_path']}/notices"));
107
		if (!$queue) {
108
			return false;
109
		}
110
		if ($category != 'all') {
111
			foreach ($queue as $time => $notice) {
112
				if (strtolower($notice['category']) == strtolower($category)) {
113
					$toreturn[$time] = $notice;
114
				}
115
			}
116
			return $toreturn;
117
		} else {
118
			return $queue;
119
		}
120
	} else {
121
		return false;
122
	}
123
}
124

    
125
/****f* notices/close_notice
126
 * NAME
127
 *   close_notice
128
 * INPUTS
129
 *	 $id
130
 * RESULT
131
 *   Removes a notice from the list
132
 ******/
133
function close_notice($id) {
134
	global $notice_path;
135
	require_once("util.inc");
136
	/* soekris */
137
	if (file_exists("/dev/led/error")) {
138
		exec("/bin/echo 0 > /dev/led/error");
139
	}
140
	/* wrap & alix */
141
	led_normalize();
142
	$ids = array();
143
	if (!$notices = get_notices()) {
144
		return;
145
	}
146
	if ($id == "all") {
147
		unlink_if_exists($notice_path);
148
		return;
149
	}
150
	foreach (array_keys($notices) as $time) {
151
		if ($id == $time) {
152
			unset($notices[$id]);
153
			break;
154
		}
155
	}
156
	foreach ($notices as $key => $notice) {
157
		$ids[$key] = $notice['id'];
158
	}
159
	foreach ($ids as $time => $tocheck) {
160
		if ($id == $tocheck) {
161
			unset($notices[$time]);
162
			break;
163
		}
164
	}
165
	if (count($notices) != 0) {
166
		$queueout = fopen($notice_path, "w");
167
		fwrite($queueout, serialize($notices));
168
		fclose($queueout);
169
	} else {
170
		unlink_if_exists($notice_path);
171
	}
172

    
173
	return;
174
}
175

    
176
/****f* notices/dump_xml_notices
177
 * NAME
178
 *   dump_xml_notices
179
 * INPUTS
180
 *	 NONE
181
 * RESULT
182
 *   Outputs notices in XML formatted text
183
 ******/
184
function dump_xml_notices() {
185
	if (file_exists("/cf/conf/use_xmlreader")) {
186
		require_once("xmlreader.inc");
187
	} else {
188
		require_once("xmlparse.inc");
189
	}
190
	global $notice_path, $listtags;
191
	$listtags[] = 'notice';
192
	if (!$notices = get_notices()) {
193
		return;
194
	}
195
	foreach ($notices as $time => $notice) {
196
		$notice['time'] = $time;
197
		$toput['notice'][] = $notice;
198
	}
199
	$xml = dump_xml_config($toput, 'notices');
200
	return $xml;
201
}
202

    
203
/****f* notices/print_notices
204
 * NAME
205
 *   print_notices
206
 * INPUTS
207
 *	 $notices, $category
208
 * RESULT
209
 *   prints notices to the GUI
210
 ******/
211
function print_notices($notices, $category = "all") {
212
	foreach ($notices as $notice) {
213
		if ($category != "all") {
214
			if (in_array($notice['category'], $category)) {
215
				$categories[] = $notice['category'];
216
			}
217
		} else {
218
			$categories[] = $notice['category'];
219
		}
220
	}
221
	$categories = array_unique($categories);
222
	sort($categories);
223
	foreach ($categories as $category) {
224
		$toreturn .= "<ul><li>{$category}<ul>";
225
		foreach ($notices as $notice) {
226
			if (strtolower($notice['category']) == strtolower($category)) {
227
				if ($notice['id'] != "") {
228
					if ($notice['url'] != "") {
229
						$toreturn .= "<li><a href={$notice['url']}>{$notice['id']}</a> - {$notice['notice']}</li>";
230
					} else {
231
						$toreturn .= "<li>{$notice['id']} - {$notice['notice']}</li>";
232
					}
233
				}
234
			}
235
		}
236
		$toreturn .= "</ul></li></ul>";
237
	}
238
	return $toreturn;
239
}
240

    
241
/****f* notices/print_notice_box
242
 * NAME
243
 *   print_notice_box
244
 * INPUTS
245
 *	 $category
246
 * RESULT
247
 *   prints an info box to the GUI
248
 ******/
249
function print_notice_box($category = "all") {
250
	$notices = get_notices();
251
	if (!$notices) {
252
		return;
253
	}
254
	print_info_box(print_notices($notices, $category));
255
	return;
256
}
257

    
258
/****f* notices/are_notices_pending
259
 * NAME
260
 *   are_notices_pending
261
 * INPUTS
262
 *	 $category to check
263
 * RESULT
264
 *   returns true if notices are pending, false if they are not
265
 ******/
266
function are_notices_pending($category = "all") {
267
	global $notice_path;
268
	if (file_exists($notice_path)) {
269
		return true;
270
	}
271
	return false;
272
}
273

    
274
/****f* notices/notify_via_smtp
275
 * NAME
276
 *   notify_via_smtp
277
 * INPUTS
278
 *	 notification string to send as an email
279
 * RESULT
280
 *   returns true if message was sent
281
 ******/
282
function notify_via_smtp($message, $force = false) {
283
	global $config, $g;
284
	if (platform_booting()) {
285
		return;
286
	}
287

    
288
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
289
		return;
290
	}
291

    
292
	/* Do NOT send the same message twice, except if $force is true */
293
	if (!$force && file_exists("/var/db/notices_lastmsg.txt")) {
294
		$lastmsg = trim(file_get_contents("/var/db/notices_lastmsg.txt"));
295
		if ($lastmsg == $message) {
296
			return;
297
		}
298
	}
299

    
300
	/* Store last message sent to avoid spamming */
301
	$fd = fopen("/var/db/notices_lastmsg.txt", "w");
302
	fwrite($fd, $message);
303
	fclose($fd);
304

    
305
	return send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
306
}
307

    
308
function send_smtp_message($message, $subject = "(no subject)", $force = false) {
309
	global $config, $g;
310
	require_once("Mail.php");
311

    
312
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
313
		return;
314
	}
315

    
316
	if (!$config['notifications']['smtp']['ipaddress']) {
317
		return;
318
	}
319

    
320
	if (!$config['notifications']['smtp']['notifyemailaddress']) {
321
		return;
322
	}
323

    
324
	$to = $config['notifications']['smtp']['notifyemailaddress'];
325

    
326
	if (empty($config['notifications']['smtp']['username']) ||
327
	    empty($config['notifications']['smtp']['password'])) {
328
		$auth = false;
329
		$username = '';
330
		$password = '';
331
	} else {
332
		$auth = isset($config['notifications']['smtp']['authentication_mechanism'])
333
		    ? $config['notifications']['smtp']['authentication_mechanism']
334
		    : 'PLAIN';
335
		$username = $config['notifications']['smtp']['username'];
336
		$password = $config['notifications']['smtp']['password'];
337
	}
338

    
339
	$params = array(
340
		'host' => (isset($config['notifications']['smtp']['ssl'])
341
		    ? 'ssl://'
342
		    : '')
343
		    . $config['notifications']['smtp']['ipaddress'],
344
		'port' => empty($config['notifications']['smtp']['port'])
345
		    ? 25
346
		    : $config['notifications']['smtp']['port'],
347
		'auth' => $auth,
348
		'username' => $username,
349
		'password' => $password,
350
		'localhost' => $config['system']['hostname'] . "." .
351
		    $config['system']['domain'],
352
		'timeout' => !empty($config['notifications']['smtp']['timeout'])
353
		    ? $config['notifications']['smtp']['timeout']
354
		    : 20,
355
		'debug' => false,
356
		'persist' => false
357
	);
358

    
359
	if ($config['notifications']['smtp']['fromaddress']) {
360
		$from = $config['notifications']['smtp']['fromaddress'];
361
	} else {
362
		$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
363
	}
364

    
365
	$headers = array(
366
		"From"    => $from,
367
		"To"      => $to,
368
		"Subject" => $subject,
369
		"Date"    => date("r")
370
	);
371

    
372
	$smtp =& Mail::factory('smtp', $params);
373
	$mail = $smtp->send($to, $headers, $message);
374

    
375
	if (PEAR::isError($mail)) {
376
		$err_msg = sprintf(gettext(
377
		    'Could not send the message to %1$s -- Error: %2$s'),
378
		    $to, $mail->getMessage());
379
		log_error($err_msg);
380
		return($err_msg);
381
	}
382

    
383
	log_error(sprintf(gettext("Message sent to %s OK"), $to));
384
	return;
385
}
386

    
387
/****f* notices/notify_via_growl
388
 * NAME
389
 *   notify_via_growl
390
 * INPUTS
391
 *	 notification string to send
392
 * RESULT
393
 *   returns true if message was sent
394
 ******/
395
function notify_via_growl($message, $force=false) {
396
	require_once("Net/Growl/Autoload.php");
397

    
398
	global $config, $g;
399

    
400
	if (isset($config['notifications']['growl']['disable']) && !$force) {
401
		return;
402
	}
403

    
404
	if (empty($config['notifications']['growl']['ipaddress'])) {
405
		return;
406
	}
407

    
408
	/* Do NOT send the same message twice */
409
	if (file_exists("/var/db/growlnotices_lastmsg.txt")) {
410
		$lastmsg = trim(file_get_contents("/var/db/growlnotices_lastmsg.txt"));
411
		if ($lastmsg == $message) {
412
			return;
413
		}
414
	}
415

    
416
	$ip = $config['notifications']['growl']['ipaddress'];
417

    
418
	if (!is_ipaddr($ip) && !(dns_check_record($ip, A) || dns_check_record($ip, AAAA))) {
419
		$err_msg = gettext(
420
		    "Growl IP Address is invalid. Check the setting in System Advanced Notifications.");
421
		log_error($err_msg);
422
		return($err_msg);
423
	}
424

    
425
	$hostname = $config['system']['hostname'] . "." . $config['system']['domain'];
426
	$password = $config['notifications']['growl']['password'];
427
	$name = $config['notifications']['growl']['name'];
428
	$notification = $config['notifications']['growl']['notification_name'];
429

    
430
	$options  = array(
431
		'host' => $ip,
432
		'protocol' => 'gntp',
433
		'timeout' => 20
434
	);
435

    
436
	try {
437
		$growl = Net_Growl::singleton($name, null, $password, $options);
438
		//$name = 'GROWL_NOTIFY_STATUS';
439
		$title = sprintf(gettext("%s (%s) - Notification"), $g['product_name'], $hostname);
440
		$growl->publish($name, $title, $message);
441
	} catch (Net_Growl_Exception $e) {
442
		$err_msg = sprintf(gettext(
443
		    'Could not send Growl notification to %1$s -- Error: %2$s'),
444
		    $ip, $e->getMessage());
445
		log_error($err_msg);
446
		return($err_msg);
447
	}
448

    
449
	/* Store last message sent to avoid spamming */
450
	@file_put_contents("/var/db/growlnotices_lastmsg.txt", $message);
451

    
452
	return;
453
}
454

    
455
/****f* notices/register_via_growl
456
 * NAME
457
 *   register_via_growl
458
 * INPUTS
459
 *	 none
460
 * RESULT
461
 *   none
462
 ******/
463
function register_via_growl() {
464
	require_once("Net/Growl/Autoload.php");
465

    
466
	global $config;
467

    
468
	if (empty($config['notifications']['growl']['ipaddress'])) {
469
		return;
470
	}
471

    
472
	$ip = $config['notifications']['growl']['ipaddress'];
473

    
474
	if (!is_ipaddr($ip) && !(dns_check_record($ip, A) || dns_check_record($ip, AAAA))) {
475
		$err_msg = gettext(
476
		    "Growl IP Address is invalid. Check the setting in System Advanced Notifications.");
477
		log_error($err_msg);
478
		return($err_msg);
479
	}
480

    
481
	$name = $config['notifications']['growl']['name'];
482
	$password = $config['notifications']['growl']['password'];
483

    
484
	$app = new Net_Growl_Application(
485
		$name,
486
		null,
487
		$password
488
	);
489

    
490
	$options = array(
491
		'host' => $ip,
492
		'protocol' => 'gntp',
493
		'timeout' => 20
494
	);
495

    
496
	try {
497
		$growl = Net_Growl::singleton($app, null, null, $options);
498
		$growl->register();
499
	} catch (Net_Growl_Exception $e) {
500
		$err_msg = sprintf(gettext(
501
		    'Could not send register Growl on %1$s -- Error: %2$s'),
502
		    $ip, $e->getMessage());
503
		log_error($err_msg);
504
		return($err_msg);
505
	}
506

    
507
	return;
508
}
509

    
510
/* Notify via remote methods only - not via GUI. */
511
function notify_all_remote($msg) {
512
	notify_via_smtp($msg);
513
	notify_via_growl($msg);
514
}
515

    
516
?>
(25-25/51)