Index: doc/jackd_acl.txt =================================================================== --- doc/jackd_acl.txt (revision 0) +++ doc/jackd_acl.txt (revision 0) @@ -0,0 +1,49 @@ +Hello. + +First a few words. +Basically i wrote the jackd port connection acl system to +be able to deny some clients the ability to make some port +connections. Its a really simple system, and so without further +delay, here is an explanation. + +first off, where is the config file? well. by default jackd +will try to open $HOME/.jackd_acl, however you can specify +the file to use by setting the JACKD_ACL environment variable. + +The way it works, is that in your acl file, you specify a rule +to match the source, and a rule to match the destination, and +if it should be allowed ot denied. The default policy if no +rules matches, is to allow. if there is a rule which allows it, +that is irrecovable, so that you can do a deny all, allow some +setup. It matches the entire name of the port(including client) +like this: "xine:out_R". +So, its time for an example: + +---------------------- +@deny +* +system:* + +@allow +xine* +system:playback_1 + +@allow +mplayer*:out_1 +system:playback_2 +---------------------- + +what this will do, is to deny every client/port access to system: +and then specifically allow xine to connect any of its ports only +to system:playback_1, and allow only mplayer's out_1 port to +connect to only system:playback_2. + +It doesent use regex yet, all it can do is glob checking. +(check man 3 fnmatch for more info.) + +To reload the config file, you can send it the SIHUP signal like +this: "killall -HUP jackd". + +Copyright (C) Kasper Sandberg, 2007. + +Document under GNU Free Document License(latest version as of 2007-05-31) Property changes on: doc/jackd_acl.txt ___________________________________________________________________ Name: svn:eol-style + native Index: jackd/portacl.c =================================================================== --- jackd/portacl.c (revision 0) +++ jackd/portacl.c (revision 0) @@ -0,0 +1,120 @@ +/* + Copyright (C) 2007 Kasper Sandberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include // to be replaced with regex.h and fullblown posix regular expressions +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "portacl.h" + +jack_port_connection_acl_t * jack_port_connection_acls = NULL; +int jack_port_connection_num_acls = 0; +pthread_rwlock_t aclloadmutex = PTHREAD_RWLOCK_INITIALIZER; + +void jack_load_port_connection_acl_file() +{ + FILE * fp = NULL; + char * line = NULL; + size_t len = 0; + ssize_t read = 0; + + char * name = getenv( "JACKD_ACL" ); + + if( NULL == name ) + { + name = getenv( "HOME" ); + + if( NULL == name ) + return; + + char * cfile = malloc( strlen( name ) + 12 ); + strcpy( cfile, name ); + + cfile = strcat( cfile, "/.jackd_acl" ); + fp = fopen( cfile, "r" ); + free( cfile ); + } else + fp = fopen( name, "r" ); + + if( NULL == fp ) + return; + + jack_port_connection_acl_t * new_port_connection_acls = NULL; + int new_port_connection_num_acls = 0; + + while( ( read = getline( &line, &len, fp ) ) != -1 ) + { + short allow; + if( fnmatch( "@allow*", line, 0 ) == 0 ) + allow = 1; + else if( fnmatch( "@deny*", line, 0 ) == 0 ) + allow = 0; + else + continue; + + jack_port_connection_acl_t entry; + if( ( read = getline( &line, &len, fp ) ) != -1 ) { + entry.sourcematch = malloc( strlen( line ) ); + memcpy( (void *) entry.sourcematch, line, strlen( line ) ); + entry.sourcematch[ strlen( line ) -1 ] = 0 ; + } else + break; + + if( ( read = getline( &line, &len, fp ) ) != -1 ) { + entry.destmatch = malloc( strlen( line ) ); + memcpy( (void *) entry.destmatch, line, strlen( line ) ); + entry.destmatch[ strlen( line ) - 1 ] = 0; + } else { + free( (void *) entry.sourcematch ); + break; + } + + entry.allow = allow; + + new_port_connection_acls = realloc( new_port_connection_acls, sizeof( jack_port_connection_acl_t ) * ++new_port_connection_num_acls ); + new_port_connection_acls[ new_port_connection_num_acls - 1 ] = entry; + printf( "\nelem: '%s' '%s' '%i'\n", entry.sourcematch, entry.destmatch, entry.allow ); + + } + free( line ); + fclose( fp ); + + pthread_rwlock_wrlock( &aclloadmutex ); + + jack_port_connection_acl_t * old_port_connection_acls = jack_port_connection_acls; + int old_port_connection_num_acls = jack_port_connection_num_acls; + + jack_port_connection_acls = new_port_connection_acls; + jack_port_connection_num_acls = new_port_connection_num_acls; + + pthread_rwlock_unlock( &aclloadmutex ); + + if( NULL != old_port_connection_acls && old_port_connection_num_acls > 0 ) { + int i; + for( i = 0 ; i < old_port_connection_num_acls ; i++ ) + { + free( (void *) old_port_connection_acls[ i ].sourcematch ); + free( (void *) old_port_connection_acls[ i ].destmatch ); + } + free( old_port_connection_acls ); + old_port_connection_acls = NULL; + } +} Property changes on: jackd/portacl.c ___________________________________________________________________ Name: svn:eol-style + native Index: jackd/engine.c =================================================================== --- jackd/engine.c (revision 1043) +++ jackd/engine.c (working copy) @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2004 Jack O'Quin + Copyright (C) 2007 Kasper Sandberg (port acl parts) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +30,7 @@ #include #include #include +#include #include #ifdef HAVE_STDINT_H #include @@ -60,6 +62,7 @@ #include "clientengine.h" #include "transengine.h" +#include "portacl.h" typedef struct { @@ -3003,6 +3006,40 @@ } } + // Begin redeeman jackhack :) + pthread_rwlock_rdlock( &aclloadmutex ); + if( jack_port_connection_num_acls > 0 ) + { + int IsAllowed = 0; // 0 = default allowed, 1 = disallowed, 2 = irevocably allowed + int i = 0; + for( i = 0 ; i < jack_port_connection_num_acls ; i++ ) + { + if( fnmatch( jack_port_connection_acls[ i ].sourcematch, source_port, 0 ) == 0 ) + { + if( fnmatch( jack_port_connection_acls[ i ].destmatch, destination_port, 0 ) == 0 ) + { + if( jack_port_connection_acls[ i ].allow == 1 ) + { + printf( "Irrecovably allowed: %s -> %s\n", source_port, destination_port ); + IsAllowed = 2; + break; + } + else if( IsAllowed != 2 ) { + printf( "Disallowed: %s -> %s\n", source_port, destination_port ); + IsAllowed = 1; + } + } + } + } + if( IsAllowed == 1 ) + { + pthread_rwlock_unlock( &aclloadmutex ); + return -1; + } + } + pthread_rwlock_unlock( &aclloadmutex ); + // End jackhack + connection = (jack_connection_internal_t *) malloc (sizeof (jack_connection_internal_t)); Index: jackd/portacl.h =================================================================== --- jackd/portacl.h (revision 0) +++ jackd/portacl.h (revision 0) @@ -0,0 +1,37 @@ +/* + Copyright (C) 2007 Kasper Sandberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __jack_portacl_h__ +#define __jack_portacl_h__ + +#include + +typedef struct _jack_port_connection_acl_t { + char * sourcematch; + char * destmatch; + short allow; +} jack_port_connection_acl_t; + +extern jack_port_connection_acl_t * jack_port_connection_acls; +extern int jack_port_connection_num_acls; + +extern pthread_rwlock_t aclloadmutex; + +void jack_load_port_connection_acl_file(); + +#endif Property changes on: jackd/portacl.h ___________________________________________________________________ Name: svn:eol-style + native Index: jackd/jackd.c =================================================================== --- jackd/jackd.c (revision 1043) +++ jackd/jackd.c (working copy) @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ #include #include +#include "portacl.h" + #ifdef USE_CAPABILITIES #include @@ -192,6 +195,9 @@ fprintf (stderr, "jack main caught signal %d\n", sig); switch (sig) { + case SIGHUP: + jack_load_port_connection_acl_file(); + break; case SIGUSR1: jack_dump_configuration(engine, 1); break; @@ -690,6 +696,10 @@ copyright (stdout); + // Load the config acl (perhaps make this a a jackd parameter?) + // i believe this is early enough to be 100% sure + jack_load_port_connection_acl_file(); + rc = jack_register_server (server_name); switch (rc) { case EEXIST: @@ -722,6 +732,10 @@ if (verbose) fprintf (stderr, "cleaning up files\n"); jack_cleanup_files (server_name); + + // need to check if its locked? + pthread_rwlock_destroy( &aclloadmutex ); + if (verbose) fprintf (stderr, "unregistering server `%s'\n", server_name); jack_unregister_server (server_name); Index: jackd/Makefile.am =================================================================== --- jackd/Makefile.am (revision 1043) +++ jackd/Makefile.am (working copy) @@ -23,10 +23,10 @@ AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" -jackd_SOURCES = jackd.c engine.c clientengine.c transengine.c +jackd_SOURCES = portacl.c jackd.c engine.c clientengine.c transengine.c jackd_LDADD = ../libjack/libjack.la $(CAP_LIBS) @OS_LDFLAGS@ noinst_HEADERS = jack_md5.h md5.h md5_loc.h \ - clientengine.h transengine.h + clientengine.h transengine.h portacl.h BUILT_SOURCES = jack_md5.h