Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

auth.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: auth.c,v 1.34.2.1 2004/12/07 03:05:06 pneumatus Exp $
 */

#include "struct.h"
#include "conf2.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include "patchlevel.h"
#include "ssl.h"
#include "config.h"
#include "memory.h"
#include "send.h"
#include "h.h"
#include <time.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

static const char enc_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";

#ifdef USE_OPENSSL
static char *auth_ssl(char *, char *, short);
#endif
static char *auth_crypt(char *, char *, short);

static ConfigAuth auth_types[] = {
#ifdef USE_OPENSSL
      /* Token                Flag                    Handler */
      { "ripemd/160",         AUTH_RIPEMD_160,  auth_ssl },
      { "sha1/160",           AUTH_SHA1_160,          auth_ssl },
      { "md5/128",            AUTH_MD5_128,           auth_ssl },
#endif
      { "des/56",       AUTH_DES_56,            auth_crypt },
      { "md5/56",       AUTH_MD5_56,            auth_crypt },
      { "plaintext",          AUTH_PLAINTEXT,         auth_crypt },
      { NULL,                 0,                NULL }
};

static short get_auth_type(char *s)
{
      ConfigAuth *a;

      ASSERT(!BadPtr(s));

      for (a = auth_types; a->string != NULL; a++) {
            if (!mycmp(a->string, s)) {
                  return a->type;
            }
      }

      return -1;
}

ConfigAuth *parse_auth(ConfigEntry *entry, char *dir)
{
      unsigned int type = -1;
      char *s = NULL;
      ConfigEntry *e;
      ConfigAuth *a = NULL;

      BLOCK_ENTRIES(entry, dir)

      for (EACH_ENTRY(e, entry)) {
            VARIABLE(e, dir)
            PARAMETER(e, dir)

            if (!mycmp(e->varname, "string")) {
                  s = e->vardata;
            }
            else if (!mycmp(e->varname, "type")) {
                  if ((type = get_auth_type(e->vardata)) == -1) {
                        report(0, "%s:%d: %s::type: unknown type %s", e->file->filename, e->varlinenum,
                              dir, e->vardata);
                        continue;
                  }
            }
            else {
                  UNKNOWN_VAR(e, dir);
            }
      }

      if (s == NULL) {
            report(0, "%s: %s::string: missing parameter, ignoring section", entry->file->filename, dir);
            return NULL;
      }
      if (type == -1) {
            report(0, "%s: %s::type: missing parameter, ignoring section", entry->file->filename, dir);
            return NULL;
      }

      a = (ConfigAuth *)MyMalloc(sizeof(ConfigAuth));
      DupString(a->string, s);
      a->type = type;
      a->func = NULL;

      return a;
}

void destroy_auth(ConfigAuth *a)
{
      ASSERT(a != NULL);

      if (!BadPtr(a->string)) {
            MyFree(a->string);
      }
      MyFree(a);
}

#ifdef USE_OPENSSL
static char *auth_ssl(char *passwd, char *salted, short type)
{
      static char buf[BUFSIZE];
      char encr[20];
      int i = 0;

      ASSERT(!BadPtr(passwd));

      *buf = '\0';
      *encr = '\0';

      switch (type) {
            case AUTH_RIPEMD_160:
                  i = RIPEMD160_DIGEST_LENGTH;
                  RIPEMD160(passwd, strlen(passwd), encr);
                  break;
            case AUTH_SHA1_160:
                  i = SHA_DIGEST_LENGTH;
                  SHA1(passwd, strlen(passwd), encr);
                  break;
            case AUTH_MD5_128:
                  i = MD5_DIGEST_LENGTH;
                  MD5(passwd, strlen(passwd), encr);
                  break;
            default:
                  ASSERT("unknown ssl type!" == NULL);
                  break;
      }

      if (i && (i = base64_encode(encr, i, buf, BUFSIZE)) > 0) {
            return buf;
      }

      return NULL;
}
#endif

static char *auth_crypt(char *passwd, char *salted, short type)
{
      static char buf[BUFSIZE];
      char salt[12];
      int i;

      ASSERT(!BadPtr(passwd));

      *buf = '\0';
      *salt = '\0';

      srandom(timeofday);

      switch (type) {
            case AUTH_DES_56:
                  if (!BadPtr(salted) && (strlen(salted) < 2)) {
                        break;
                  }
                  
                  for (i = 0; i < 2; i++) {
                        salt[i] = (BadPtr(salted)) ? enc_chars[random() % 64] : salted[i];
                  }
                  
                  salt[i] = '\0';
                  break;
            case AUTH_MD5_56:
                  salt[0] = '$';
                  salt[1] = '1';
                  salt[2] = '$';
                  
                  if (BadPtr(salted)) {
                        for (i = 0; i < 8; i++) {
                              salt[i + 3] = enc_chars[random() % 64];
                        }
                  }
                  else {
                        for (i = 0; i < 8; i++) {
                              if (salted[i + 3] == '\0' || salted[i + 3] == '$') {
                                    break;
                              }
                              salt[i + 3] = salted[i + 3];
                        }
                  }
                  
                  salt[i + 3] = '\0';
                  break;
            case AUTH_PLAINTEXT:
                  return passwd;
                  break;
            default:
                  ASSERT("unknown crypt type!" == NULL);
                  break;
      }

      if (*salt != '\0') {
            strncpyzt(buf, crypt(passwd, salt), BUFSIZE);
            return buf;
      }

      return NULL;
}

int check_auth(ConfigAuth *auth, char *passwd)
{
      char *encr = NULL;

      ASSERT(!BadPtr(passwd));

      if ((encr = auth_types[auth->type].func(passwd, auth->string, auth->type)) != NULL) {
            if (!irccmp(encr, auth->string)) {
                  return 1;
            }
      }
      
      return 0;
}

void make_auth_passwd(aClient *sptr, char *type_str, char *passwd)
{
      short type = -1;
      char *encr;

      ASSERT(!BadPtr(type_str));
      if ((type = get_auth_type(type_str)) == -1) {
            send_me_notice(sptr, ":%s is an unknown encryption type", type_str);
            return;
      }

      ASSERT(!BadPtr(passwd));
      if ((encr = auth_types[type].func(passwd, NULL, type)) == NULL) {
            send_me_noticeNA(sptr, ":Encryption failed");
      }
      else {
            send_me_notice(sptr, ":Your encrypted string is: %s", encr);
      }
}

Generated by  Doxygen 1.6.0   Back to index