Project

General

Profile

Download (12.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/notices
3
	NAME
4
		notices.inc - pfSense notice utilities
5
	DESCRIPTION
6
		This include contains the pfSense notice facilities.
7
	HISTORY
8
		$Id$
9

    
10
	Copyright (C) 2009 Scott Ullrich (sullrich@gmail.com)
11
	Copyright (C) 2005 Colin Smith (ethethlay@gmail.com)
12
	All rights reserved.
13
	Redistribution and use in source and binary forms, with or without
14
	modification, are permitted provided that the following conditions are met:
15

    
16
	1. Redistributions of source code must retain the above copyright notice,
17
	   this list of conditions and the following disclaimer.
18

    
19
	2. Redistributions in binary form must reproduce the above copyright
20
	   notice, this list of conditions and the following disclaimer in the
21
	   documentation and/or other materials provided with the distribution.
22

    
23
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
	RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
	POSSIBILITY OF SUCH DAMAGE.
33
 */
34

    
35
/*
36
	pfSense_BUILDER_BINARIES:	/bin/echo
37
	pfSense_MODULE:	notifications
38
*/
39

    
40
require_once("globals.inc");
41
require_once("led.inc");
42

    
43
$notice_path = $g['tmp_path'] . '/notices';
44
$smtp_authentication_mechanisms = array(
45
	'PLAIN' => 'PLAIN',
46
	'LOGIN' => 'LOGIN');
47
/* Other SMTP Authentication Mechanisms that could be supported.
48
 * Note that MD5 is no longer considered secure.
49
 *	'GSSAPI' => 'GSSAPI ' . gettext("Generic Security Services Application Program Interface")
50
 *	'DIGEST-MD5' => 'DIGEST-MD5 ' . gettext("Digest access authentication")
51
 *	'MD5' => 'MD5'
52
 *	'CRAM-MD5' => 'CRAM-MD5'
53
*/
54

    
55
/****f* notices/file_notice
56
 * NAME
57
 *   file_notice
58
 * INPUTS
59
 *	 $id, $notice, $category, $url, $priority
60
 * RESULT
61
 *   Files a notice and kicks off the various alerts, smtp, growl, system log, LED's, etc.
62
 ******/
63
function file_notice($id, $notice, $category = "General", $url = "", $priority = 1) {
64
	/*
65
	 * $category - Category that this notice should be displayed under. This can be arbitrary,
66
	 * 	       but a page must be set to receive this messages for it to be displayed.
67
	 *
68
	 * $priority - A notice's priority. Higher numbers indicate greater severity.
69
	 *	       0 = informational, 1 = warning, 2 = error, etc. This may also be arbitrary,
70
	 */
71
	global $notice_path;
72
	if (!$queue = get_notices()) {
73
		$queue = array();
74
	}
75
	$queuekey = time();
76
	$toqueue = array(
77
				'id'		=> $id,
78
				'notice'	=> $notice,
79
				'url'		=> $url,
80
				'category'	=> $category,
81
				'priority'	=> $priority,
82
			);
83
	while (isset($queue[$queuekey])) {
84
		$queuekey++;
85
	}
86
	$queue[$queuekey] = $toqueue;
87
	$queueout = fopen($notice_path, "w");
88
	if (!$queueout) {
89
		log_error(printf(gettext("Could not open %s for writing"), $notice_path));
90
		return;
91
	}
92
	fwrite($queueout, serialize($queue));
93
	fclose($queueout);
94
	log_error("New alert found: $notice");
95
	/* soekris */
96
	if (file_exists("/dev/led/error")) {
97
		exec("/bin/echo 1 > /dev/led/error");
98
	}
99
	/* wrap & alix */
100
	led_normalize();
101
	led_morse(1, 'sos');
102
	notify_via_growl($notice);
103
	notify_via_smtp($notice);
104
	return $queuekey;
105
}
106

    
107
/****f* notices/get_notices
108
 * NAME
109
 *   get_notices
110
 * INPUTS
111
 *	 $category
112
 * RESULT
113
 *   Returns a specific notices text
114
 ******/
115
function get_notices($category = "all") {
116
	global $g;
117

    
118
	if (file_exists("{$g['tmp_path']}/notices")) {
119
		$queue = unserialize(file_get_contents("{$g['tmp_path']}/notices"));
120
		if (!$queue) {
121
			return false;
122
		}
123
		if ($category != 'all') {
124
			foreach ($queue as $time => $notice) {
125
				if (strtolower($notice['category']) == strtolower($category)) {
126
					$toreturn[$time] = $notice;
127
				}
128
			}
129
			return $toreturn;
130
		} else {
131
			return $queue;
132
		}
133
	} else {
134
		return false;
135
	}
136
}
137

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

    
186
	return;
187
}
188

    
189
/****f* notices/dump_xml_notices
190
 * NAME
191
 *   dump_xml_notices
192
 * INPUTS
193
 *	 NONE
194
 * RESULT
195
 *   Outputs notices in XML formatted text
196
 ******/
197
function dump_xml_notices() {
198
	if (file_exists("/cf/conf/use_xmlreader")) {
199
		require_once("xmlreader.inc");
200
	} else {
201
		require_once("xmlparse.inc");
202
	}
203
	global $notice_path, $listtags;
204
	$listtags[] = 'notice';
205
	if (!$notices = get_notices()) {
206
		return;
207
	}
208
	foreach ($notices as $time => $notice) {
209
		$notice['time'] = $time;
210
		$toput['notice'][] = $notice;
211
	}
212
	$xml = dump_xml_config($toput, 'notices');
213
	return $xml;
214
}
215

    
216
/****f* notices/print_notices
217
 * NAME
218
 *   print_notices
219
 * INPUTS
220
 *	 $notices, $category
221
 * RESULT
222
 *   prints notices to the GUI
223
 ******/
224
function print_notices($notices, $category = "all") {
225
	foreach ($notices as $notice) {
226
		if ($category != "all") {
227
			if (in_array($notice['category'], $category)) {
228
				$categories[] = $notice['category'];
229
			}
230
		} else {
231
			$categories[] = $notice['category'];
232
		}
233
	}
234
	$categories = array_unique($categories);
235
	sort($categories);
236
	foreach ($categories as $category) {
237
		$toreturn .= "<ul><li>{$category}<ul>";
238
		foreach ($notices as $notice) {
239
			if (strtolower($notice['category']) == strtolower($category)) {
240
				if ($notice['id'] != "") {
241
					if ($notice['url'] != "") {
242
						$toreturn .= "<li><a href={$notice['url']}>{$notice['id']}</a> - {$notice['notice']}</li>";
243
					} else {
244
						$toreturn .= "<li>{$notice['id']} - {$notice['notice']}</li>";
245
					}
246
				}
247
			}
248
		}
249
		$toreturn .= "</ul></li></ul>";
250
	}
251
	return $toreturn;
252
}
253

    
254
/****f* notices/print_notice_box
255
 * NAME
256
 *   print_notice_box
257
 * INPUTS
258
 *	 $category
259
 * RESULT
260
 *   prints an info box to the GUI
261
 ******/
262
function print_notice_box($category = "all") {
263
	$notices = get_notices();
264
	if (!$notices) {
265
		return;
266
	}
267
	print_info_box_np(print_notices($notices, $category));
268
	return;
269
}
270

    
271
/****f* notices/are_notices_pending
272
 * NAME
273
 *   are_notices_pending
274
 * INPUTS
275
 *	 $category to check
276
 * RESULT
277
 *   returns true if notices are pending, false if they are not
278
 ******/
279
function are_notices_pending($category = "all") {
280
	global $notice_path;
281
	if (file_exists($notice_path)) {
282
		return true;
283
	}
284
	return false;
285
}
286

    
287
/****f* notices/notify_via_smtp
288
 * NAME
289
 *   notify_via_smtp
290
 * INPUTS
291
 *	 notification string to send as an email
292
 * RESULT
293
 *   returns true if message was sent
294
 ******/
295
function notify_via_smtp($message, $force = false) {
296
	global $config, $g;
297
	if (platform_booting()) {
298
		return;
299
	}
300

    
301
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
302
		return;
303
	}
304

    
305
	/* Do NOT send the same message twice */
306
	if (file_exists("/var/db/notices_lastmsg.txt")) {
307
		$lastmsg = trim(file_get_contents("/var/db/notices_lastmsg.txt"));
308
		if ($lastmsg == $message) {
309
			return;
310
		}
311
	}
312

    
313
	/* Store last message sent to avoid spamming */
314
	$fd = fopen("/var/db/notices_lastmsg.txt", "w");
315
	fwrite($fd, $message);
316
	fclose($fd);
317

    
318
	send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
319
	return;
320
}
321

    
322
function send_smtp_message($message, $subject = "(no subject)", $force = false) {
323
	global $config, $g;
324
	require_once("sasl.inc");
325
	require_once("smtp.inc");
326

    
327
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
328
		return;
329
	}
330

    
331
	if (!$config['notifications']['smtp']['ipaddress']) {
332
		return;
333
	}
334

    
335
	if (!$config['notifications']['smtp']['notifyemailaddress']) {
336
		return;
337
	}
338

    
339
	$smtp = new smtp_class;
340

    
341
	$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
342
	$to = $config['notifications']['smtp']['notifyemailaddress'];
343

    
344
	$smtp->host_name = $config['notifications']['smtp']['ipaddress'];
345
	$smtp->host_port = empty($config['notifications']['smtp']['port']) ? 25 : $config['notifications']['smtp']['port'];
346

    
347
	$smtp->direct_delivery = 0;
348
	$smtp->ssl = (isset($config['notifications']['smtp']['ssl'])) ? 1 : 0;
349
	$smtp->tls = (isset($config['notifications']['smtp']['tls'])) ? 1 : 0;
350
	$smtp->debug = 0;
351
	$smtp->html_debug = 0;
352
	$smtp->localhost = $config['system']['hostname'] . "." . $config['system']['domain'];
353

    
354
	if ($config['notifications']['smtp']['fromaddress']) {
355
		$from = $config['notifications']['smtp']['fromaddress'];
356
	}
357

    
358
	// Use SMTP Auth if fields are filled out
359
	if ($config['notifications']['smtp']['username'] &&
360
	    $config['notifications']['smtp']['password']) {
361
		if (isset($config['notifications']['smtp']['authentication_mechanism'])) {
362
			$smtp->authentication_mechanism = $config['notifications']['smtp']['authentication_mechanism'];
363
		} else {
364
			$smtp->authentication_mechanism = "PLAIN";
365
		}
366
		$smtp->user = $config['notifications']['smtp']['username'];
367
		$smtp->password = $config['notifications']['smtp']['password'];
368
	}
369

    
370
	$headers = array(
371
		"From: {$from}",
372
		"To: {$to}",
373
		"Subject: {$subject}",
374
		"Date: " . date("r")
375
	);
376

    
377
	if ($smtp->SendMessage($from, preg_split('/\s*,\s*/', trim($to)), $headers, $message)) {
378
		log_error(sprintf(gettext("Message sent to %s OK"), $to));
379
		return;
380
	} else {
381
		log_error(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
382
		return(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
383
	}
384
}
385

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

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

    
402
	/* Do NOT send the same message twice */
403
	if (file_exists("/var/db/growlnotices_lastmsg.txt")) {
404
		$lastmsg = trim(file_get_contents("/var/db/growlnotices_lastmsg.txt"));
405
		if ($lastmsg == $message) {
406
			return;
407
		}
408
	}
409

    
410
	$hostname = $config['system']['hostname'] . "." . $config['system']['domain'];
411
	$growl_ip = $config['notifications']['growl']['ipaddress'];
412
	$growl_password = $config['notifications']['growl']['password'];
413
	$growl_name = $config['notifications']['growl']['name'];
414
	$growl_notification = $config['notifications']['growl']['notification_name'];
415

    
416
	if (!empty($growl_ip) && (is_ipaddr($growl_ip) || dns_get_record($growl_ip, DNS_A) || dns_get_record($growl_ip, DNS_AAAA))) {
417
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
418
		$growl->notify("{$growl_notification}", gettext(sprintf("%s (%s) - Notification", $g['product_name'], $hostname)), "{$message}");
419
	}
420

    
421
	/* Store last message sent to avoid spamming */
422
	$fd = fopen("/var/db/growlnotices_lastmsg.txt", "w");
423
	fwrite($fd, $message);
424
	fclose($fd);
425
}
426

    
427
/****f* notices/register_via_growl
428
 * NAME
429
 *   register_via_growl
430
 * INPUTS
431
 *	 none
432
 * RESULT
433
 *   none
434
 ******/
435
function register_via_growl() {
436
	require_once("growl.class");
437
	global $config;
438
	$growl_ip = $config['notifications']['growl']['ipaddress'];
439
	$growl_password = $config['notifications']['growl']['password'];
440
	$growl_name = $config['notifications']['growl']['name'];
441
	$growl_notification = $config['notifications']['growl']['notification_name'];
442

    
443
	if ($growl_ip) {
444
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
445
		$growl->addNotification($growl_notification);
446
		$growl->register();
447
	}
448
}
449

    
450
/* Notify via remote methods only - not via GUI. */
451
function notify_all_remote($msg) {
452
	notify_via_smtp($msg);
453
	notify_via_growl($msg);
454
}
455

    
456
?>
(33-33/65)