]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'in_mem_user_list'
authorAndre <maan@meins.(none)>
Thu, 16 Nov 2006 18:43:29 +0000 (19:43 +0100)
committerAndre <maan@meins.(none)>
Thu, 16 Nov 2006 18:43:29 +0000 (19:43 +0100)
21 files changed:
Doxyfile
close_on_fork.c
command.c
configure.ac
crypt.c
crypt.h
dccp_send.c
error.h
grab_client.c
http_send.c
list.h
mysql_selector.c
ortp_send.c
playlist_selector.c
sched.c
server.c
server.h
stat.c
user_list.c [new file with mode: 0644]
user_list.h [new file with mode: 0644]
write.c

index b8d50d1302f855c2234a05a55c5711d1a2b56e19..ba35867d5c4b43ec5884aa219676f89f7d6a86c0 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -487,7 +487,7 @@ EXCLUDE_SYMLINKS       = NO
 # against the file with absolute path, so to exclude all test directories 
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS = list.h *.cmdline.* krell.* gui* SFont* write.c gcc-compat.h rc4.h recv.c para.h fade.c config.h sdl_gui.c filter.c slider.c dbadm.c
+EXCLUDE_PATTERNS = list.h *.cmdline.* krell.* gui* SFont* gcc-compat.h rc4.h recv.c para.h fade.c config.h sdl_gui.c filter.c slider.c dbadm.c
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or 
 # directories that contain example code fragments that are included (see 
index 74b419483ac78bb68115f20e40889cb5f4eb4862..722e7509cc3aa44db29a4067b94e58a682160cbf 100644 (file)
@@ -50,7 +50,7 @@ void add_close_on_fork_list(int fd)
                initialized = 1;
        }
        cof->fd = fd;
-       list_add(&cof->node, &close_on_fork_list);
+       para_list_add(&cof->node, &close_on_fork_list);
 }
 
 
index ad3f504103b4a773b392c25afe07be28e36dff2c..f096edcc37493bab7dbe8e4cab461da71dee50ce 100644 (file)
--- a/command.c
+++ b/command.c
@@ -19,7 +19,6 @@
 /** \file command.c does client authentication and executes server commands */
 
 #include <sys/time.h> /* gettimeofday */
-#include "crypt.h"
 #include "server.cmdline.h"
 #include "db.h"
 #include "server.h"
@@ -32,6 +31,7 @@
 #include "daemon.h"
 #include "string.h"
 #include "fd.h"
+#include "user_list.h"
 
 static RC4_KEY rc4_recv_key;
 static RC4_KEY rc4_send_key;
@@ -992,70 +992,6 @@ long int para_rand(long unsigned max)
        return (long int) ((max + 0.0) * (random() / (RAND_MAX + 1.0)));
 }
 
-/* Open user_list file, returns pointer to opened file on success,
- * NULL on errors
- */
-static FILE *open_user_list(char *file)
-{
-       PARA_DEBUG_LOG("opening user list %s\n", file);
-       return fopen(file, "r");
-}
-
-/*
- * lookup user in user_list file. Fills in a user struct containing
- * filename of the user's public key as well as the permissions of that user.
- * Returns 1 on success, 0 if user does not exist and < 0 on errors.
- */
-static int get_user(struct user *user) {
-       FILE *file_ptr;
-       char *char_ptr;
-       char line[MAXLINE];
-       /* keyword, user, key, perms */
-       char w[MAXLINE], n[MAXLINE], k[MAXLINE], p[MAXLINE], tmp[4][MAXLINE];
-       int num, ret;
-
-       file_ptr = open_user_list(user_list);
-       if (!file_ptr)
-               return -E_USERLIST;
-       for (;;) {
-               ret = para_fgets(line, MAXLINE, file_ptr);
-               if (ret < 0)
-                       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
-               if (ret <= 0)
-                       break;
-               if (sscanf(line,"%200s %200s %200s %200s", w, n, k, p) < 3)
-                       continue;
-               if (strcmp(w, "user") || strcmp(user->name, n))
-                       continue;
-               PARA_DEBUG_LOG("found entry for %s\n", n);
-               strcpy(user->name, n);
-               strcpy(user->pubkey_file, k);
-               user->perms = 0;
-               char_ptr = p;
-               num = sscanf(char_ptr, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]",
-                       tmp[0], tmp[1], tmp[2], tmp[3]);
-               PARA_DEBUG_LOG("found %i perm entries\n", num);
-               user->perms = 0;
-               while (num > 0) {
-                       num--;
-                       if (!strcmp(tmp[num], "AFS_READ"))
-                               user->perms = user->perms | AFS_READ;
-                       else if (!strcmp(tmp[num], "AFS_WRITE"))
-                               user->perms = user->perms | AFS_WRITE;
-                       else if (!strcmp(tmp[num], "DB_READ"))
-                               user->perms = user->perms | DB_READ;
-                       else if (!strcmp(tmp[num], "DB_WRITE"))
-                               user->perms = user->perms | DB_WRITE;
-                       else /* unknown permission */
-                               PARA_WARNING_LOG("unknown permission: %s\n",
-                                       tmp[num]);
-               }
-               break;
-       }
-       fclose(file_ptr);
-       return ret;
-}
-
 static void init_rc4_keys(void)
 {
        int i;
@@ -1119,23 +1055,21 @@ int handle_connect(int fd, struct sockaddr_in *addr)
                goto err_out;
 
        if (numbytes < 9 || strncmp(buf, "auth rc4 ", 9))
-               strcpy(u.name, buf + 5); /* client version < 0.2.6 */
+               u.name = para_strdup(buf + 5); /* client version < 0.2.6 */
        else {
-               strcpy(u.name, buf + 9); /* client version >= 0.2.6 */
+               u.name = para_strdup(buf + 9); /* client version >= 0.2.6 */
                use_rc4 = 1;
        }
-//     strcpy(u.name, buf + 5); /* ok, but ugly */
        PARA_DEBUG_LOG("received %s request for user %s\n",
                use_rc4? "rc4" : "auth", u.name);
-       /* lookup user in list file */
-       if ((ret = get_user(&u)) < 0)
+       if ((ret = lookup_user(&u)) < 0)
                goto err_out;
        if (!ret) { /* user not found */
                PARA_WARNING_LOG("auth request for unknown user %s\n", u.name);
                ret = -E_BAD_USER;
                goto err_out;
        }
-       ret = para_encrypt_challenge(u.pubkey_file, challenge_nr, crypt_buf);
+       ret = para_encrypt_challenge(u.rsa, challenge_nr, crypt_buf);
        if (ret <= 0)
                goto err_out;
        numbytes = ret;
@@ -1160,7 +1094,7 @@ int handle_connect(int fd, struct sockaddr_in *addr)
        sprintf(buf, "%s", PROCEED_MSG);
        if (use_rc4) {
                init_rc4_keys();
-               ret = para_encrypt_buffer(u.pubkey_file, rc4_buf, 2 * RC4_KEY_LEN,
+               ret = para_encrypt_buffer(u.rsa, rc4_buf, 2 * RC4_KEY_LEN,
                        (unsigned char *)buf + PROCEED_MSG_LEN + 1);
                if (ret <= 0)
                        goto err_out;
index efd27d4e518be5782045408b9d4be4cb42b05ce3..faa5d4addcd8a7c153f706c208d0b8afee283137 100644 (file)
@@ -83,7 +83,7 @@ audiod_audio_formats=""
 server_cmdline_objs="server.cmdline"
 server_errlist_objs="server mp3_afh afs command net string signal random_selector
        time daemon stat crypt http_send db close_on_fork playlist_selector
-       ipc dccp dccp_send fd"
+       ipc dccp dccp_send fd user_list"
 server_ldflags=""
 server_audio_formats=" mp3"
 
diff --git a/crypt.c b/crypt.c
index 653b1a2452cdc85215d916c1abd35f641800dcf1..cf1cabecbad80cdca6d69cf2bbc2165427a84ed8 100644 (file)
--- a/crypt.c
+++ b/crypt.c
 
 /** \file crypt.c openssl-based RSA encryption/decryption routines */
 
-#include <openssl/pem.h>
 #include "para.h"
 #include "error.h"
 #include "string.h"
-
-/** \cond used to distinguish between loading of private/public key */
-#define LOAD_PUBLIC_KEY 0
-#define LOAD_PRIVATE_KEY 1
-/** \endcond **/
+#include "crypt.h"
 
 static EVP_PKEY *load_key(const char *file, int private)
 {
@@ -46,7 +41,8 @@ static EVP_PKEY *load_key(const char *file, int private)
        return pkey;
 }
 
-static int get_key(char *key_file, RSA **rsa, int private)
+
+int get_rsa_key(char *key_file, RSA **rsa, int private)
 {
        EVP_PKEY *key = load_key(key_file, private);
 
@@ -77,7 +73,7 @@ int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *in
                        int rsa_inlen)
 {
        RSA *rsa;
-       int ret = get_key(key_file, &rsa, LOAD_PRIVATE_KEY);
+       int ret = get_rsa_key(key_file, &rsa, LOAD_PRIVATE_KEY);
 
        if (ret < 0)
                return ret;
@@ -115,7 +111,7 @@ int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr,
 /**
  * encrypt a buffer using an RSA key
  *
- * \param key_file full path of the rsa key
+ * \param rsa: public rsa key
  * \param inbuf the input buffer
  * \param len the length of \a inbuf
  * \param outbuf the output buffer
@@ -124,22 +120,18 @@ int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr,
  *
  * \sa RSA_public_encrypt(3)
  */
-int para_encrypt_buffer(char *key_file, unsigned char *inbuf,
+int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf,
                const unsigned len, unsigned char *outbuf)
 {
-       RSA *rsa;
-       int ret = get_key(key_file, &rsa, LOAD_PUBLIC_KEY);
-
-       if (ret < 0)
-               return ret;
-       ret = RSA_public_encrypt(len, inbuf, outbuf, rsa, RSA_PKCS1_PADDING);
+       int ret = RSA_public_encrypt(len, inbuf, outbuf, rsa,
+               RSA_PKCS1_PADDING);
        return ret < 0?  -E_ENCRYPT : ret;
 }
 
 /**
  * encrypt the given challenge number
  *
- * \param key_file full path of the rsa key
+ * \param rsa: public rsa key
  * \param challenge_nr the number to be encrypted
  * \param outbuf the output buffer
  *
@@ -150,11 +142,11 @@ int para_encrypt_buffer(char *key_file, unsigned char *inbuf,
  * \sa para_encrypt_buffer()
  *
  */
-int para_encrypt_challenge(char *key_file, long unsigned challenge_nr,
+int para_encrypt_challenge(RSA* rsa, long unsigned challenge_nr,
        unsigned char *outbuf)
 {
        unsigned char *inbuf = (unsigned char*) make_message("%lu", challenge_nr);
-       int ret = para_encrypt_buffer(key_file, inbuf, strlen((char *)inbuf), outbuf);
+       int ret = para_encrypt_buffer(rsa, inbuf, strlen((char *)inbuf), outbuf);
        free(inbuf);
        return ret;
 }
diff --git a/crypt.h b/crypt.h
index 82ed4f9dc42face7d7a3cfda25b1a154e341edd8..2f51ff52977d0f413ab7cfb5eb9384524289adb7 100644 (file)
--- a/crypt.h
+++ b/crypt.h
@@ -1,9 +1,35 @@
+/*
+ * Copyright (C) 2005-2006 Andre Noll <maan@systemlinux.org>
+ *
+ *     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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ */
+
 /** \file crypt.h prototypes for the RSA crypt functions */
+
+#include <openssl/pem.h>
 int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr,
        unsigned char *buf, int rsa_inlen);
-int para_encrypt_challenge(char *key_file, long unsigned challenge_nr,
+int para_encrypt_challenge(RSA* rsa, long unsigned challenge_nr,
        unsigned char *outbuf);
-int para_encrypt_buffer(char *key_file, unsigned char *inbuf, const unsigned len,
+int para_encrypt_buffer(RSA* rsa, unsigned char *inbuf, const unsigned len,
        unsigned char *outbuf);
 int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *inbuf,
        int rsa_inlen);
+int get_rsa_key(char *key_file, RSA **rsa, int private);
+
+/** \cond used to distinguish between loading of private/public key */
+#define LOAD_PUBLIC_KEY 0
+#define LOAD_PRIVATE_KEY 1
+/** \endcond **/
index bb46678e8cdd84bd58cbc609b1c8e19252407d7a..273961fcf908fdfbc6faa2b953210930a48fae5e 100644 (file)
@@ -76,7 +76,7 @@ static void dccp_post_select(fd_set *rfds, __a_unused fd_set *wfds)
        }
        PARA_NOTICE_LOG("connection from %s\n", inet_ntoa(dc->addr.sin_addr));
        dc->fd = ret;
-       list_add(&dc->node, &clients);
+       para_list_add(&dc->node, &clients);
        add_close_on_fork_list(dc->fd);
        mark_fd_nonblock(dc->fd);
 }
diff --git a/error.h b/error.h
index 05efb790aab78184c58e23829603270e41392ca6..b94139e38b013cec2bd5cbbcb954f04ee2708c72 100644 (file)
--- a/error.h
+++ b/error.h
@@ -74,6 +74,7 @@ enum para_subsystem {
        SS_ALSA_WRITE,
        SS_FILE_WRITE,
        SS_OSX_WRITE,
+       SS_USER_LIST,
        NUM_SS
 };
 
@@ -94,6 +95,11 @@ enum para_subsystem {
 extern const char **para_errlist[];
 /** \endcond */
 
+#define USER_LIST_ERRORS \
+       PARA_ERROR(USERLIST, "failed to open user list file"), \
+       PARA_ERROR(BAD_USER, "you don't exist. Go away."), \
+
+
 #define OSX_WRITE_ERRORS \
        PARA_ERROR(STREAM_FORMAT, "could not set stream format"), \
        PARA_ERROR(ADD_CALLBACK, "can not add callback"), \
@@ -354,8 +360,6 @@ extern const char **para_errlist[];
        PARA_ERROR(NO_AUDIO_FILE, "no audio file"), \
        PARA_ERROR(BAD_CMD, "invalid command"), \
        PARA_ERROR(PERM, "permission denied"), \
-       PARA_ERROR(USERLIST, "failed to open user list file"), \
-       PARA_ERROR(BAD_USER, "you don't exist. Go away."), \
        PARA_ERROR(LOCK, "lock error"), \
        PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \
        PARA_ERROR(SERVER_CRASH, "para_server crashed -- can not live without it"), \
@@ -571,6 +575,7 @@ SS_ENUM(RINGBUFFER);
 SS_ENUM(CLIENT);
 SS_ENUM(CLIENT_COMMON);
 SS_ENUM(AUDIOC);
+SS_ENUM(USER_LIST);
 /** \endcond */
 #undef PARA_ERROR
 /* rest of the world only sees the error text */
index 70b95f4f655b174db266809428f5f0667e6bc2e2..50594f238aeb5d579c6cb0c627fb3c4b5fe51f4a 100644 (file)
@@ -33,6 +33,7 @@
 #include "error.h"
 #include "string.h"
 #include "fd.h"
+#include "crypt.h"
 
 /** grab clients that are not yet attached to a filter node */
 struct list_head inactive_grab_client_list;
@@ -123,7 +124,7 @@ static void add_inactive_gc(struct grab_client *gc)
 {
        PARA_INFO_LOG("adding grab client %p (fd %d) to inactive list\n",
                gc, gc->fd);
-       list_add(&gc->node, &inactive_grab_client_list);
+       para_list_add(&gc->node, &inactive_grab_client_list);
 }
 
 static void gc_free(struct grab_client *gc)
@@ -164,7 +165,7 @@ void activate_grab_client(struct grab_client *gc, struct filter_node *fn)
 {
        PARA_INFO_LOG("activating %p (fd %d, filter node: %p)\n", gc, gc->fd, fn);
        list_del(&gc->node);
-       list_add(&gc->fcb.node, &fn->callbacks);
+       para_list_add(&gc->fcb.node, &fn->callbacks);
 }
 
 /**
index 1d970a5df561a3395effa19abf0960a70af9c3ef..f06a5ac258e9a36c88cc9d9dd26acaede6fe2029 100644 (file)
@@ -323,7 +323,7 @@ static void http_post_select(fd_set *rfds, fd_set *wfds)
        PARA_INFO_LOG("accepted client #%d: %s (fd %d)\n", numclients,
                CLIENT_ADDR(hc), hc->fd);
        numclients++;
-       list_add(&hc->node, &clients);
+       para_list_add(&hc->node, &clients);
        add_close_on_fork_list(hc->fd);
        mark_fd_nonblock(hc->fd);
        return;
@@ -432,7 +432,7 @@ static void add_perm_list_entry(struct sender_command_data *scd)
        ai->netmask = scd->netmask;
        PARA_INFO_LOG("adding %s/%i to access list\n", inet_ntoa(ai->addr),
                ai->netmask);
-       list_add(&ai->node, &access_perm_list);
+       para_list_add(&ai->node, &access_perm_list);
 }
 
 static int http_com_deny(struct sender_command_data *scd)
diff --git a/list.h b/list.h
index c85f50c7e79c45f8ae47ab0e721763044e80d09f..486b9170e0001d59c68b3ec34d7f6b33356df76f 100644 (file)
--- a/list.h
+++ b/list.h
@@ -56,14 +56,15 @@ static inline void __list_add(struct list_head *new,
 }
 
 /**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
+ * add a new entry
+ *
+ * \param new: new entry to be added
+ * \param head: list head to add it after
  *
  * Insert a new entry after the specified head.
  * This is good for implementing stacks.
  */
-static inline void list_add(struct list_head *new, struct list_head *head)
+static inline void para_list_add(struct list_head *new, struct list_head *head)
 {
        __list_add(new, head, head->next);
 }
@@ -115,7 +116,7 @@ static inline void list_del(struct list_head *entry)
 static inline void list_move(struct list_head *list, struct list_head *head)
 {
         __list_del(list->prev, list->next);
-        list_add(list, head);
+        para_list_add(list, head);
 }
 
 /**
index 51273644413ec0b67c4d100281857a023bac5d77..9363dba45c0b7a031adf5f9e0b64326243ee0b1a 100644 (file)
@@ -31,6 +31,7 @@
 #include "error.h"
 #include "net.h"
 #include "string.h"
+#include "user_list.h"
 
 /** pointer to the shared memory area */
 extern struct misc_meta_data *mmd;
index 15b97eb1304caaf2ec1198acde6252dd1bc10ee3..4dd19d7d2cb183743ff0dee435692c44eff43e16 100644 (file)
@@ -249,7 +249,7 @@ static void ortp_add_target(int port, struct in_addr *addr)
        ot->addr = *addr;
        PARA_INFO_LOG("adding to target list (%s:%d)\n",
                TARGET_ADDR(ot), ot->port);
-       list_add(&ot->node, &targets);
+       para_list_add(&ot->node, &targets);
 }
 
 static int ortp_com_add(struct sender_command_data *scd)
index b925453ec203234a799bbd124c5c60019b71f9dc..010c9d21e05a6bbde2092e6433d458d65e7657c7 100644 (file)
@@ -24,6 +24,7 @@
 #include "net.h"
 #include "string.h"
 #include "ipc.h"
+#include "user_list.h"
 
 /**
  * structure used for transmission of the playlist
diff --git a/sched.c b/sched.c
index c2a0e64b16326c5ce4f28b20cb4a048ae6322d30..e122903e8e46823ed2a4b987cf3264782ca3040e 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -125,11 +125,11 @@ void register_task(struct task *t)
        PARA_INFO_LOG("registering %s (%p)\n", t->status, t);
        if (t->pre_select) {
                PARA_DEBUG_LOG("pre_select: %p\n", &t->pre_select);
-               list_add(&t->pre_select_node, &pre_select_list);
+               para_list_add(&t->pre_select_node, &pre_select_list);
        }
        if (t->post_select) {
                PARA_DEBUG_LOG("post_select: %p\n", &t->pre_select);
-               list_add(&t->post_select_node, &post_select_list);
+               para_list_add(&t->post_select_node, &post_select_list);
        }
 }
 
index 9688c6ccf2cb4ac29723b0a8dd6f40627c16d934..2cbc5a7197e11ebc0305e97c218976e728745e54 100644 (file)
--- a/server.c
+++ b/server.c
@@ -42,6 +42,7 @@
 #include "string.h"
 #include "ipc.h"
 #include "fd.h"
+#include "user_list.h"
 
 /** define the array of error lists needed by para_server */
 INIT_SERVER_ERRLISTS;
@@ -57,7 +58,7 @@ struct misc_meta_data *mmd;
  * senders.
 */
 struct server_args_info conf;
-char *user_list = NULL;
+char *user_list_file = NULL;
 extern void dccp_send_init(struct sender *);
 extern void http_send_init(struct sender *);
 extern void ortp_send_init(struct sender *);
@@ -221,11 +222,11 @@ static void parse_config(int override)
                cf = conf.config_file_arg;
        else
                cf = make_message("%s/.paraslash/server.conf", home);
-       free(user_list);
+       free(user_list_file);
        if (!conf.user_list_given)
-               user_list = make_message("%s/.paraslash/server.users", home);
+               user_list_file = make_message("%s/.paraslash/server.users", home);
        else
-               user_list = para_strdup(conf.user_list_arg);
+               user_list_file = para_strdup(conf.user_list_arg);
        ret = stat(cf, &statbuf);
        if (ret && conf.config_file_given) {
                ret = -1;
@@ -251,8 +252,8 @@ out:
        free(home);
        if (ret > 0)
                return;
-       free(user_list);
-       user_list = NULL;
+       free(user_list_file);
+       user_list_file = NULL;
        exit(EXIT_FAILURE);
 }
 
@@ -353,6 +354,7 @@ static unsigned do_inits(int argc, char **argv)
        log_welcome("para_server", conf.loglevel_arg);
        shm_init(); /* init mmd struct */
        server_uptime(UPTIME_SET); /* reset server uptime */
+       init_user_list(user_list_file);
        /* become daemon */
        if (conf.daemon_given)
                daemon_init();
@@ -398,6 +400,7 @@ static void handle_sighup(void)
        parse_config(1); /* reopens log */
        mmd->selector_change = mmd->selector_num; /* do not change selector.. */
        change_selector(); /* .. just reload */
+       init_user_list(user_list_file); /* reload user list */
 }
 
 static void status_refresh(void)
index 9d18561e0f8e1eb20300759cc597970795abe887..1648acfe700b9486860087cb75cea73ff9d47a0e 100644 (file)
--- a/server.h
+++ b/server.h
 /** \file server.h common server data structures */
 
 #include "para.h"
-
+#include "list.h"
+#include <openssl/pem.h>
 
 /** size of the selector_info and audio_file info strings of struct misc_meta_data */
 #define MMD_INFO_SIZE 16384
 
-/**
- * permission flags that can be set individually for any server command
- *
- * - DB_READ: command reads from the database
- * - DB_WRITE: command changes the contents of the database
- * - AFS_READ: command reads information about the current audio stream
- * - AFS_WRITE: command changes the current audio stream
- */
-enum {DB_READ = 1, DB_WRITE = 2, AFS_READ = 4, AFS_WRITE = 8};
-
-/**
- * data needed to authenticate the user
- */
-struct user{
-/** the username */
-       char name[MAXLINE];
-/** full path to the public RSA key */
-       char pubkey_file[_POSIX_PATH_MAX];
-/** the privileges of this user */
-       unsigned int perms;
-};
-
 /**
  * defines one command of para_server
  */
diff --git a/stat.c b/stat.c
index 8220fd27f3233499baa9d40035af1cbb2f797995..caf432d9748ca3b5e293657359a17ca98f5b8559 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -123,7 +123,7 @@ int stat_client_add(int fd, long unsigned mask)
        new_client = para_malloc(sizeof(struct stat_client));
        new_client->fd = fd;
        new_client->item_mask = mask;
-       list_add(&new_client->node, &client_list);
+       para_list_add(&new_client->node, &client_list);
        dump_stat_client_list();
        num_clients++;
        return 1;
diff --git a/user_list.c b/user_list.c
new file mode 100644 (file)
index 0000000..abd47e1
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
+ *
+ *     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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ */
+
+/** \file user_list.c user handling for para_server */
+
+#include "para.h"
+#include "error.h"
+#include "fd.h"
+#include "string.h"
+#include "user_list.h"
+
+static struct list_head user_list;
+
+/*
+ * lookup user in user list file. Fills in a user struct containing
+ * filename of the user's public key as well as the permissions of that user.
+ * Returns 1 on success, 0 if user does not exist and < 0 on errors.
+ */
+static void populate_user_list(char *user_list_file)
+{
+       FILE *file_ptr = NULL;
+       char *char_ptr;
+       char line[MAXLINE];
+       /* keyword, user, key, perms */
+       char w[MAXLINE], n[MAXLINE], k[MAXLINE], p[MAXLINE], tmp[4][MAXLINE];
+       int num, ret;
+
+       file_ptr = fopen(user_list_file, "r");
+       ret = -E_USERLIST;
+       if (!file_ptr)
+               goto out;
+       for (;;) {
+               struct user *u;
+               ret = para_fgets(line, MAXLINE, file_ptr);
+               if (ret < 0)
+                       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               if (ret <= 0)
+                       break;
+               if (sscanf(line,"%200s %200s %200s %200s", w, n, k, p) < 3)
+                       continue;
+               if (strcmp(w, "user"))
+                       continue;
+               PARA_DEBUG_LOG("found entry for %s\n", n);
+               u = para_malloc(sizeof(struct user));
+               u->name = para_strdup(n);
+               u->rsa = para_malloc(sizeof(RSA));
+               ret = get_rsa_key(k, &u->rsa, LOAD_PUBLIC_KEY);
+               if (ret < 0)
+                       break;
+               u->perms = 0;
+               char_ptr = p;
+               num = sscanf(char_ptr, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]",
+                       tmp[0], tmp[1], tmp[2], tmp[3]);
+               PARA_DEBUG_LOG("found %i perm entries\n", num);
+               u->perms = 0;
+               while (num > 0) {
+                       num--;
+                       if (!strcmp(tmp[num], "AFS_READ"))
+                               u->perms |= AFS_READ;
+                       else if (!strcmp(tmp[num], "AFS_WRITE"))
+                               u->perms |= AFS_WRITE;
+                       else if (!strcmp(tmp[num], "DB_READ"))
+                               u->perms |= DB_READ;
+                       else if (!strcmp(tmp[num], "DB_WRITE"))
+                               u->perms |= DB_WRITE;
+                       else /* unknown permission */
+                               PARA_WARNING_LOG("unknown permission: %s\n",
+                                       tmp[num]);
+               }
+               para_list_add(&u->node, &user_list);
+       }
+out:
+       if (file_ptr)
+               fclose(file_ptr);
+       if (ret >= 0)
+               return;
+       PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+       exit(EXIT_FAILURE);
+}
+
+void init_user_list(char *user_list_file)
+{
+       struct user *u, *tmp;
+       static int initialized;
+
+       if (initialized) {
+               list_for_each_entry_safe(u, tmp, &user_list, node) {
+                       list_del(&u->node);
+                       free(u->name);
+                       free(u->rsa);
+                       free(u);
+               }
+       } else
+               INIT_LIST_HEAD(&user_list);
+       initialized = 1;
+       populate_user_list(user_list_file);
+}
+
+/**
+ * lookup user in user_list.
+ *
+ * \param user: must initially contain the name of the user and is filled
+ * in by this function on success.
+ *
+ * \return 1 on success and < 0 on errors.
+ */
+int lookup_user(struct user *user)
+{
+       struct user *u;
+       list_for_each_entry(u, &user_list, node) {
+               if (strcmp(u->name, user->name))
+                       continue;
+               *user = *u;
+               return 1;
+       }
+       return -E_BAD_USER;
+}
diff --git a/user_list.h b/user_list.h
new file mode 100644 (file)
index 0000000..507ea02
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
+ *
+ *     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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ */
+
+/** \file user_list.h exported functions from user_list.c */
+
+#include "list.h"
+#include "crypt.h"
+
+/**
+ * permission flags that can be set individually for any server command
+ *
+ * - DB_READ: command reads from the database
+ * - DB_WRITE: command changes the contents of the database
+ * - AFS_READ: command reads information about the current audio stream
+ * - AFS_WRITE: command changes the current audio stream
+ */
+enum {DB_READ = 1, DB_WRITE = 2, AFS_READ = 4, AFS_WRITE = 8};
+
+/**
+ * data needed to authenticate the user
+ */
+struct user {
+       /** the position of this user in the list of users */
+       struct list_head node;
+       /** the username */
+       char *name;
+       /**  the public RSA key */
+       RSA *rsa;
+       /** the privileges that this user has */
+       unsigned int perms;
+};
+
+void init_user_list(char *user_list_file);
+int lookup_user(struct user *user);
diff --git a/write.c b/write.c
index 7f29665de46f0844589e36a144e4b61848dda79b..ec27f3d35ac078824e03f33c3ba38572177ef38d 100644 (file)
--- a/write.c
+++ b/write.c
@@ -16,6 +16,8 @@
  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  */
 
+/** \file write.c Paraslash's standalone wav/raw player */
+
 #include "para.h"
 #include "string.h"
 #include "write.cmdline.h"
 
 INIT_WRITE_ERRLISTS;
 
+/**
+ * check if given buffer contains a valid wave header
+ */
 struct check_wav_task {
+       /** the buffer to check */
        char *buf;
+       /** number of bytes loaded in \a buf */
        size_t *loaded;
+       /** non-zero if end of file was reached */
        int *eof;
+       /** number of channels specified in wav header given by \a buf */
        unsigned channels;
+       /** samplerate specified in wav header given by \a buf */
        unsigned samplerate;
+       /** the task structure for this task */
        struct task task;
 };
 
+/**
+ * delay writing until given time
+ */
 struct initial_delay_task {
+       /** the time the first data should be written out */
        struct timeval start_time;
+       /** the task structure for this task */
        struct task task;
 };
 
 static struct write_args_info conf;
-struct stdin_task sit;
-struct check_wav_task cwt;
-struct initial_delay_task idt;
+static struct stdin_task sit;
+static struct check_wav_task cwt;
+static struct initial_delay_task idt;
 static struct writer_node_group *wng;
 
+/** length of a standard wav header */
 #define WAV_HEADER_LEN 44
 
 /**
@@ -96,6 +113,12 @@ static void initial_delay_pre_select(struct sched *s, struct task *t)
                s->timeout = diff;
 }
 
+/**
+ * all log messages are written to stderr
+ *
+ * \param ll: loglevel
+ * \param fmt: format string
+ */
 void para_log(int ll, const char* fmt,...)
 {
        va_list argp;
@@ -205,6 +228,13 @@ static void cwt_event_handler(struct task *t)
        register_task(&idt.task);
 }
 
+/**
+ * para_write's main function
+ *
+ * It registers the stdin task, the check_wav_task, the task for initial delay
+ * and all tasks for actually writing out the stream.
+ *
+ */
 int main(int argc, char *argv[])
 {
        int ret = -E_WRITE_SYNTAX;