Logo Search packages:      
Sourcecode: icecast-server version File versions  Download package

user.c

/*
 * user.c
 * - User authentication file stuff
 * 
 * Copyright (c) 1999 Jack Moffitt, Barath Raghavan, and Alexander Havšng
 * 
 * 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-1307, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#ifdef _WIN32
#include "win32config.h"
#else
#include "config.h"
#endif
#endif

#include "definitions.h"
#include <stdio.h>
#include "definitions.h"

#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <stdlib.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#endif

#include "avl.h"
#include "threads.h"
#include "icetypes.h"
#include "icecast.h"
#include "utility.h"
#include "ice_string.h"
#include "connection.h"
#include "log.h"
#include "sock.h"
#include "avl_functions.h"
#include "restrict.h"
#include "match.h"
#include "vars.h"
#include "memory.h"
#include "basic.h"
#include "commands.h"
#include "admin.h"
#include "user.h"

extern server_info_t info;

extern mutex_t authentication_mutex;
extern mounttree_t *mounttree;
extern usertree_t *usertree;
extern grouptree_t *grouptree;

void parse_user_authentication_file()
{
      int fd;
      ice_user_t *user;
      char line[BUFSIZE];
      char *userfile = get_icecast_file(info.userfile, conf_file_e, R_OK);

      if (!userfile || ((fd = open_for_reading(userfile)) == -1)) {
            if (userfile)
                  nfree(userfile);
            xa_debug(1, "WARNING: Could not open user authentication file");
            return;
      }
      while (fd_read_line(fd, line, BUFSIZE)) {
            if (line[0] == '#' || line[0] == ' ')
                  continue;

            user = create_user_from_line(line);

            if (user)
                  add_authentication_user(user);
      }

      if (userfile)
            nfree(userfile);
      fd_close(fd);
}

int runtime_add_user(const char *name, const char *password)
{
      char line[BUFSIZE];
      char *userfile;
      int fd;

      if (!name || !password || !name[0] || !password[0])
            return ICE_ERROR_INVALID_SYNTAX;
#ifdef _WIN32
      sprintf(line, "%s:%s\r\n", name, password);
#else
      sprintf(line, "%s:%s\n", name, password);
#endif

      thread_mutex_lock(&authentication_mutex);

      if (find_user_from_tree(usertree, name)) {
            thread_mutex_unlock(&authentication_mutex);
            return ICE_ERROR_DUPLICATE;
      }
      userfile = get_icecast_file(info.userfile, conf_file_e, W_OK);

      if (!userfile || ((fd = open_for_append(userfile)) == -1)) {
            if (userfile)
                  nfree(userfile);
            xa_debug(1, "WARNING: Could not open user authentication file for writing");
            thread_mutex_unlock(&authentication_mutex);
            return ICE_ERROR_FILE;
      }
      fd_write_line(fd, "%s", line);
      fd_close(fd);
      if (userfile)
            nfree(userfile);
      thread_mutex_unlock(&authentication_mutex);
      return 1;
}

ice_user_t *
create_user_from_line(char *line)
{
      ice_user_t *user;
      char name[BUFSIZE], pass[BUFSIZE];

      if (!line) {
            xa_debug(1, "WARNING: create_user_from_line() called with NULL pointer");
            return NULL;
      }
      if (!splitc(name, line, ':')) {
            xa_debug(1, "ERROR: Syntax error in user file, with line [%s]", line);
            return NULL;
      }
      if (!splitc(pass, line, ':'))
            strcpy(pass, line);

      user = create_user();
      user->name = nstrdup(clean_string(name));
      user->pass = nstrdup(clean_string(pass));

      return user;
}

ice_user_t *
create_user()
{
      ice_user_t *user = (ice_user_t *) nmalloc(sizeof (ice_user_t));

      user->name = NULL;
      user->pass = NULL;
      return user;
}

usertree_t *
 create_user_tree()
{
      usertree_t *ut = avl_create(compare_users, &info);

      return ut;
}


void add_authentication_user(ice_user_t * user)
{
      ice_user_t *out;

      if (!user || !usertree || !user->name || !user->pass) {
            xa_debug(1, "ERROR: add_authentication_user() called with NULL pointers");
            return;
      }
      out = avl_replace(usertree, user);

      if (out) {
            write_log(LOG_DEFAULT, "WARNING: Duplicate user record %s, using latter", user->name);
            nfree(out->name);
            nfree(out->pass);
            nfree(out);
      }
      xa_debug(1, "DEBUG: add_authentication_user(): Inserted user [%s:%s]", user->name, user->pass);
}

void free_user_tree(usertree_t * ut)
{
      avl_traverser trav =
      {0};
      ice_user_t *user, *out;

      if (!ut)
            return;

      while ((user = avl_traverse(ut, &trav))) {
            out = avl_delete(ut, user);

            if (!out) {
                  xa_debug(1, "WARNING: Weird ass things going on in usertree!");
                  continue;
            }
            nfree(out->name);
            nfree(out->pass);
            nfree(out);
      }
}

int user_authenticate(char *cuser, const char *password)
{
      const ice_user_t *user;
      ice_user_t search;

      search.name = cuser;

      if (!cuser || !password) {
            xa_debug(1, "WARNING: user_authenticate() called with NULL pointer");
            return 0;
      }
      user = avl_find(usertree, &search);

      if (!user)
            return 0;
      return password_match(user->pass, password);
}

ice_user_t *
 find_user_from_tree(usertree_t * ut, const char *name)
{
      ice_user_t search;

      search.name = strchr(name, name[0]);      /*
                                     * sigh... 
                                     */

      if (!ut || !name) {
            xa_debug(1, "WARNING: find_user_from_tree() called with NULL pointers");
            return NULL;
      }
      return avl_find(ut, &search);
}

ice_user_t *
 con_get_user(connection_t * con, ice_user_t * outuser)
{
      const char *cauth;
      char *decoded, *ptr;
      char user[BUFSIZE];
      char auth[BUFSIZE];
      char pass[BUFSIZE];

      if (!con || !outuser) {
            xa_debug(1, "WARNING: con_get_user() called with NULL pointers");
            return NULL;
      }
      outuser->name = NULL;
      outuser->pass = NULL;

      cauth = get_con_variable(con, "Authorization");

      if (!cauth)
            return NULL;

      strcpy(auth, cauth);

      splitc(NULL, auth, ' ');

      xa_debug(1, "DEBUG: con_get_user() decoding: [%s]", auth);

      ptr = decoded = util_base64_decode(auth);

      xa_debug(1, "DEBUG: con_get_user() decoded: [%s]", decoded);

      if (!splitc(user, decoded, ':')) {
            free(ptr);
            xa_debug(1, "DEBUG: con_get_user() Invalid authentication string");
            return NULL;
      }
      if (!splitc(pass, decoded, ':'))
            strcpy(pass, decoded);

      outuser->name = strdup(user);
      outuser->pass = strdup(pass);

      free(ptr);

      return outuser;
}

void con_display_users(com_request_t * req)
{
      ice_user_t *user;
      avl_traverser trav =
      {0};
      int listed = 0;

      admin_write_line(req, ADMIN_SHOW_AUTH_USER_START, "Listing users in the authentication module");

      thread_mutex_lock(&authentication_mutex);

      while ((user = avl_traverse(usertree, &trav))) {
            admin_write_line(req, ADMIN_SHOW_AUTH_USER_ENTRY, "User: [%s]", user->name);
            listed++;
      }

      thread_mutex_unlock(&authentication_mutex);

      admin_write_line(req, ADMIN_SHOW_AUTH_USER_END, "End of user listing (%d listed)", listed);
}

Generated by  Doxygen 1.6.0   Back to index