From 349a64ef8f9408297ba57ac9f9e0a69dfe724976 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Thu, 7 Jul 2005 23:34:59 +0000 Subject: add path-locking to voicemail CGI app (bug #4304) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6055 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- contrib/scripts/vmail.cgi | 135 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 105 insertions(+), 30 deletions(-) (limited to 'contrib') diff --git a/contrib/scripts/vmail.cgi b/contrib/scripts/vmail.cgi index d347898a0..5a428970d 100755 --- a/contrib/scripts/vmail.cgi +++ b/contrib/scripts/vmail.cgi @@ -11,10 +11,15 @@ # (icky, I know.... if you know better perl please help!) # # +# Synchronization added by GDS Partners (www.gdspartners.com) +# Stojan Sljivic (stojan.sljivic@gdspartners.com) +# use CGI qw/:standard/; use Carp::Heavy; use CGI::Carp qw(fatalsToBrowser); use DBI; +use Fcntl qw ( O_WRONLY O_CREAT O_EXCL ); +use Time::HiRes qw ( usleep ); $context=""; # Define here your by default context (so you dont need to put voicemail@context in the login @@ -44,6 +49,57 @@ $stdcontainerstart = "
\n"; $footer = "
The Asterisk Open Source PBX Copyright 2004, Digium, Inc."; $stdcontainerend = "
$footer
\n"; +sub lock_path() { + + my($path) = @_; + my $rand; + my $rfile; + my $start; + my $res; + + $rand = rand 99999999; + $rfile = "$path/.lock-$rand"; + + sysopen(RFILE, $rfile, O_WRONLY | O_CREAT | O_EXCL, 0666) or return -1; + close(RFILE); + + $res = link($rfile, "$path/.lock"); + $start = time; + if ($res == 0) { + while (($res == 0) && (time - $start <= 5)) { + $res = link($rfile, "$path/.lock"); + usleep(1); + } + } + unlink($rfile); + + if ($res == 0) { + return -1; + } else { + return 0; + } +} + +sub unlock_path() { + + my($path) = @_; + + unlink("$path/.lock"); +} + +sub untaint() { + + my($data) = @_; + + if ($data =~ /^([-\@\w.]+)$/) { + $data = $1; + } else { + die "Security violation."; + } + + return $data; +} + sub login_screen() { print header; my ($message) = @_; @@ -873,19 +929,29 @@ sub message_forward() die("Bah! Not a valid mailbox '$newmbox'\n"); return ""; } - $msgcount = &msgcount($context, $newmbox, "INBOX"); + my $txt; - if ($newmbox ne $mbox) { -# print header; - foreach $msg (@msgs) { -# print "Forwarding $msg from $mbox to $newmbox
\n"; - &message_copy($context, $mbox, $newmbox, $folder, $msg, sprintf "%04d", $msgcount); - $msgcount++; + $context = &untaint($context); + $newmbox = &untaint($newmbox); + my $path = "/var/spool/asterisk/voicemail/$context/$newmbox/INBOX"; + if (&lock_path($path) == 0) { + $msgcount = &msgcount($context, $newmbox, "INBOX"); + + if ($newmbox ne $mbox) { +# print header; + foreach $msg (@msgs) { +# print "Forwarding $msg from $mbox to $newmbox
\n"; + &message_copy($context, $mbox, $newmbox, $folder, $msg, sprintf "%04d", $msgcount); + $msgcount++; + } + $txt = "Forwarded messages " . join(', ', @msgs) . "to $newmbox"; + } else { + $txt = "Can't forward messages to yourself!\n"; } - $txt = "Forwarded messages " . join(', ', @msgs) . "to $newmbox"; + &unlock_path($path); } else { - $txt = "Can't forward messages to yourself!\n"; - } + $txt = "Cannot forward messages: Unable to lock path.\n"; + } if ($toindex) { &message_index($folder, $txt); } else { @@ -910,33 +976,42 @@ sub message_delete_or_move() $context = "default"; } my $passwd = param('password'); - my $msgcount = &msgcount($context, $mbox, $folder); - my $omsgcount = &msgcount($context, $mbox, $newfolder) if $newfolder; -# print header; - if ($newfolder ne $folder) { - $y = 0; - for ($x=0;$x<$msgcount;$x++) { - my $msg = sprintf "%04d", $x; - my $newmsg = sprintf "%04d", $y; - if (grep(/^$msg$/, @msgs)) { - if ($newfolder) { - &message_rename($context, $mbox, $folder, $msg, $newfolder, sprintf "%04d", $omsgcount); - $omsgcount++; + $context = &untaint($context); + $mbox = &untaint($mbox); + $folder = &untaint($folder); + my $path = "/var/spool/asterisk/voicemail/$context/$mbox/$folder"; + if (&lock_path($path) == 0) { + my $msgcount = &msgcount($context, $mbox, $folder); + my $omsgcount = &msgcount($context, $mbox, $newfolder) if $newfolder; + # print header; + if ($newfolder ne $folder) { + $y = 0; + for ($x=0;$x<$msgcount;$x++) { + my $msg = sprintf "%04d", $x; + my $newmsg = sprintf "%04d", $y; + if (grep(/^$msg$/, @msgs)) { + if ($newfolder) { + &message_rename($context, $mbox, $folder, $msg, $newfolder, sprintf "%04d", $omsgcount); + $omsgcount++; + } else { + &message_delete($context, $mbox, $folder, $msg); + } } else { - &message_delete($context, $mbox, $folder, $msg); + &message_rename($context, $mbox, $folder, $msg, $folder, $newmsg); + $y++; } + } + if ($del) { + $txt = "Deleted messages " . join (', ', @msgs); } else { - &message_rename($context, $mbox, $folder, $msg, $folder, $newmsg); - $y++; + $txt = "Moved messages " . join (', ', @msgs) . " to $newfolder"; } - } - if ($del) { - $txt = "Deleted messages " . join (', ', @msgs); } else { - $txt = "Moved messages " . join (', ', @msgs) . " to $newfolder"; + $txt = "Can't move a message to the same folder they're in already"; } + &unlock_path($path); } else { - $txt = "Can't move a message to the same folder they're in already"; + $txt = "Cannot move/delete messages: Unable to lock path.\n"; } # Not as many messages now $msgcount--; -- cgit v1.2.3