diff options
author | Kissaki <kissaki@gmx.de> | 2013-01-14 00:02:55 +0400 |
---|---|---|
committer | Kissaki <kissaki@gmx.de> | 2013-06-04 23:59:54 +0400 |
commit | 2c490d71261ecd0dcfcb07735bc3289717628b93 (patch) | |
tree | a91468ffd842abf84f5822a20af7ad2ac849c220 /scripts/server | |
parent | 15370fb50475e60ad713b20bb90781b20539109e (diff) |
categorize scripts (move example scripts for serverside into subfolders)
Diffstat (limited to 'scripts/server')
-rw-r--r-- | scripts/server/dbus/ListUsers.cs | 77 | ||||
-rw-r--r-- | scripts/server/dbus/dbusauth.pl | 294 | ||||
-rw-r--r-- | scripts/server/dbus/murmur.pl | 286 | ||||
-rw-r--r-- | scripts/server/dbus/weblist.pl | 148 | ||||
-rw-r--r-- | scripts/server/ice/addban.php | 50 | ||||
-rw-r--r-- | scripts/server/ice/glacier/config | 3 | ||||
-rw-r--r-- | scripts/server/ice/glacier/glacier.php | 45 | ||||
-rw-r--r-- | scripts/server/ice/glacier/passwords | 3 | ||||
-rw-r--r-- | scripts/server/ice/icedemo.php | 209 | ||||
-rw-r--r-- | scripts/server/ice/idle.php | 81 | ||||
-rw-r--r-- | scripts/server/ice/mumble-auth.py | 274 | ||||
-rw-r--r-- | scripts/server/ice/rubytest.rb | 58 | ||||
-rw-r--r-- | scripts/server/ice/simpleregister.php | 76 | ||||
-rw-r--r-- | scripts/server/ice/testauth.py | 119 | ||||
-rw-r--r-- | scripts/server/ice/testcallback.py | 117 | ||||
-rw-r--r-- | scripts/server/ice/testdynamic.py | 29 | ||||
-rw-r--r-- | scripts/server/ice/weblist.php | 60 |
17 files changed, 1929 insertions, 0 deletions
diff --git a/scripts/server/dbus/ListUsers.cs b/scripts/server/dbus/ListUsers.cs new file mode 100644 index 000000000..cc6c8fa48 --- /dev/null +++ b/scripts/server/dbus/ListUsers.cs @@ -0,0 +1,77 @@ +/* +This shows how to list connected users in C#. This depends on the NDesk-DBus +package, which can be found at http://www.ndesk.org/DBusSharp + +Note that DBusSharp requires you to define the interface of the object you +are connecting to at compile time. As such, you loose the advantages of DBus +Introspection, but it's a bit faster (and type safe). +This example only includes a very small subset of the interface definition. + +To compile this with Mono, type: +gmcs -pkg:ndesk-dbus-1.0 ListUsers.cs + +To compile this with the Microsoft compiler, type: +csc -r:NDesk.DBus.dll ListUsers.cs +*/ + +using System; +using NDesk.DBus; +using org.freedesktop.DBus; + +public class ListUsers +{ + public static void Main (string[] args) + { + Connection bus; + if (args.Length == 0) { + bus = Bus.Session; + } else { + if (args[0] == "--session") + bus = Bus.Session; + else if (args[0] == "--system") + bus = Bus.System; + else + bus = Connection.Open (args[0]); + } + + Meta m = bus.GetObject<Meta>("net.sourceforge.mumble.murmur", new ObjectPath("/")); + int [] servers = m.getBootedServers(); + + foreach(int id in servers) { + string path="/"+id; + Console.WriteLine("Users on server #{0}, path {1}",id,path); + Server s = bus.GetObject<Server>("net.sourceforge.mumble.murmur", new ObjectPath(path)); + PlayerInfoExtended [] players = s.getPlayers(); + foreach(PlayerInfoExtended pi in players) { + Console.WriteLine(" {0} ({1})",pi.name,pi.session); + } + } + } +} + +[Interface ("net.sourceforge.mumble.Meta")] +public interface Meta : Introspectable +{ + int [] getBootedServers(); +} + +[Interface ("net.sourceforge.mumble.Murmur")] +public interface Server : Introspectable +{ + PlayerInfoExtended [] getPlayers(); +} + +public struct PlayerInfoExtended +{ + public uint session; + public bool mute; + public bool deaf; + public bool suppressed; + public bool selfMute; + public bool selfDeaf; + public int channel; + public int id; + public string name; + public int onlinesecs; + public int bytespersec; +} diff --git a/scripts/server/dbus/dbusauth.pl b/scripts/server/dbus/dbusauth.pl new file mode 100644 index 000000000..2a3ac7007 --- /dev/null +++ b/scripts/server/dbus/dbusauth.pl @@ -0,0 +1,294 @@ +#! /usr/bin/perl + +# This is a small example script of how to set up murmur to authenticate through +# phpBB3. To use it, you'll have to have started murmur with DBus, and use the +# same session for this script. +# + +use warnings; +use strict; + +# Replace these with whatever is correct for you +our $dbname="phpbb3"; +our $dbuser="phpbb3"; +our $dbpass="uhduqw1237a"; +our $dbprefix="phpbb_"; +our $dbhost="localhost"; + +# Assign user id as phpbb3 user_id plus this, to avoid clashing +# with local murmur users. If you're going to use ONLY external +# authentication, you can set this to 1, but there's no real point. +# Note that Mumble ignores values above 1000000000 when allocating +# player IDs on its own, so you probably want to leave this alone. +our $id_offset = 1000000000; + +# Path to phpBB user avatars. If you want to disable avatar support, set +# this blank. This can be either a directory path or a full URL. + +our $avatar_path = "http://xeno.stud.hive.no/phpBB3/download.php?avatar="; + +# +# No user servicable parts below this point. +# + +use DBI; +use Net::DBus; +use Data::Dumper; +use Net::DBus::Reactor; +use LWP::UserAgent; +use Carp; + +our %texturecache; + +our @dbhparams=("dbi:mysql:dbname=${dbname};host=${dbhost}", $dbuser, $dbpass); +our $agent=new LWP::UserAgent; +$agent->timeout(5); + +our ($bus, $service); + +our $r = Net::DBus::Reactor->main; +eval { + $bus = Net::DBus->system(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); +}; + +if (! $service) { + eval { + $bus = Net::DBus->session(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); + }; +} + +die "Murmur service not found" if (! $service); + +my $dbh=DBI->connect_cached(@dbhparams); +if (! $dbh) { + die $DBI::errstr; +} + +our $object = $service->get_object("/1"); + +our $rservice = $bus->export_service("net.sourceforge.mumble.phpbb"); +our $robject = Mumble::Auth->new($rservice); + + +package Mumble::Auth; + +use Data::Dumper; +use Image::Magick; +use Digest::MD5 qw(md5); +use Net::DBus::Exporter qw(net.sourceforge.mumble.auther); +use base qw(Net::DBus::Object); +dbus_method("authenticate", ["string","string"], ["int32","string",["array","string"]]); +dbus_method("getUserName", ["int32"], ["string"]); +dbus_method("getUserId", ["string"], ["int32"]); +dbus_method("getUserTexture", ["int32"], [["array", "byte"]]); + +sub new { + my $class = shift; + my $service = shift; + my $self = $class->SUPER::new($service, "/authority"); + bless $self, $class; + return $self; +} + +sub hash { + my $self = shift; + my $pw = shift; + my $hash = shift; + my $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + my @itoa64 = split(//,$itoa64); + my $count_log2 = index($itoa64, substr($hash,3,1)); + my $count = 1 << $count_log2; + my $salt = substr($hash, 4, 8); + + my $nhash = $salt; + + do { + $nhash = md5($nhash . $pw); + } while ($count--); + + my $output = substr($hash, 0, 12); + + my $i = 0; + my @input = split(//,$nhash); + while ($i < 16) { + my $value; + $value = ord($input[$i++]); + $output .= $itoa64[$value & 0x3f]; + if ($i < 16) { + $value |= ord($input[$i]) << 8; + } + $output .= $itoa64[($value >> 6) & 0x3f]; + last if ($i++ >= 16); + + if ($i < 16) { + $value |= ord($input[$i]) << 16; + } + $output .= $itoa64[($value >> 12) & 0x3f]; + + last if ($i++ >= 16); + $output .= $itoa64[($value >> 18) & 0x3f]; + }; + + return $output; +} + +# Possible responses are: +# >0 ID of user +# 0 SuperUser +# -1 Wrong password +# -2 Unknown user -- fall back to builtin database + +sub authenticate { + my $self = shift; + my $uname = shift; + my $pw = shift; + + my $dbh=DBI->connect_cached(@dbhparams); + if (! $dbh) { + carp $DBI::errstr; + return -2,'',undef; + } + $dbh->do("SET names utf8"); + my $sth=$dbh->prepare("SELECT user_id, user_password, user_type, username FROM ${dbprefix}users WHERE LOWER(username) = LOWER(?)"); + $sth->execute($uname); + if ((my $r=$sth->fetchrow_hashref())) { + if ($$r{'user_password'} ne $self->hash($pw,$$r{'user_password'})) { + print "Wrong password for $uname\n"; + return -1,'',undef; + } + if (($$r{'user_type'} != 0) && ($$r{'user_type'} != 3)) { + return -1,'',undef; + } + my $id = $$r{'user_id'} + $id_offset; + my $name = $$r{'username'}; + $sth->finish(); + + my @groups; + $sth=$dbh->prepare("SELECT group_name FROM ${dbprefix}user_group LEFT JOIN ${dbprefix}groups USING (group_id) WHERE user_id = ?"); + $sth->execute($$r{'user_id'}); + while ((my $g=$sth->fetchrow_hashref())) { + push @groups, lc $$g{'group_name'}; + } + #my $response = $object->setTemporaryGroups(0, $id, \@groups); + #Dumper($response); + print "Authenticated $uname as ID $id with groups ".join(" ",@groups)."\n"; + return $id,$name,\@groups; + } else { + print "Unknown user $uname\n"; + return -2,'',undef; + } +} + +# Possible responses are: +# string Name of user +# empty Unknown user +# undef Fall back to builting database + +sub getUserName { + my $self = shift; + my $id = shift; + + my $dbh=DBI->connect_cached(@dbhparams); + if (! $dbh) { + carp $DBI::errstr; + return undef; + } + $dbh->do("SET names utf8"); + my $sth=$dbh->prepare("SELECT username FROM ${dbprefix}users WHERE user_id = ?"); + $sth->execute($id - $id_offset); + if ((my $r=$sth->fetchrow_hashref())) { + print "UID $id :: " .$$r{'username'}."\n"; + return $$r{'username'}; + } + print "No match for id $id\n"; + return undef; +} + +# Same response as authenticate + +sub getUserId { + my $self = shift; + my $name = shift; + + my $dbh=DBI->connect_cached(@dbhparams); + if (! $dbh) { + carp $DBI::errstr; + return -2; + } + $dbh->do("SET names utf8"); + my $sth=$dbh->prepare("SELECT user_id FROM ${dbprefix}users WHERE username = ?"); + $sth->execute($name); + if ((my $r=$sth->fetchrow_hashref())) { + return $$r{'user_id'} + $id_offset; + } + return -2; +} + +# Grab a user texture. + +sub getUserTexture { + my $self = shift; + my $uid = shift; + + my @a; + + my $dbh=DBI->connect_cached(@dbhparams); + if (! $dbh) { + carp $DBI::errstr; + return undef; + } + $dbh->do("SET names utf8"); + my $sth=$dbh->prepare("SELECT user_avatar, user_avatar_type FROM ${dbprefix}users WHERE user_id = ?"); + $sth->execute($uid - $id_offset); + if ((my $r=$sth->fetchrow_hashref())) { + my $file = $$r{'user_avatar'}; + my $type = $$r{'user_avatar_type'}; + if (($type != 1) && ($type != 2)) { + print "Request for texture $uid :: not uploaded texture ($type)\n"; + return \@a; + } + if (exists $texturecache{$file}) { + return $texturecache{$file}; + } + + my $url = (($type == 1) ? $avatar_path : '') . $file; + my $response = $agent->get($url); + if (! $response->is_success) { + print "Request for texture $uid :: Fetch $url failed: ". $response->status_line . "\n"; + } else { + my $image = new Image::Magick(); + my $r = $image->BlobToImage($response->content); + if ($r) { + print "Request for texture $uid :: Image $url load failed: $r\n"; + } else { + $image->Extent(x => 0, y => 0, width => 600, height => 60); + my $out=$image->ImageToBlob(magick => 'rgba', depth => 8); + if (length($out) != (600*60*4)) { + print "Request for texture $uid :: Failed resize\n"; + } else { + @a = unpack("C*", $out); + for(my $i=0;$i<600*60;$i++) { + my $red=$a[$i*4]; + my $blue=$a[$i*4+2]; + $a[$i*4]=$blue; + $a[$i*4+2]=$red; + } + print "Request for texture $uid :: $url :: Success\n"; + } + } + } + $texturecache{$file} = \@a; + return $texturecache{$file}; + } + return undef; +} + + +package main; + +my $response = $object->setAuthenticator("/authority", 0); + +print "Entering main DBus loop...\n"; +$r->run(); diff --git a/scripts/server/dbus/murmur.pl b/scripts/server/dbus/murmur.pl new file mode 100644 index 000000000..ce439cd8a --- /dev/null +++ b/scripts/server/dbus/murmur.pl @@ -0,0 +1,286 @@ +#! /usr/bin/perl +# +# For now, this is a CGI using Perl. +# + +use warnings; +use strict; + +## User configurable settings: + +# What's the name of this server? +our $servername = "Mumble & Murmur Test Server"; + +# Who should outgoing authentication emails be from? +our $emailfrom = ""; + +# And what server should be used? +our $emailserver = "localhost"; + +# Which server to add to? Unless you have multiple virtual servers, +# this is always 1 +our $serverid = 1; + +## End of user configurable data +## +## Really. You shouldn't touch anything below this point. + +# If we're being run as a CGI in suexec, $HOME doesn't exist. Fake it. +my $home = (getpwuid($<))[7]; + +# This needs to be done before "use Net::DBus" +if (open(F, "$home/murmur/.dbus.sh")) { + while(<F>) { + chomp(); + if ($_ =~ /^(.+?)\='(.+)';$/) { + $ENV{$1}=$2; + } + } + close(F); +} + +use CGI; +use CGI::Carp 'fatalsToBrowser'; +use CGI::Session; +use Net::SMTP; +use Net::DNS; +use Net::DBus; +use Image::Magick; +use Compress::Zlib; +use Config::Simple; + +sub randomCode($) { + my ($length) = @_; + my $ret; + my $chars="0123456789abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + for(my $i=0;$i<$length;$i++) { + $ret .= substr($chars, rand(int(length($chars))), 1); + } + return $ret; +} + +my $showit = 1; + +CGI::Session->find( sub { } ); + +my $q = new CGI(); +my $s = new CGI::Session(); + +$s->expire('+1d'); + +print $s->header(); +print $q->start_html(-title=>"Registration"); + +my $bus; +my $service; + +# First try the system bus +eval { + $bus=Net::DBus->system(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); + + my $cfg = new Config::Simple(filename => '/etc/mumble-server.ini', syntax => 'simple'); + $servername = $cfg->param("registerName") || $servername; + $emailfrom = $cfg->param("emailfrom") || $emailfrom; +}; + +# If that failed, the session bus +if (! $service) { + eval { + $bus = Net::DBus->session(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); + } +} + +die "Murmur service not found" if (! $service); + +if (! defined($emailfrom) || ($emailfrom eq "")) { + croak(qq{Missing configuration. + Please edit either /etc/mumble-server.ini for systemwide installations, + or murmur.pl for a personal one. + }); +} + + +# Fetch handle to remote object +my $object = $service->get_object("/$serverid"); +my $res; + +my $auth = $q->param('auth'); +my $name = $q->param('name'); +my $pw = $q->param('pw'); +my $email = $q->param('email'); +my $image = $q->upload('image'); + +if (defined($s->param('auth')) && ($auth eq $s->param('auth'))) { + $res = $object->getRegisteredPlayers($s->param('name')); + if ($#{$res} == 0) { + my $aref = $$res[0]; + if ($email ne $$aref[2]) { + $$aref[3] = $s->param('pw'); + $object->updateRegistration($aref); + print "<h1>Updated password</h1><p>Your password has been reset.</p>"; + $showit = 0; + } else { + print "<h1>Apologies</h1><p>Someone has already registered that name in the meantime.</p>"; + } + } else { + $res = $object->registerPlayer($s->param('name')); + if (($res != 0) && ($res != "0")) { + my @array = ($res, $s->param('name'), $s->param('email'), $s->param('pw')); + $object->updateRegistration(\@array); + print "<h1>Succeeded</h1><p>Thank you for registering.</p>"; + $showit = 0; + } else { + print "<h1>Failed</h1><p>Username rejected by server.</p>"; + } + } + $s->clear(); +} elsif (defined($name) && defined($pw) && defined($image)) { + my $id = $object->getPlayerIds( [ $name ] ); + $res = $object->verifyPassword($$id[0], $pw); + if (! $res) { + print "<h1>Tsk tsk</h1><p>Now, that's not a valid user and password, is it?</p>"; + } else { + my $blob; + sysread($image,$blob,1000000); + my $image=Image::Magick->new(); + my $r=$image->BlobToImage($blob); + if (! $r) { + $image->Extent(x => 0, y => 0, width => 600, height => 60, background => "transparent"); + my $out=$image->ImageToBlob(magick => 'rgba', depth => 8); + if (length($out) == (600*60*4)) { + # We need BGRA, AKA ARGB inverse + my @a=unpack("C*", $out); + for(my $i=0;$i<600*60;$i++) { + my $red=$a[$i*4]; + my $blue=$a[$i*4+2]; + $a[$i*4]=$blue; + $a[$i*4+2]=$red; + } + @a=unpack("C*", pack("N", $#a + 1) . compress(pack("C*",@a))); + $res = $object->setTexture($$id[0], \@a); + } else { + $r=1; + } + } + if ($r) { + print "<h1>Image failure</h1><p>Failed to convert that to a proper image.</p>"; + } else { + print "<h1>Succeeded</h1><p>Reconnect to use the new image.</p>"; + $showit = 0; + } + } +} elsif (defined($name) && defined($pw) && defined($email)) { + my @errors; + + if (length($name) < 4) { + push @errors, "Username is too short."; + } + if (length($pw) < 8) { + push @errors, "Password is too short."; + } + if ($name !~ /^[0-9a-zA-Z\(\)\[\]\-\_]+$/) { + push @errors, "Username contains illegal characters."; + } + + if ($email !~ /^[0-9a-zA-Z\.\-\_]+\@(.+)$/) { + push @errors, "That doesn't even look like an email adddress."; + } else { + my @mx = mx($1); + if ($#mx == -1) { + push @errors, "And how am I supposed to send email there?"; + } + } + + $res=$object->getRegisteredPlayers($name); + if ( $#{$res} == 0 ) { + my $aref = $$res[0]; + if ($email ne $$aref[2]) { + push @errors, "Name is already taken"; + } + } + + if ($#errors == -1) { + my $code = randomCode(10); + + $s->param('name', $name); + $s->param('pw', $pw); + $s->param('email', $email); + $s->param('auth', $code); + + my $smtp = new Net::SMTP($emailserver); + if (! $smtp) { + croak(qq{Failed to connect to SMTP server "$emailserver". This is most likely a configuration problem.\n}); + } + $smtp->mail($emailfrom); + $smtp->to($email); + $smtp->data(); + $smtp->datasend("From: $emailfrom\n"); + $smtp->datasend("To: $email\n"); + $smtp->datasend("Subject: Murmur registration\n"); + $smtp->datasend("\n"); + $smtp->datasend("A user from $ENV{'REMOTE_ADDR'} registered the username $name\n"); + $smtp->datasend("on \"${servername}\".\n\n"); + $smtp->datasend("If this was you, please visit the following url to activate your account:\n"); + $q->delete_all(); + $q->param('auth', $code); + $smtp->datasend($q->url(-query=>1)); + $smtp->datasend("\n\n"); + $smtp->datasend("If you have no idea what this is about, just disregard this message."); + $smtp->dataend(); + + print '<h1>Registration complete</h1><p>Thank you for registering. An email has been sent to you with '; + print 'an activation code.</p>'; + $showit = 0; + } else { + print '<ul>'; + foreach my $error (@errors) { + print "<li>$error</li>"; + } + print '</ul>'; + } +} + +if ($showit) { + print '<h1>Registration form</h1>'; + print '<p>Fill out your desired username, password and your current email address. A mail will be sent to you '; + print 'with an authentication code.</p>'; + print '<p>If you\'ve forgotten your password, just reregister with the same name and email address. A new '; + print 'confirmation email will be sent.</p>'; + print '<p>'; + print $q->start_form(-method=>'POST'); + print "Username "; + print $q->textfield(-name=>'name', -size=>'10'); + print "<br />\n"; + print "Email "; + print $q->textfield(-name=>'email', -size=>'30'); + print "<br />\n"; + print "Password "; + print $q->password_field(-name=>'pw', -size=>'10'); + print "<br />\n"; + print $q->submit(-value=>'Register'); + print $q->end_form(); + print '</p>'; + + print '<h1>Upload custom texture?</h1>'; + print '<p>'; + print 'Remember that the image must be 600 by 60 pixels, and must have an alpha channel.<br />'; + print "\n"; + print $q->start_form(-method=>'POST'); + print "Username "; + print $q->textfield(-name=>'name', -size=>'10'); + print "<br />\n"; + print "Password "; + print $q->password_field(-name=>'pw', -size=>'10'); + print "<br />\n"; + print "Image "; + print $q->filefield(-name=>'image', -size=>'30'); + print "<br />\n"; + print $q->submit(-value=>'Upload Image'); + print $q->end_form(); + print '</p>'; +} + +print $q->end_html(); diff --git a/scripts/server/dbus/weblist.pl b/scripts/server/dbus/weblist.pl new file mode 100644 index 000000000..5f78237e1 --- /dev/null +++ b/scripts/server/dbus/weblist.pl @@ -0,0 +1,148 @@ +#! /usr/bin/perl + +use warnings; +use strict; + +# If we're being run as a CGI in suexec, $HOME doesn't exist. Fake it. +my $home = (getpwuid($<))[7]; + +# This needs to be done before "use Net::DBus" +if (open(F, "$home/murmur/.dbus.sh")) { + while(<F>) { + chomp(); + if ($_ =~ /^(.+?)\='(.+)';$/) { + $ENV{$1}=$2; + } + } + close(F); +} + +use Net::DBus; +use CGI::Carp qw(fatalsToBrowser); +use HTML::Template; + +my $tmpl_fname = $1 if ($0 =~ /(.+)\.([a-z]+)$/); +my $tmpl; +if (-f "$tmpl_fname.tmpl") { + $tmpl = HTML::Template->new(filename => "$tmpl_fname.tmpl"); +} else { + $tmpl = HTML::Template->new(filehandle => *DATA); +} +my $bus; +my $service; + +# First try the system bus +eval { + $bus=Net::DBus->system(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); +}; + +# If that failed, the session bus +if (! $service) { + eval { + $bus = Net::DBus->session(); + $service = $bus->get_service("net.sourceforge.mumble.murmur"); + } +} + +die "Murmur service not found" if (! $service); + +# Fetch handle to remote object +my $object = $service->get_object("/"); +# Call a function on the murmur object +my $servers = $object->getBootedServers(); + +my $params = []; +foreach my $server (@{$servers}) { + my $name = $object->getConf($server, "registername"); + my $servobj = $service->get_object("/$server"); + + my %users; + # First, get channel names + my $channels = $servobj->getChannels(); + my %channels; + foreach my $c (@{$channels}) { + my @c = @{$c}; + my $id = $c[0]; + my $name = $c[1]; + $channels{$id}=$name; + } + # Then, get and print the players + my $players = $servobj->getPlayers(); + my $_total = 0; + foreach my $p (@{$players}) { + my @p = @{$p}; + my $chanid = $p[6]; + my $name = $p[8]; + my $chan = $channels{$chanid}; + $users{$chan} = [] unless $users{$chan}; + push @{$users{$chan}}, $name; + $_total++; + } + my $_channels = []; + for my $c (sort keys %users) { + my $_users = []; + for my $u (sort @{$users{$c}}) { + push @{$_users}, {'user' => $u}; + } + push @{$_channels}, { + 'channel' => $c, + 'users' => $_users + }; + } + push @{$params}, {'server' => $server, 'name' => $name, 'total' => $_total, 'channels' => $_channels}; +} + +$tmpl->param("servers", $params); +print "Content-type: text/html;charset=utf8\r\n\r\n", + $tmpl->output; + +__END__ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<HTML lang="ja"> + <HEAD> + <Title>mumble server user list</title> + <STYLE TYPE="text/css"> + <!-- + body { + background-color: #ffffff; + color: #4b4b4b; + font-family: verdana, arial, sans-serif; + font-size: 13px; + margin: 10px 20px; + } + dl { + margin-left: 5px; + } + dt { + clear: both; + font-weight: bold; + padding-left: 5px; + border-left: #4b4b4b 5px solid + } + dd { + float: left; + margin-left: 5px; + margin-bottom: 5px; + margin-top: 2px; + } + --> + </STYLE> + </HEAD> + <BODY bgcolor="#ffffff" text="#4b4b4b" link="#3399ff" alink="#0099cc" vlink="#006666"> + <TMPL_LOOP NAME="servers"> + <H1>Server #<TMPL_VAR NAME="server"> <TMPL_VAR NAME="name"></H1> + total: <TMPL_VAR NAME="total"> + <dl> + <TMPL_LOOP NAME="channels"> + <dt><TMPL_VAR NAME="channel"> + <dd> + <TMPL_LOOP NAME="users"> + <TMPL_VAR NAME="user">, + </TMPL_LOOP> + </TMPL_LOOP> + </dl> + </TMPL_LOOP> + </BODY> +</HTML> + diff --git a/scripts/server/ice/addban.php b/scripts/server/ice/addban.php new file mode 100644 index 000000000..bc601bfa4 --- /dev/null +++ b/scripts/server/ice/addban.php @@ -0,0 +1,50 @@ +<?php + +# This shows how to use structs from PHP. + +if (Ice_intversion() >= 30400) { + require 'Ice.php'; + require 'Murmur.php'; +} else { + Ice_loadProfile(); +} + +try { + if (Ice_intversion() >= 30400) { + $ICE = Ice_initialize(); + } + + $base = $ICE->stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502"); + $meta = $base->ice_checkedCast("::Murmur::Meta"); + + $default = $meta->getDefaultConf(); + + $server = $meta->getServer(1); + + + $bans = $server->getBans(); + + print_r($bans); + foreach($bans as $ban) { + for($i=0;$i<16;$i+=2) { + echo sprintf("%02x%02x", $ban->address[$i], $ban->address[$i+1]); + if ($i != 14) { + echo ":"; + } + } + $mask = $ban->bits; + echo "/$mask\n"; + } + + $ban = new Murmur_Ban(); + $ban->address = array(0,0,0,0,0,0,0,0,0,0,255,255,127,0,0,1); + $ban->bits = 128; + + array_push($bans, $ban); + + $server->setBans($bans); + +} catch (Ice_Exception $ex) { + print_r($ex); +} +?> diff --git a/scripts/server/ice/glacier/config b/scripts/server/ice/glacier/config new file mode 100644 index 000000000..399378e6a --- /dev/null +++ b/scripts/server/ice/glacier/config @@ -0,0 +1,3 @@ +Glacier2.Client.Endpoints=tcp -h 0.0.0.0 -p 4063 +Glacier2.SessionTimeout=60 +Glacier2.CryptPasswords=passwords diff --git a/scripts/server/ice/glacier/glacier.php b/scripts/server/ice/glacier/glacier.php new file mode 100644 index 000000000..129fc47ab --- /dev/null +++ b/scripts/server/ice/glacier/glacier.php @@ -0,0 +1,45 @@ +<html> +<head> +<title>Userlist</title> +</head> +<body> +<?php + +Ice_loadProfile(); + +try { + # Replace IP address with the one your glacier2 is running on + $router = $ICE->stringToProxy("Glacier2/router:tcp -p 4063 -h 128.39.114.1"); + $router = $router->ice_uncheckedCast("::Glacier2::Router")->ice_router(null); + $session = $router->createSession("testuser", "testpass"); + + $base = $ICE->stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502")->ice_router($router); + $meta = $base->ice_checkedCast("::Murmur::Meta"); + + $servers = $meta->getBootedServers(); + $default = $meta->getDefaultConf(); + foreach($servers as $s) { + $s = $s->ice_router($router); + $name = $s->getConf("registername"); + if (! $name) { + $name = $default["registername"]; + } + echo "<h1>SERVER #" . $s->id() . " " .$name ."</h1>\n"; + echo "<table><tr><th>Name</th><th>Channel</th></tr>\n"; + + $channels = $s->getChannels(); + $players = $s->getUsers(); + + foreach($players as $id => $state) { + $chan = $channels[$state->channel]; + echo "<tr><td>".$state->name."</td><td>".$chan->name."</td></tr>\n"; + } + echo "</table>\n"; + } +} catch (Ice_LocalException $ex) { + print_r($ex); +} + +?> +</body> +</html> diff --git a/scripts/server/ice/glacier/passwords b/scripts/server/ice/glacier/passwords new file mode 100644 index 000000000..04d2dc5b4 --- /dev/null +++ b/scripts/server/ice/glacier/passwords @@ -0,0 +1,3 @@ +# Username/password pairs. +# passwords are generated with 'openssl passwd' +testuser Ok0Z9JAEBWiAY diff --git a/scripts/server/ice/icedemo.php b/scripts/server/ice/icedemo.php new file mode 100644 index 000000000..a19c3f3fc --- /dev/null +++ b/scripts/server/ice/icedemo.php @@ -0,0 +1,209 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +<title>Userlist</title> +</head> +<body> +<?php + +if (!extension_loaded('ice')) { + exit('Error: This example script needs the PHP extension for Ice to be loaded.'); +} +if ((!function_exists('Ice_intVersion') || Ice_intVersion() < 30400) || !function_exists('Ice_loadProfile')) { + exit('Error: This example script is compatible only for php-ice versions prior to 3.4.'); +} + +Ice_loadProfile(); + +if ($argc > 0) { + for($i=1;$i<$argc;$i++) { + parse_str($argv[$i], $tmp); + $_REQUEST=array_merge($_REQUEST, $tmp); + } +} + +function ucmp($a, $b) { + if (($a->playerid == 0) || ($b->playerid == 0)) { + return ($a->playerid - $b->playerid); + } + return strcasecmp($a->name, $b->name); +} + +$confitems = array(); +$confbig = array(); +$confitems['host']="IP Address to bind to"; +$confitems['port']="Port to use"; +$confitems['password']="Password for unregistered users"; +$confitems['timeout']="Timeout before kicking dead connections"; +$confitems['bandwidth']="Maximum bandwidth in bytes/sec"; +$confitems['users']="Maximum number of users on server"; +$confitems['welcometext']="Welcome message"; +$confbig['welcometext']=1; +$confitems['registername']="Server Name"; +$confitems['registerpassword']="Password for Global Server List"; +$confitems['registerhostname']="Hostname for Global Server List"; +$confitems['registerurl']="HTTP URL for Global Server List"; +$confitems['certificate']="PEM Encoded SSL Certificate"; +$confbig['certificate']=1; +$confitems['key']="PEM Encoded SSL Key"; +$confbig['key']=1; + +try { + $base = $ICE->stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502"); + $meta = $base->ice_checkedCast("::Murmur::Meta"); + + $default = $meta->getDefaultConf(); + + if (! is_null($_REQUEST['newserver'])) { + $meta->newServer(); + } else if (! is_null($_REQUEST['delserver'])) { + $meta->getServer((int)$_REQUEST['delserver'])->delete(); + } else if (! is_null($_REQUEST['stop'])) { + $meta->getServer((int) $_REQUEST['stop'])->stop(); + } else if (! is_null($_REQUEST['start'])) { + $meta->getServer((int) $_REQUEST['start'])->start(); + } else if (! is_null($_REQUEST['action'])) { + $server = $meta->getServer((int) $_REQUEST['action']); + if (!is_null($_REQUEST['kick'])) { + $server->kickPlayer((int) $_REQUEST['kick'], "Mushroom"); + } + } else if (! is_null($_REQUEST['uedit'])) { + $server = $meta->getServer((int) $_REQUEST['uedit']); + if (isset($_REQUEST['newplayer'])) { + $reg = array(); + $reg[Murmur_UserInfo::UserName] = $_REQUEST['newplayer']; + if ($_REQUEST['password']) $reg[Murmur_UserInfo::UserPassword] = $_REQUEST['password']; // This line is added for password at user creation + $_REQUEST['uid'] = $server->registerUser($reg); + } + if (! is_null($_REQUEST['deleteplayer'])) { + $server->unregisterUser((int) $_REQUEST['deleteplayer']); + } + if (! is_null($_REQUEST['uid'])) { + $uid = (int) $_REQUEST['uid']; + $user = $server->getRegistration($uid); + if (! is_null($_REQUEST['set'])) { + $user[Murmur_UserInfo::UserEmail] = $_REQUEST['email']; + $user[Murmur_UserInfo::UserPassword] = $_REQUEST['pw']; + $server->updateRegistration($uid,$user); + } else { + echo "<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">\n"; + echo "<p>\n"; + echo "<b>Name:</b> ".$user[Murmur_UserInfo::UserName]."<br />\n"; + echo "<input type=\"hidden\" name=\"set\" value=\"1\" />\n"; + echo "<input type=\"hidden\" name=\"uedit\" value=\"".$server->id()."\" />\n"; + echo "<input type=\"hidden\" name=\"uid\" value=\"$uid\" />\n"; + echo "<b>Email:</b> <input type=\"text\" name=\"email\" size=\"30\" maxlength=\"128\" value=\"".htmlspecialchars($user[Murmur_UserInfo::UserEmail])."\" /><br />\n"; + echo "<b>New password:</b> <input type=\"password\" name=\"pw\" size=\"30\" maxlength=\"128\" /><br />\n"; + echo "<input type=\"submit\" />\n"; + echo "</p>\n"; + echo "</form>\n"; + } + } + echo "<h1>Registered User List</h1>\n"; + echo "<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">\n"; + echo "<p>\n"; + echo "<input type=\"hidden\" name=\"uedit\" value=\"".$server->id()."\" />\n"; + echo "<b>New User:</b>"; + echo "<input type=\"text\" name=\"newplayer\" size=\"30\" maxlength=\"60\" />"; + echo "<b>User Password:</b>"; + echo "<input type=\"text\" name=\"password\" size=\"30\" maxlength=\"60\" />"; + echo "<input type=\"submit\" />\n"; + echo "</p>\n"; + echo "</form>\n"; + echo "<table>\n"; + echo "<tr><th>UserName</th><th>Email</th><th></th></tr>\n"; + $users = $server->getRegisteredUsers(""); + foreach($users as $id=>$name) { + $u = $server->getRegistration($id); + echo "<tr><td>$name $id</td><td>".$u[Murmur_UserInfo::UserEmail]."</td><td>"; + echo "<a href=\"?uedit=".$server->id()."&uid=".$id."\">[Edit]</a> "; + echo "<a href=\"?uedit=".$server->id()."&deleteplayer=".$id."\">[Unregister]</a> "; + echo "</td></tr>\n"; + } + echo "</table>\n"; + } else if (! is_null($_REQUEST['server'])) { + $server = $meta->getServer($_REQUEST['server'] + 0); + if (! is_null($_REQUEST['set'])) { + foreach($confitems as $key=>$desc) { + $server->setConf($key, $_REQUEST[$key]); + } + } else { + $conf = $server->getAllConf(); + $default['port'] += $server->id() - 1; + echo "<h1>Server Configuration</h1>\n"; + echo "<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">\n"; + echo "<div>\n"; + echo "<input type=\"hidden\" name=\"server\" value=\"".$server->id()."\" />\n"; + echo "<input type=\"hidden\" name=\"set\" value=\"1\" />\n"; + echo "</div>\n"; + echo "<table><tr><th>Description</th><th>Default</th><th>Value</th></tr>\n"; + foreach($confitems as $key=>$desc) { + if (! isset($confbig[$key])) { + echo "<tr><td>$desc</td><td>".htmlspecialchars($default[$key])."</td><td>"; + echo "<input type=\"text\" name=\"$key\" size=\"30\" maxlength=\"64000\" value=\"".htmlspecialchars($conf[$key])."\" />"; + echo "</td></tr>\n"; + } else { + echo "<tr><td>$desc</td><td colspan=\"2\">".htmlspecialchars($default[$key])."</td></tr>"; + echo "<tr><td> </td><td colspan=\"2\"><textarea rows=\"5\" cols=\"80\" name=\"$key\">".htmlspecialchars($conf[$key])."</textarea>"; + echo "</td></tr>\n"; + } + } + echo "</table>\n"; + echo "<div><input type=\"submit\" /></div>\n"; + echo "</form>\n"; + } + } + + $servers = $meta->getAllServers(); + $booted = $meta->getBootedServers(); + + echo "<h1>Murmur ICE Interface demo</h1>\n"; + echo "<p><b>Warning:</b> This is not intended as a full management suite. It's an example. It has bugs. It has security holes. "; + echo "It might make precious body parts fall off. <b>Do not run it on a production server</b>.\n"; + echo "</p>\n"; + echo "<p>\n"; + echo "<a href=\"?newserver\">[New Server]</a>\n"; + echo "</p>\n"; + foreach($servers as $s) { + $name = $s->getConf("registername"); + if (! $name) { + $name = $default["registername"]; + } + $id = $s->id(); + echo "<h1>SERVER #" . $id . " " .$name ."</h1>\n"; + echo "<p>\n"; + echo "<a href=\"?server=".$id."\">[Config]</a> "; + if (in_array($s, $booted)) { + echo "<a href=\"?uedit=".$id."\">[Manage Users]</a> "; + echo "<a href=\"?stop=".$id."\">[Stop]</a> "; + } else { + echo "<a href=\"?delserver=".$id."\">[Delete Server]</a> "; + echo "<a href=\"?start=".$id."\">[Start]</a> "; + } + echo "</p>\n"; + if (in_array($s, $booted)) { + echo "<table><tr><th>Name</th><th>Channel</th><th>Actions</th></tr>\n"; + + $channels = $s->getChannels(); + $players = $s->getUsers(); + + foreach($players as $pid => $state) { + $chan = $channels[$state->channel]; + echo "<tr><td>".$state->name."</td><td>".$chan->name."</td><td>"; + echo "<a href=\"?action=".$id."&kick=$state->session\">[Kick]</a>"; + echo "</td></tr>\n"; + } + echo "</table>\n"; + } + } +} catch (Ice_Exception $ex) { + echo "<p>\n<pre>\n"; + print_r($ex); + echo "</pre>\n</p>\n"; +} + +?> +</body> +</html> diff --git a/scripts/server/ice/idle.php b/scripts/server/ice/idle.php new file mode 100644 index 000000000..64ec27372 --- /dev/null +++ b/scripts/server/ice/idle.php @@ -0,0 +1,81 @@ +<? +# idle.php - Sample "auto-idle mover" script. Run in a cron job. +# Copyright (c) 2010, Jamie Fraser / MumbleDog/Sabrienix +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of MumbleDog/Sabrienix nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +###################################################################### +# +# NOTE WELL: This is just an example. It has no error checking, left +# out both because of my own laziness and to keep the example simple. +# Steal the implementation and put it in your own script, or just use +# as-is under the full understanding it might end the world as you +# know it. + +# "AFK" channel ID +$afk = 4; + +# Time in seconds user must be AFK to be moved +$idle = 5000; + +# Ice Server +$ice = 'Meta:tcp -h 127.0.0.1 -p 6502'; + +# Murmur ID # +$mid = 0; + +###################################################################### + +if (!extension_loaded('ice')) { + exit('Error: This example script needs the PHP extension for Ice to be loaded.'); +} +if ((!function_exists('Ice_intVersion') || Ice_intVersion() < 30400) || !function_exists('Ice_loadProfile')) { + exit('Error: This example script is compatible only for php-ice versions prior to 3.4.'); +} + +Ice_loadProfile(); +$base = $ICE->stringToProxy($ice); +$murmur = $base->ice_checkedCast('::Murmur::Meta'); + +$m = $murmur->getServer($mid); + +$users = $m->getUsers(); + +foreach ($users as $u) { + printf("%s: %s\n", $u->name, $u->idlesecs); + if ($u->idlesecs > $idle && $u->channel != $afk) { + $state = $m->getState($u->session); + if ($state) { + $state->channel = $afk; + $m->setState($state); + } + } +} +?>
\ No newline at end of file diff --git a/scripts/server/ice/mumble-auth.py b/scripts/server/ice/mumble-auth.py new file mode 100644 index 000000000..1a28328fa --- /dev/null +++ b/scripts/server/ice/mumble-auth.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +# -*- coding: utf-8 +# +# mumble-auth.py - Sample script to show the basics of using server controlled +# context menu entries for in-client registration tickets. +# +# Requirements: +# * python 2.5 or higher +# * cherrypy 3 or higher +# * python ice bindings +# * murmur + mumble rev 1530 or higher + +import cherrypy +import Ice +from threading import Semaphore +import random, time + +# +#--- Config stuff +# +baseurl = "http://localhost:8080/register?id=" # Baseurl for registrations +storage_time = 10*24*60*60 # Time in seconds a reg entry is guaranteed to be valid +proxy = "Meta:tcp -h 127.0.0.1 -p 6502" +group = "admin" # ACL group which has the right to send regurls +host = "0.0.0.0" # Interface to listen on +port = 8080 # Cherrypy port +slice = "Murmur.ice" +production = False # Set this to true to surpress tracebacks + +# Runtime generate bindings +Ice.loadSlice(slice) +import Murmur + +# Global vars +sema_ids = Semaphore() +ids = {} #Contains list(sid, user, time) + + +class MetaCallbackI(Murmur.MetaCallback): + def started(self, s, current=None): + serverR = Murmur.ServerCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerCallbackI(server, current.adapter))) + s.addCallback(serverR) + def stopped(self, s, current=None): pass # Unused callback + +class ServerCallbackI(Murmur.ServerCallback): + def __init__(self, server, adapter): + self.server = server + self.contextR=Murmur.ServerContextCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerContextCallbackI(server))) + + def userConnected(self, p, current=None): + if p.userid != 0: # SuperUser is always allowed + # Check if the user is in the right acl class and add the context menu + allowed = False + for acl in self.server.getACL(0)[1]: + if acl.name == group and p.userid in acl.members: + allowed = True + break + if not allowed: + return + + self.server.addContextCallback(p.session, + "sendregurl", + "Send registration URL", + self.contextR, Murmur.ContextUser) + + def userDisconnected(self, p, current=None): pass # Unused callbacks + def userStateChanged(self, p, current=None): pass + def channelCreated(self, c, current=None): pass + def channelRemoved(self, c, current=None): pass + def channelStateChanged(self, c, current=None): pass + +class ServerContextCallbackI(Murmur.ServerContextCallback): + #--- Server message template strings + err_notallowed = "You are not allowed to send registration urls" + msg_regurl = "You've been allowed to register with this mumble server, " \ + "please <a href='%(url)s'>click here to register</a>." + + + def __init__(self, server): + self.server = server + + def contextAction(self, action, p, session, chanid, current=None): + if action == "sendregurl" and p: + if p.userid != 0: + # If it isn't SuperUser check if he is in the right acl group + allowed = False + for acl in self.server.getACL(0)[1]: + if acl.name == group and p.userid in acl.members: + allowed = True + break + if not allowed: + self.server.sendMessage(p, self.err_notallowed) + return + + sema_ids.acquire() + try: + # Take the chance to cleanup old entries + todel = [] + for key, reg in ids.iteritems(): + if int(time.time()) - reg[2] > storage_time: + todel.append(key) + for key in todel: + del ids[key] + + # Ok, now generate his registration id (64bit) + rid = None + while not rid or rid in ids: + rid = random.randrange(0, pow(2,64)) + sid = self.server.id() + + # Remember his username + try: + username = self.server.getState(session).name + except Murmur.InvalidSessionException: + username = "" + + # Save everything + ids[str(rid)] = (sid, username, int(time.time())) + # Send reg url to the user + url = baseurl + str(rid) + self.server.sendMessage(session, + self.msg_regurl % {'url':url}) + finally: + sema_ids.release() + + + +class mumble_auth(object): + #--- Web template strings + template = """<?xml version="1.0" encoding="utf-8" ?> + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> + <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + <head> + <title>%(title)s</title> + <style type="text/css"> + label { display:block; font-size:smaller; } + fieldset { border:1px solid; width:250px; } + h1 { border-bottom:2px solid; } + h2 { border-bottom:2px solid red; color:red; } + </style> + </head> + <body> + <h1>%(title)s</h1> + %(body)s + </body> + </html>""" + + err_id = """<h2>Invalid ID</h2><p> + The ID for your registration has already been used or is invalid.<br /> + Please request a new registration link from a Mumble administrator.<br /></p>""" + + err_username = """<h2>Invalid username</h2><p> + The username you chose contains characters which are not allowed.<br/> + Please only use normal characters without whitespaces.<br /></p>""" + + err_username_existing = """<h2>Username already registered</h2><p> + The username you chose is already registered on this server.<br /> + Please choose another one.<br /></p>""" + + err_password = """<h2>Invalid password</h2><p> + The password you chose didn't match the criteria enforced by this server.<br/> + Your password should be at least 6 characters long.<br /></p>""" + + err_password_mismatch = """<h2>Passwords do not match</h2><p> + The password you entered did not match the one in the confirmation box.<br/> + Make sure both boxes contain the same password.<br /></p>""" + + snippet_retry = '<br/><a href="%(url)s">Click here to try again</a>' + + body_index = """<p>This is the mumble-auth script, to be able to register yourself + an account please ask a admin on the mumble server.</p>""" + + body_complete = """<h2>Success</h2><p> + You have been registered with the server successfully,<br /> + please try to login to the server with your new login credentials!</p>""" + + body_regform = """ + <form action="doregister" method="post"> + <fieldset> + <legend>Enter user information</legend> + <label for="username">Username</label> + <input id="username" type="text" name="username" value="%(username)s" + size="20" maxlength="40" /><br /> + <label for="password">Password</label> + <input id="password" type="password" name="password" value="" + size="20" maxlength="40" /><br /> + <label for="cpassword">Confirm password</label> + <input id="cpassword" type="password" name="cpassword" value="" + size="20" maxlength="40" /><br /> + <input type="hidden" name="id" value="%(id)s" /> + <input id="register" type="submit" value="Register" /> + </fieldset> + </form>""" + + def __init__(self, murmur): + self.murmur = murmur + + def index(self): + title = "Mumble Auth - Index" + return self.template % {'title':title, + 'body':self.body_index} + index.exposed = True + + def register(self, id = None): + title = "Mumble Auth - Register"; + if not id in ids: + body = self.err_id # Invalid ID + else: + # In case of a valid ID + body = self.body_regform % {'username':ids[id][1], + 'id':id} + + return self.template % {'title':title, + 'body':body} + register.exposed = True + + def doregister(self, id = None, username = None, password = None, cpassword = None): + title = "Mumble Auth - Register"; + sema_ids.acquire() + try: + # Check if all parameters are ok + if not id in ids: + body = self.err_id # Invalid id + elif not username or " " in username: # Invalid username + body = self.err_username + \ + self.snippet_retry % {'url':baseurl+id} + elif len(password) < 6: # Password criteria didn't match + body = self.err_password + \ + self.snippet_retry % {'url':baseurl+id} + elif password != cpassword: # Password mismatch + body = self.err_password_mismatch + \ + self.snippet_retry % {'url':baseurl+id} + else: + # Ok, try to register him + server = self.murmur.getServer(ids[id][0]) + if (len(server.getRegisteredUsers(username))!=0): + body = self.err_username_existing + \ + self.snippet_retry % {'url':baseurl+id} + else: + # Register user + info = {Murmur.UserInfo.UserName:username, + Murmur.UserInfo.UserPassword:password} + server.registerUser(info) + # Void registration id + del ids[id] + # Success + body = self.body_complete + finally: + sema_ids.release() + return self.template % {'title':title, + 'body':body} + doregister.exposed = True + +if __name__ == "__main__": + random.seed() + ice = Ice.initialize() + try: + meta = Murmur.MetaPrx.checkedCast(ice.stringToProxy(proxy)) + adapter = ice.createObjectAdapterWithEndpoints("Callback.Client", "tcp -h 127.0.0.1") + metaR=Murmur.MetaCallbackPrx.uncheckedCast(adapter.addWithUUID(MetaCallbackI())) + adapter.activate() + + meta.addCallback(metaR) + for server in meta.getBootedServers(): + serverR=Murmur.ServerCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerCallbackI(server, adapter))) + server.addCallback(serverR) + + if production: cherrypy.config.update({'environment': 'production'}) + cherrypy.server.socket_host = host + cherrypy.server.socket_port = port + cherrypy.quickstart(mumble_auth(meta)) + finally: + ice.shutdown() + ice.waitForShutdown() diff --git a/scripts/server/ice/rubytest.rb b/scripts/server/ice/rubytest.rb new file mode 100644 index 000000000..82edb4d69 --- /dev/null +++ b/scripts/server/ice/rubytest.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby + +# Download Murmur.ice from +# http://mumble.git.sourceforge.net/git/gitweb.cgi?p=mumble;a=blob_plain;f=src/murmur/Murmur.ice;hb=HEAD +# and run 'slice2rb Murmur.ice'. slice2rb is part of ICE. +# This will generate the necessary 'Murmur.rb' file which needs to be included: + +require 'Murmur.rb' + +status = 0 +ic = nil +begin + ic = Ice::initialize(ARGV) + base = ic.stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502") + meta = Murmur::MetaPrx::checkedCast(base) + + unless meta + rais "invalid proxy" + end + + # All commands are documented here: + # http://mumble.sourceforge.net/slice/?title=slice + + servers = meta.getBootedServers + puts "Server version:", meta.getVersion[3] + + servers.each do |server| + puts "" + puts "Server name:"+server.getConf('registername') + + channels = server.getChannels + players = server.getPlayers + + players.each do |id,player| + channel = channels[player.channel] + puts player.name+" in "+channel.name + end + + end + +rescue + puts $! + puts $!.backtrace.join("\n") + status = 1 +end + +if ic + # Clean up + begin + ic.destroy() + rescue + puts $! + puts $!.backtrace.join("\n") + status = 1 + end +end + +exit(status) diff --git a/scripts/server/ice/simpleregister.php b/scripts/server/ice/simpleregister.php new file mode 100644 index 000000000..5712efc38 --- /dev/null +++ b/scripts/server/ice/simpleregister.php @@ -0,0 +1,76 @@ +<?php +// Really simple script to add users to your mumble server. +// Make sure to select the server this script should be used for first: +$serverId = 1; + +// Requires a correctly set up PHP-ICE Module and mumble server running with ICE. +// For instructions see http://mumble.sourceforge.net/ICE + +// Credits +// This script was created by Kissaki + +// This is as simple as it can get. You really SHOULD NOT make the URL to this script all-public as it may be abused/spammed. + + +if (!extension_loaded('ice')) { + exit('Error: This example script needs the PHP extension for Ice to be loaded.'); +} +if ((!function_exists('Ice_intVersion') || Ice_intVersion() < 30400) || !function_exists('Ice_loadProfile')) { + exit('Error: This example script is compatible only for php-ice versions prior to 3.4.'); +} + +?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +</head> +<body> +<?php + +Ice_loadProfile(); + +if( isset($_GET['uname']) && $_GET['password'] && $_GET['email'] && $_GET['uname']!='' && $_GET['password']!='' ) +{ + + try { + $base = $ICE->stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502"); + $meta = $base->ice_checkedCast("::Murmur::Meta"); + + $server = $meta->getServer($serverId); + + if(empty($server)){ + echo 'Server could not be found.'; + }else{ + $registrationId = $server->registerPlayer($_GET['uname']); + + $registration = $server->getRegistration(intval($registrationId)); + $registration->pw = $_GET['password']; + $registration->email = $_GET['email']; + $server->updateregistration($registration); + } + + }catch(InvalidPlayerException $ex){ + echo 'InvalidPlayerException'; + }catch(ServerBootedException $ex){ + echo 'Server is not running'; + }catch(Ice_UnknownLocalException $exc){ + echo 'Ice could probably not be found'; + }catch (Ice_Exception $ex){ + echo "<p>\n<pre>\n"; + print_r($ex); + echo "</pre>\n</p>\n"; + } +} + +?> + <form action="" method="get"> + <table> + <tr><td>Username</td><td><input name="uname" type="text" value=""/></td></tr> + <tr><td>Password</td><td><input name="password" type="password" value=""/></td> + <tr><td>eMail</td><td><input name="email" type="text" value=""/></td></tr> + </table> + <input type="submit"/> + </form> +</body> +</html> diff --git a/scripts/server/ice/testauth.py b/scripts/server/ice/testauth.py new file mode 100644 index 000000000..b165d6d2c --- /dev/null +++ b/scripts/server/ice/testauth.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 +import Ice, sys, time +from M2Crypto import X509; +Ice.loadSlice('', ['-I' + Ice.getSliceDir(), 'Murmur.ice']) +import Murmur + +class ServerAuthenticatorI(Murmur.ServerUpdatingAuthenticator): + def __init__(self, server, adapter): + self.server = server + + def authenticate(self, name, pw, certlist, certhash, strong, current=None): + print certhash, strong + for cert in certlist: + cert = X509.load_cert_der_string(cert) + print cert.get_subject(), "issued by", cert.get_issuer() + groups = ("GroupA", "GroupB"); + if (name == "One"): + if (pw == "Magic"): + return (1, "One", groups) + else: + return (-1, None, None) + elif (name == "Two"): + if (pw == "Mushroom"): + return (2, "twO", groups) + else: + return (-1, None, None) + elif (name == "White Space"): + if (pw == "Space White"): + return (3, "White Space", groups) + else: + return (-1, None, None) + elif (name == "Fail"): + time.sleep(6) + return (-2, None, None) + + def getInfo(self, id, current=None): + print "getInfo ", id + name = self.idToName(id); + if (name == None): + return (False, {}) + map = {} + map[Murmur.UserInfo.UserName]=name + return (True, map) + + def nameToId(self, name, current=None): + if (name == "One"): + return 1 + elif (name == "Twoer"): + return 2 + else: + return -2; + + def idToName(self, id, current=None): + if (id == 1): + return "One" + elif (id == 2): + return "Two" + else: + return None + + def idToTexture(self, id, current=None): + print "idToTexture", id + return open("../icons/mumble.osx.png").read(); + + # The expanded methods from UpdatingAuthenticator. We only implement a subset for this example, but + # a valid implementation has to define all of them + def registerUser(self, name, current=None): + print "Someone tried to register " + name[Murmur.UserInfo.UserName] + return -2 + + def unregisterUser(self, id, current=None): + print "Unregister ", id + return -2 + + def getRegistration(self, id, current=None): + return (-2, None, None) + + def setInfo(self, id, info, current=None): + print "Set", id, info + return -1 + +if __name__ == "__main__": + global contextR + + print "Creating callbacks...", + ice = Ice.initialize(sys.argv) + + meta = Murmur.MetaPrx.checkedCast(ice.stringToProxy('Meta:tcp -h 127.0.0.1 -p 6502')) + + adapter = ice.createObjectAdapterWithEndpoints("Callback.Client", "tcp -h 127.0.0.1") + adapter.activate() + + for server in meta.getBootedServers(): + serverR=Murmur.ServerUpdatingAuthenticatorPrx.uncheckedCast(adapter.addWithUUID(ServerAuthenticatorI(server, adapter))) + server.setAuthenticator(serverR) + + print "Done" + + map = {}; + map[Murmur.UserInfo.UserName] = 'TestUser'; + + for server in meta.getBootedServers(): + ids= server.getUserIds(["TestUser"]) + for name,id in ids.iteritems(): + if (id > 0): + print "Will unregister ", id + server.unregisterUser(id) + server.registerUser(map) + + print 'Script running (press CTRL-C to abort)'; + try: + ice.waitForShutdown() + except KeyboardInterrupt: + print 'CTRL-C caught, aborting' + + meta.removeCallback(metaR) + ice.shutdown() + print "Goodbye" diff --git a/scripts/server/ice/testcallback.py b/scripts/server/ice/testcallback.py new file mode 100644 index 000000000..3e1566350 --- /dev/null +++ b/scripts/server/ice/testcallback.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# -*- coding: utf-8 +import Ice, sys, sha +from M2Crypto import X509; + +Ice.loadSlice('', ['-I' + Ice.getSliceDir(), 'Murmur.ice']) +import Murmur + +class MetaCallbackI(Murmur.MetaCallback): + def started(self, s, current=None): + print "started" + serverR=Murmur.ServerCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerCallbackI(server, current.adapter))) + s.addCallback(serverR) + + def stopped(self, s, current=None): + print "stopped" + +class ServerCallbackI(Murmur.ServerCallback): + def __init__(self, server, adapter): + self.server = server + self.contextR=Murmur.ServerContextCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerContextCallbackI(server))) + + def userConnected(self, p, current=None): + print "connected" + print p + self.server.addContextCallback(p.session, "flubber", "Power up the T", self.contextR, Murmur.ContextChannel | Murmur.ContextUser) + if (self.server.hasPermission(p.session, 0, Murmur.PermissionWrite)): + print "Is a global admin" + certlist=self.server.getCertificateList(p.session) + for cert in certlist: + hash = sha.new() + hash.update(cert) + cert = X509.load_cert_der_string(cert) + print cert.get_subject(), "issued by", cert.get_issuer(), "hash", hash.hexdigest() + if current: + print current.ctx + + def userDisconnected(self, p, current=None): + print "disconnected" + print p + + def userStateChanged(self, p, current=None): + print "stateChanged" + print self.server + print p + + def userTextMessage(self, p, msg, current=None): + print "userTextMessage" + print self.server + print p + print msg + + def channelCreated(self, c, current=None): + print "created" + print c + + def channelRemoved(self, c, current=None): + print "removed" + print c + + def channelStateChanged(self, c, current=None): + print "stateChanged" + print c + +class ServerContextCallbackI(Murmur.ServerContextCallback): + def __init__(self, server): + self.server = server + + def contextAction(self, action, p, session, chanid, current=None): + print "aaand ACTION" + print action + print p + print session + print chanid + if (session != 0): + server.sendMessage(session, "Bouncy") + elif (chanid >= 0): + server.sendMessageChannel(chanid, 0, "Channel Bouncy") + +if __name__ == "__main__": + global contextR + + prop = Ice.createProperties(sys.argv) + prop.setProperty("Ice.ImplicitContext", "Shared") + + idd = Ice.InitializationData() + idd.properties = prop + + ice = Ice.initialize(idd) + + print "Creating callbacks...", + + # If icesecret is set, we need to set it here as well. + ice.getImplicitContext().put("secret", "fourtytwo") + + meta = Murmur.MetaPrx.checkedCast(ice.stringToProxy('Meta:tcp -h 127.0.0.1 -p 6502')) + adapter = ice.createObjectAdapterWithEndpoints("Callback.Client", "tcp -h 127.0.0.1") + + metaR=Murmur.MetaCallbackPrx.uncheckedCast(adapter.addWithUUID(MetaCallbackI())) + adapter.activate() + + meta.addCallback(metaR) + + for server in meta.getBootedServers(): + serverR=Murmur.ServerCallbackPrx.uncheckedCast(adapter.addWithUUID(ServerCallbackI(server, adapter))) + server.addCallback(serverR) + + print "Done" + print 'Script running (press CTRL-C to abort)'; + try: + ice.waitForShutdown() + except KeyboardInterrupt: + print 'CTRL-C caught, aborting' + + meta.removeCallback(metaR) + ice.shutdown() + print "Goodbye" diff --git a/scripts/server/ice/testdynamic.py b/scripts/server/ice/testdynamic.py new file mode 100644 index 000000000..639b81226 --- /dev/null +++ b/scripts/server/ice/testdynamic.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# -*- coding: utf-8 +import Ice, IcePy, sys, tempfile, os + +ice = Ice.initialize(sys.argv) + +proxy = ice.stringToProxy('Meta:tcp -h 127.0.0.1 -p 6502') + +try: + slice = IcePy.Operation('getSlice', Ice.OperationMode.Idempotent, Ice.OperationMode.Idempotent, True, (), (), (), IcePy._t_string, ()).invoke(proxy, ((), None)) + + (slicefiledesc, slicefilepath) = tempfile.mkstemp(suffix = '.ice') + slicefile = os.fdopen(slicefiledesc, 'w') + slicefile.write(slice) + slicefile.flush() + Ice.loadSlice('', ['-I' + Ice.getSliceDir(), slicefilepath]) + slicefile.close() + os.remove(slicefilepath) + + print 'Using dynamic slice' +except Exception: + Ice.loadSlice('', ['-I' + Ice.getSliceDir(), 'Murmur.ice']) + print 'Using bundled slice' + +import Murmur + +meta = Murmur.MetaPrx.checkedCast(proxy) + +print meta.getVersion() diff --git a/scripts/server/ice/weblist.php b/scripts/server/ice/weblist.php new file mode 100644 index 000000000..3f7f5cbdd --- /dev/null +++ b/scripts/server/ice/weblist.php @@ -0,0 +1,60 @@ +<html> +<head> +<title>Userlist</title> +</head> +<body> +<?php + +# +# Murmur.php is generated by calling +# slice2php /path/to/Murmur.ice +# in this directory +# + +if (Ice_intversion() >= 30400) { + if (!stream_resolve_include_path('Ice.php')) { + exit('The required file Ice.php could not be found in the PHP include path(s).'); + } + if (!stream_resolve_include_path('Murmur.php')) { + exit('The required file Murmur.php could not be found in the PHP include path(s).'); + } + require 'Ice.php'; + require 'Murmur.php'; +} else { + Ice_loadProfile(); +} + +try { + if (Ice_intversion() >= 30400) { + $ICE = Ice_initialize(); + } + + $base = $ICE->stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502"); + $meta = $base->ice_checkedCast("::Murmur::Meta"); + + $servers = $meta->getBootedServers(); + $default = $meta->getDefaultConf(); + foreach($servers as $s) { + $name = $s->getConf("registername"); + if (! $name) { + $name = $default["registername"]; + } + echo "<h1>SERVER #" . $s->id() . " " .$name ."</h1>\n"; + echo "<table><tr><th>Name</th><th>Channel</th></tr>\n"; + + $channels = $s->getChannels(); + $players = $s->getUsers(); + + foreach($players as $id => $state) { + $chan = $channels[$state->channel]; + echo "<tr><td>".$state->name."</td><td>".$chan->name."</td></tr>\n"; + } + echo "</table>\n"; + } +} catch (Ice_LocalException $ex) { + print_r($ex); +} + +?> +</body> +</html> |