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

m_dkey.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: m_dkey.c,v 1.31.2.2 2005/01/15 23:53:32 amcwilliam Exp $
 */

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

Module MOD_HEADER(m_dkey) = {
      "m_dkey",
      "DKEY protocol",
      6, "$Revision: 1.31.2.2 $"
};

int MOD_LOAD(m_dkey)()
{
      if (register_command(&MOD_HEADER(m_dkey), &CMD_DKEY, m_dkey) == NULL) {
            return MOD_FAILURE;
      }
      return MOD_SUCCESS;
}

int MOD_UNLOAD(m_dkey)()
{
      return MOD_SUCCESS;
}

/*
 * m_dkey
 *    parv[0] = sender prefix
 *    parv[1] = command
 *    parv[2] = optional argument
 *    parv[3] = optional argument
 */
int m_dkey(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
      if (!(sptr->serv != NULL && DoingDKEY(sptr) && parc > 1)) {
            if (IsPerson(sptr)) {
                  return 0;
            }
            return exit_client(sptr, sptr, sptr, "Not negotiating now");
      }
#ifdef USE_OPENSSL
      if (!mycmp(parv[1], "START")) {
            char keybuf[1024];

            if (parc != 2) {
                  return exit_client(sptr, sptr, sptr, "DKEY START failiure");
            }
            if (sptr->serv->sessioninfo_in != NULL && sptr->serv->sessioninfo_out != NULL) {
                  return exit_client(sptr, sptr, sptr, "DKEY START duplicate");
            }

            sptr->serv->sessioninfo_in = dh_start_session();
            sptr->serv->sessioninfo_out = dh_start_session();

            send_gnotice("Initialising Diffie-Hellman key exchange with %s", sptr->name);

            dh_get_s_public(keybuf, 1024, sptr->serv->sessioninfo_in);
            sendto_one_client_nopostfix(sptr, NULL, &CMD_DKEY, "PUB I %s", keybuf);

            dh_get_s_public(keybuf, 1024, sptr->serv->sessioninfo_out);
            sendto_one_client_nopostfix(sptr, NULL, &CMD_DKEY, "PUB O %s", keybuf);

            return 0;
      }

      if (!mycmp(parv[1], "PUB")) {
            char keybuf[1024];
            int keylen;

            if (parc != 4 || sptr->serv->sessioninfo_in == NULL || sptr->serv->sessioninfo_out == NULL) {
                  return exit_client(sptr, sptr, sptr, "DKEY PUB failiure");
            }

            if (!mycmp(parv[2], "O")) {
                  if (!dh_generate_shared(sptr->serv->sessioninfo_in, parv[3])) {
                        return exit_client(sptr, sptr, sptr, "DKEY PUB O invalid");
                  }
                  SetDKEYin(sptr);
            }
            else if (!mycmp(parv[2], "I")) {
                  if (!dh_generate_shared(sptr->serv->sessioninfo_out, parv[3])) {
                        return exit_client(sptr, sptr, sptr, "DKEY PUB I invalid");
                  }
                  SetDKEYout(sptr);
            }
            else {
                  return exit_client(sptr, sptr, sptr, "DKEY PUB bad option");
            }

            if (GotDKEYin(sptr) && GotDKEYout(sptr)) {
                  sendto_one_client_nopostfix(sptr, NULL, &CMD_DKEY, "DONE");
                  SetOutputRC4(sptr);

                  keylen = 1024;
                  if (!dh_get_s_shared(keybuf, &keylen, sptr->serv->sessioninfo_in)) {
                        return exit_client(sptr, sptr, sptr, "Could not setup encrypted session");
                  }
                  sptr->serv->rc4_in = rc4_initstate(keybuf, keylen);

                  keylen = 1024;
                  if (!dh_get_s_shared(keybuf, &keylen, sptr->serv->sessioninfo_out)) {
                        return exit_client(sptr, sptr, sptr, "Could not setup encrypted session");
                  }
                  sptr->serv->rc4_out = rc4_initstate(keybuf, keylen);

                  ClearDKEYin(sptr);
                  dh_end_session(sptr->serv->sessioninfo_in);
                  sptr->serv->sessioninfo_in = NULL;

                  ClearDKEYout(sptr);
                  dh_end_session(sptr->serv->sessioninfo_out);
                  sptr->serv->sessioninfo_out = NULL;
            }

            return 0;
      }

      if (!mycmp(parv[1], "DONE")) {
            if (!((sptr->serv->sessioninfo_in == NULL && sptr->serv->sessioninfo_out == NULL)
              && (sptr->serv->rc4_in && sptr->serv->rc4_out))) {
                  return exit_client(sptr, sptr, sptr, "DKEY DONE when not done");
            }

            SetInputRC4(sptr);
            send_gnotice("Diffie-Hellman key exchange with %s complete, connection encrypted.", sptr->name);
            sendto_one_client_nopostfix(sptr, NULL, &CMD_DKEY, "EXIT");
            return RC4_NEXT_BUFFER;
      }

      if (!mycmp(parv[1], "EXIT")) {
            if (!InputRC4(sptr) || !OutputRC4(sptr)) {
                  return exit_client(sptr, sptr, sptr, "DKEY EXIT when not in proper stage");
            }

            ClearDoingDKEY(sptr);
            return do_server_estab(sptr);
      }
#endif
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index