initialized = 1;
}
cof->fd = fd;
- list_add(&cof->node, &close_on_fork_list);
+ para_list_add(&cof->node, &close_on_fork_list);
}
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);
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;
const unsigned len, unsigned char *outbuf)
{
RSA *rsa;
- int ret = get_key(key_file, &rsa, LOAD_PUBLIC_KEY);
+ int ret = get_rsa_key(key_file, &rsa, LOAD_PUBLIC_KEY);
if (ret < 0)
return ret;
+#include <openssl/pem.h>
/** \file crypt.h prototypes for the RSA crypt functions */
int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr,
unsigned char *buf, int rsa_inlen);
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);
}
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);
}
#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;
{
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)
{
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);
}
/**
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;
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)
}
/**
- * 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);
}
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);
}
/**
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)
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);
}
}
#include "string.h"
#include "ipc.h"
#include "fd.h"
+#include "crypt.h"
/** define the array of error lists needed by para_server */
INIT_SERVER_ERRLISTS;
*/
struct server_args_info conf;
char *user_list = NULL;
+struct list_head _user_list;
extern void dccp_send_init(struct sender *);
extern void http_send_init(struct sender *);
extern void ortp_send_init(struct sender *);
}
}
+/*
+ * 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(void) {
+ 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, "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, 0 /* public */);
+ 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);
+}
+
+static void init_user_list(void)
+{
+ 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();
+}
+
+int _get_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 0;
+}
+
static void init_selector(void)
{
int i, ret;
log_welcome("para_server", conf.loglevel_arg);
shm_init(); /* init mmd struct */
server_uptime(UPTIME_SET); /* reset server uptime */
+ init_user_list();
/* become daemon */
if (conf.daemon_given)
daemon_init();
/** \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
* data needed to authenticate the user
*/
struct user{
-/** the username */
+ /** the username */
char name[MAXLINE];
-/** full path to the public RSA key */
+ /** full path to the public RSA key */
char pubkey_file[_POSIX_PATH_MAX];
-/** the privileges of this user */
+ /** the privileges of this user */
+ unsigned int perms;
+};
+
+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;
};
extern struct server_args_info conf;
int handle_connect(int fd, struct sockaddr_in *addr);
+int _get_user(struct _user *user);
void mmd_unlock(void);
void mmd_lock(void);
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;