Project

General

Profile

Download (12 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
	$queue[$queuekey] = $toqueue;
84
	$queueout = fopen($notice_path, "w");
85
	if (!$queueout) {
86
		log_error(printf(gettext("Could not open %s for writing"), $notice_path));
87
		return;
88
	}
89
	fwrite($queueout, serialize($queue));
90
	fclose($queueout);
91
	log_error("New alert found: $notice");
92
	/* soekris */
93
	if (file_exists("/dev/led/error")) {
94
		exec("/bin/echo 1 > /dev/led/error");
95
	}
96
	/* wrap & alix */
97
	led_normalize();
98
	led_morse(1, 'sos');
99
	notify_via_growl($notice);
100
	notify_via_smtp($notice);
101
	return $queuekey;
102
}
103

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

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

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

    
183
	return;
184
}
185

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

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

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

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

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

    
298
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
299
		return;
300
	}
301

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

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

    
315
	send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
316
	return;
317
}
318

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

    
324
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
325
		return;
326
	}
327

    
328
	if (!$config['notifications']['smtp']['ipaddress']) {
329
		return;
330
	}
331

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

    
336
	$smtp = new smtp_class;
337

    
338
	$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
339
	$to = $config['notifications']['smtp']['notifyemailaddress'];
340

    
341
	$smtp->host_name = $config['notifications']['smtp']['ipaddress'];
342
	$smtp->host_port = empty($config['notifications']['smtp']['port']) ? 25 : $config['notifications']['smtp']['port'];
343

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

    
351
	if ($config['notifications']['smtp']['fromaddress']) {
352
		$from = $config['notifications']['smtp']['fromaddress'];
353
	}
354

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

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

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

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

    
395
	if (isset($config['notifications']['growl']['disable']) && !$force) {
396
		return;
397
	}
398

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

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

    
413
	if (!empty($growl_ip)) {
414
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
415
		$growl->notify("{$growl_notification}", gettext(sprintf("%s (%s) - Notification", $g['product_name'], $hostname)), "{$message}");
416
	}
417

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

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

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

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

    
453
?>
(34-34/68)