Esempio n. 1
0
/*
 * m_challenge - generate RSA challenge for wouldbe oper
 * parv[0] = sender prefix
 * parv[1] = operator to challenge for, or +response
 *
 */
static void
m_challenge(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	char *challenge = NULL;
	struct ConfItem *conf = NULL;
	struct AccessItem *aconf = NULL;

	/* if theyre an oper, reprint oper motd and ignore */
	if(IsOper(source_p))
	{
		sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, parv[0]);
		send_message_file(source_p, &ConfigFileEntry.opermotd);
		return;
	}

	if(*parv[1] == '+')
	{
		/* Ignore it if we aren't expecting this... -A1kmm */
		if(source_p->localClient->response == NULL)
			return;

		if(svsnoop)
		{
			sendto_one(source_p,
				   ":%s NOTICE %s :*** This server is in NOOP mode, you cannot /oper",
				   me.name, source_p->name);
			failed_challenge_notice(source_p, source_p->localClient->auth_oper,
						"This server is in NOOP mode");
			log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
					source_p->localClient->auth_oper);
			return;
		}

		if(irccmp(source_p->localClient->response, ++parv[1]))
		{
			sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
			failed_challenge_notice(source_p, source_p->localClient->auth_oper,
						"challenge failed");
			return;
		}

		conf = find_exact_name_conf(OPER_TYPE,
					    source_p->localClient->auth_oper,
					    source_p->username, source_p->host);
		if(conf == NULL)
			conf = find_exact_name_conf(OPER_TYPE,
						    source_p->localClient->auth_oper,
						    source_p->username, source_p->realhost);
		if(conf == NULL)
			conf = find_exact_name_conf(OPER_TYPE,
						    source_p->localClient->auth_oper,
						    source_p->username, source_p->sockhost);
		if(conf == NULL)
		{
			sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
			log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
					source_p->localClient->auth_oper);
			return;
		}

		if(attach_conf(source_p, conf) != 0)
		{
			sendto_one(source_p, ":%s NOTICE %s :Can't attach conf!",
				   me.name, source_p->name);
			failed_challenge_notice(source_p, conf->name, "can't attach conf!");
			log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
					source_p->localClient->auth_oper);
			return;
		}

		oper_up(source_p);

		ilog(L_TRACE, "OPER %s by %s!%s@%s",
		     source_p->localClient->auth_oper, source_p->name, source_p->username,
		     source_p->realhost);
		log_oper_action(LOG_OPER_TYPE, source_p, "%s\n", source_p->localClient->auth_oper);

		MyFree(source_p->localClient->response);
		MyFree(source_p->localClient->auth_oper);
		source_p->localClient->response = NULL;
		source_p->localClient->auth_oper = NULL;
		return;
	}

	MyFree(source_p->localClient->response);
	MyFree(source_p->localClient->auth_oper);
	source_p->localClient->response = NULL;
	source_p->localClient->auth_oper = NULL;

	if((conf = find_conf_exact(OPER_TYPE, parv[1], source_p->username, source_p->host)) != NULL)
		aconf = map_to_conf(conf);
	else if((conf = find_conf_exact(OPER_TYPE,
					parv[1], source_p->username, source_p->realhost)) != NULL)
		aconf = map_to_conf(conf);
	else if((conf = find_conf_exact(OPER_TYPE,
					parv[1], source_p->username, source_p->sockhost)) != NULL)
		aconf = map_to_conf(conf);

	if(aconf == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
		conf = find_exact_name_conf(OPER_TYPE, parv[1], NULL, NULL);
		failed_challenge_notice(source_p, parv[1], (conf != NULL)
					? "host mismatch" : "no oper {} block");
		log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n", parv[1]);
		return;
	}

	if(aconf->rsa_public_key == NULL)
	{
		sendto_one(source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
			   "is not enabled for your oper{} block.", me.name, parv[0]);
		return;
	}

	if(!generate_challenge(&challenge, &(source_p->localClient->response),
			       aconf->rsa_public_key))
		sendto_one(source_p, form_str(RPL_RSACHALLENGE), me.name, parv[0], challenge);

	DupString(source_p->localClient->auth_oper, conf->name);
	MyFree(challenge);
}
Esempio n. 2
0
int ms_challenge(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
#ifdef USE_SSL
  struct ConfItem *aconf;
  RSA *rsa_public_key;
  BIO *file = NULL;
  char *challenge = NULL;
  char *name;
  char *tmpname;
  char             chan[CHANNELLEN-1];
  char*            join[2];
  int nl;
  struct Client *acptr = NULL;
  char *privbuf;

  if (!IsServer(cptr))
    return 0;

  /* if theyre an oper, reprint oper motd and ignore */
  if (IsOper(sptr))
  {
    send_reply(sptr, RPL_YOUREOPER);
    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);
  }

  if (parc < 3) {
    return send_reply(sptr, ERR_NOOPERHOST);
  }

  if (!(acptr = FindNServer(parv[1]))) {
    return send_reply(sptr, ERR_NOOPERHOST);
  } else if (!IsMe(acptr)) {
    sendcmdto_one(sptr, CMD_CHALLENGE, acptr, "%C %s %s", acptr, parv[2],
                  parv[3]);
    return 0;
  }

  if (*parv[2] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (cli_user(sptr)->response == NULL)
      return 0;

    if (ircd_strcmp(cli_user(sptr)->response, ++parv[2]))
    {
      send_reply(sptr, ERR_PASSWDMISMATCH);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (Password Incorrect)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      tmpname = strdup(cli_user(sptr)->auth_oper);
      failed_challenge_notice(sptr, tmpname, "challenge failed");
      return 0;
    }

    name = strdup(cli_user(sptr)->auth_oper);
     
    aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                            MyUser(sptr) ? cli_sockhost(sptr) :
                            cli_user(sptr)->realhost, CONF_OPS);

    if (!aconf)
      aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

    if (!aconf)
      aconf = find_conf_cidr(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              cli_ip(sptr), CONF_OPS);

    if (!aconf)
    {
      send_reply(sptr, ERR_NOOPERHOST);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      return 0;
    }

    if (CONF_LOCOP == aconf->status) {
      ClearOper(sptr);
      SetLocOp(sptr);
    }
    else {
      /* This must be called before client_set_privs() */
      SetRemoteOper(sptr);

      if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_WHOIS)) {
        OSetWhois(sptr);
      }
      if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_IDLE)) {
        OSetIdle(sptr);
      }
      if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_XTRAOP)) {
        OSetXtraop(sptr);
      }
      if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_HIDECHANS)) {
        OSetHideChans(sptr);
      }

      /* prevent someone from being both oper and local oper */
      ClearLocOp(sptr);

      if (!feature_bool(FEAT_OPERFLAGS) || !(aconf->port & OFLAG_ADMIN)) {
        /* Global Oper */
        ClearAdmin(sptr);
        OSetGlobal(sptr);
        SetOper(sptr);
      } else {
        /* Admin */
        OSetGlobal(sptr);
        OSetAdmin(sptr);
        SetOper(sptr);
        SetAdmin(sptr);
      }

      /* Tell client_set_privs to send privileges to the user */
      client_set_privs(sptr, aconf);

      ClearOper(sptr);
      ClearAdmin(sptr);

      ClearRemoteOper(sptr);
      privbuf = client_print_privs(sptr);
      sendcmdto_one(&me, CMD_PRIVS, sptr, "%C %s", sptr, privbuf);
    }

    sendcmdto_one(&me, CMD_MODE, sptr, "%s %s", cli_name(sptr),
                  (OIsAdmin(sptr)) ? "+aoiwsg" : "+oiwsg");

    send_reply(sptr, RPL_YOUREOPER);

    if (OIsAdmin(sptr)) {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Administrator",
                    parv[0], cli_user(sptr)->username, cli_sockhost(sptr));

      /* Autojoin admins to admin channel and oper channel (if enabled) */
      if (feature_bool(FEAT_AUTOJOIN_ADMIN)) {
        if (feature_bool(FEAT_AUTOJOIN_ADMIN_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_ADMIN_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_ADMIN_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
      if (feature_bool(FEAT_AUTOJOIN_OPER) && OIsGlobal(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    } else {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Operator (%c)",
                         parv[0], cli_user(sptr)->username, cli_sockhost(sptr),
                         OIsGlobal(sptr) ? 'O' : 'o');

      if (feature_bool(FEAT_AUTOJOIN_OPER) && OIsGlobal(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    }

    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);

    log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#C)", name, sptr);

    ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
    return 0;
  }

  ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
  ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN+1, "%s", "");

  aconf = find_conf_exact(parv[2], cli_user(sptr)->realusername,
                          cli_user(sptr)->realhost, CONF_OPS);

  if (!aconf)
    aconf = find_conf_exact(parv[2], cli_user(sptr)->realusername,
                            ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

  if (!aconf)
    aconf = find_conf_cidr(parv[2], cli_user(sptr)->realusername,
                            cli_ip(sptr), CONF_OPS);

  if (aconf == NULL)
  {
    send_reply(sptr, ERR_NOOPERHOST);
    failed_challenge_notice(sptr, parv[2], "No o:line");
    sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                       parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
    return 0;
  }

  if (!(aconf->port & OFLAG_REMOTE)) {
    send_reply(sptr, ERR_NOOPERHOST);
    sendto_allops(&me, SNO_OLDREALOP,
      "Failed OPER attempt by %s (%s@%s) (Remote Oper)", parv[0],
      cli_user(sptr)->realusername, cli_user(sptr)->realhost);
    return 0;
  }

  if (!(aconf->port & OFLAG_RSA))
  {
    send_reply(sptr, RPL_NO_CHALL);
    return 0;
  }

  if (!verify_sslclifp(sptr, aconf))
  {
    sendto_allops(&me, SNO_OLDREALOP,
           "Failed OPER attempt by %s (%s@%s) (SSL Fingerprint Missmatch)",
           parv[0], cli_user(sptr)->realusername,
           cli_user(sptr)->realhost);
    send_reply(sptr, ERR_SSLCLIFP);
    return 0;
  }

  if ((file = BIO_new_file(aconf->passwd, "r")) == NULL)
  {
    send_reply(sptr, RPL_NO_KEY);
    return 0;
  }

  rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
  if (rsa_public_key == NULL)
     return send_reply(sptr, RPL_INVALID_KEY);


  if (!generate_challenge(&challenge, rsa_public_key, sptr)) {
      Debug((DEBUG_DEBUG, "generating challenge sum (%s)", challenge));
      send_reply(sptr, RPL_RSACHALLENGE, challenge);
      ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN + 1, "%s", aconf->name);
  }
  nl = BIO_set_close(file, BIO_CLOSE);
  BIO_free(file);

  return 1;
#else
  return 1;
#endif
}
Esempio n. 3
0
int m_challenge(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
#ifdef USE_SSL
  struct ConfItem *aconf;
  RSA *rsa_public_key;
  BIO *file = NULL;
  char *challenge = NULL;
  char *name;
  char *tmpname;
  char             chan[CHANNELLEN-1];
  char*            join[2];
  int nl;
  struct Flags old_mode = cli_flags(sptr);

  if (!MyUser(sptr))
    return 0;

  if (parc < 2)
    return need_more_params(sptr, "CHALLENGE");

  if (parc > 2) { /* This is a remote OPER Request */
    struct Client *srv;
    if (!string_has_wildcards(parv[1]))
      srv = FindServer(parv[1]);
    else
      srv = find_match_server(parv[1]);

    if (!feature_bool(FEAT_REMOTE_OPER))
      return send_reply(sptr, ERR_NOOPERHOST);

    if (!srv)
      return send_reply(sptr, ERR_NOOPERHOST);

    if (IsMe(srv)) {
      parv[1] = parv[2];
    } else {
      sendcmdto_one(sptr, CMD_CHALLENGE, srv, "%C %s", srv, parv[2]);
      return 0;
    }
  }

  /* if theyre an oper, reprint oper motd and ignore */
  if (IsOper(sptr))
  {
    send_reply(sptr, RPL_YOUREOPER);
    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);
  }

  if (*parv[1] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (cli_user(sptr)->response == NULL)
      return 0;

    if (ircd_strcmp(cli_user(sptr)->response, ++parv[1]))
    {
      send_reply(sptr, ERR_PASSWDMISMATCH);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (Password Incorrect)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      tmpname = strdup(cli_user(sptr)->auth_oper);
      failed_challenge_notice(sptr, tmpname, "challenge failed");
      return 0;
    }

    name = strdup(cli_user(sptr)->auth_oper);
     
    aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                            MyUser(sptr) ? cli_sockhost(sptr) :
                            cli_user(sptr)->realhost, CONF_OPS);

    if (!aconf)
      aconf = find_conf_exact(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

    if (!aconf)
      aconf = find_conf_cidr(cli_user(sptr)->auth_oper, cli_user(sptr)->realusername,
                              cli_ip(sptr), CONF_OPS);

    if (!aconf)
    {
      send_reply(sptr, ERR_NOOPERHOST);
      sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                         parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
      return 0;
    }

    if (CONF_LOCOP == aconf->status) {
      ClearOper(sptr);
      SetLocOp(sptr);
    }
    else {
      /*
       * prevent someone from being both oper and local oper
       */
      ClearLocOp(sptr);
      if (!feature_bool(FEAT_OPERFLAGS) || !(aconf->port & OFLAG_ADMIN)) {
        /* Global Oper */
        SetOper(sptr);
        ClearAdmin(sptr);
      } else {
        /* Admin */
        SetOper(sptr);
        OSetGlobal(sptr);
        SetAdmin(sptr);
      }
      ++UserStats.opers;
    }
    cli_handler(cptr) = OPER_HANDLER;

    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_WHOIS)) {
      OSetWhois(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_IDLE)) {
      OSetIdle(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_XTRAOP)) {
      OSetXtraop(sptr);
    }
    if (!feature_bool(FEAT_OPERFLAGS) || (aconf->port & OFLAG_HIDECHANS)) {
      OSetHideChans(sptr);
    }

    SetFlag(sptr, FLAG_WALLOP);
    SetFlag(sptr, FLAG_SERVNOTICE);
    SetFlag(sptr, FLAG_DEBUG);

    if (!IsAdmin(sptr))
      cli_oflags(sptr) = aconf->port;

    set_snomask(sptr, SNO_OPERDEFAULT, SNO_ADD);
    client_set_privs(sptr, aconf);
    cli_max_sendq(sptr) = 0; /* Get the sendq from the oper's class */
    send_umode_out(cptr, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
    send_reply(sptr, RPL_YOUREOPER);

    if (IsAdmin(sptr)) {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Administrator",
                    parv[0], cli_user(sptr)->username, cli_sockhost(sptr));

      /* Autojoin admins to admin channel and oper channel (if enabled) */
      if (feature_bool(FEAT_AUTOJOIN_ADMIN)) {
        if (feature_bool(FEAT_AUTOJOIN_ADMIN_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_ADMIN_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_ADMIN_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
      if (feature_bool(FEAT_AUTOJOIN_OPER) && IsOper(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    } else {
      sendto_allops(&me, SNO_OLDSNO, "%s (%s@%s) is now an IRC Operator (%c)",
                         parv[0], cli_user(sptr)->username, cli_sockhost(sptr),
                         IsOper(sptr) ? 'O' : 'o');

      if (feature_bool(FEAT_AUTOJOIN_OPER) && IsOper(sptr)) {
        if (feature_bool(FEAT_AUTOJOIN_OPER_NOTICE))
              sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, feature_str(FEAT_AUTOJOIN_OPER_NOTICE_VALUE));

        ircd_strncpy(chan, feature_str(FEAT_AUTOJOIN_OPER_CHANNEL), CHANNELLEN-1);
        join[0] = cli_name(sptr);
        join[1] = chan;
        m_join(sptr, sptr, 2, join);
      }
    }

    if (feature_bool(FEAT_OPERMOTD))
      m_opermotd(sptr, sptr, 1, parv);

    log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#C)", name, sptr);

    ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
    return 0;
  }

  ircd_snprintf(0, cli_user(sptr)->response, BUFSIZE+1, "%s", "");
  ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN+1, "%s", "");

  aconf = find_conf_exact(parv[1], cli_user(sptr)->realusername,
                          cli_user(sptr)->realhost, CONF_OPS);

  if (!aconf)
    aconf = find_conf_exact(parv[1], cli_user(sptr)->realusername,
                            ircd_ntoa((const char*) &(cli_ip(sptr))), CONF_OPS);

  if (!aconf)
    aconf = find_conf_cidr(parv[1], cli_user(sptr)->realusername,
                            cli_ip(sptr), CONF_OPS);

  if (aconf == NULL)
  {
    send_reply(sptr, ERR_NOOPERHOST);
    failed_challenge_notice(sptr, parv[1], "No o:line");
    sendto_allops(&me, SNO_OLDREALOP, "Failed OPER attempt by %s (%s@%s) (No O:line)",
                       parv[0], cli_user(sptr)->realusername, cli_sockhost(sptr));
    return 0;
  }

  if (!(aconf->port & OFLAG_RSA))
  {
    send_reply(sptr, RPL_NO_CHALL);
    return 0;
  }

  if (!verify_sslclifp(sptr, aconf))
  {
    sendto_allops(&me, SNO_OLDREALOP,
           "Failed OPER attempt by %s (%s@%s) (SSL Fingerprint Missmatch)",
           parv[0], cli_user(sptr)->realusername,
           cli_user(sptr)->realhost);
    send_reply(sptr, ERR_SSLCLIFP);
    return 0;
  }

  if ((file = BIO_new_file(aconf->passwd, "r")) == NULL)
  {
    send_reply(sptr, RPL_NO_KEY);
    return 0;
  }

  rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
  if (rsa_public_key == NULL)
     return send_reply(sptr, RPL_INVALID_KEY);


  if (!generate_challenge(&challenge, rsa_public_key, sptr)) {
      Debug((DEBUG_DEBUG, "generating challenge sum (%s)", challenge));
      send_reply(sptr, RPL_RSACHALLENGE, challenge);
      ircd_snprintf(0, cli_user(sptr)->auth_oper, NICKLEN + 1, "%s", aconf->name);
  }
  nl = BIO_set_close(file, BIO_CLOSE);
  BIO_free(file);

  return 1;
#else
  return 1;
#endif
}
Esempio n. 4
0
/*
 * m_challenge - generate RSA challenge for wouldbe oper
 * parv[0] = sender prefix
 * parv[1] = operator to challenge for, or +response
 *
 */
static void
m_challenge(struct Client *client_p, struct Client *source_p,
            int parc, char *parv[])
{
  char *challenge = NULL;
  struct MaskItem *conf = NULL;

  if (*parv[1] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (source_p->localClient->response == NULL)
      return;

    if (irccmp(source_p->localClient->response, ++parv[1]))
    {
      sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name,
                 source_p->name);
      failed_challenge_notice(source_p, source_p->localClient->auth_oper,
                              "challenge failed");
      return;
    }
    
    conf = find_exact_name_conf(CONF_OPER, source_p,
                                source_p->localClient->auth_oper, NULL, NULL);
    if (conf == NULL)
    {
      /* XXX: logging */
      sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
      return;
    }

    if (attach_conf(source_p, conf) != 0)
    {
      sendto_one(source_p,":%s NOTICE %s :Can't attach conf!",
		 me.name, source_p->name);   
      failed_challenge_notice(source_p, conf->name, "can't attach conf!");
      return;
    }

    ++conf->count;
    oper_up(source_p);

    ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s",
	 source_p->localClient->auth_oper, source_p->name, source_p->username,
	 source_p->host);

    MyFree(source_p->localClient->response);
    MyFree(source_p->localClient->auth_oper);
    source_p->localClient->response  = NULL;
    source_p->localClient->auth_oper = NULL;
    return;
  }

  MyFree(source_p->localClient->response);
  MyFree(source_p->localClient->auth_oper);
  source_p->localClient->response  = NULL;
  source_p->localClient->auth_oper = NULL;

  conf = find_exact_name_conf(CONF_OPER, source_p, parv[1], NULL, NULL);

  if (!conf)
  {
    sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
    conf = find_exact_name_conf(CONF_OPER, NULL, parv[1], NULL, NULL);
    failed_challenge_notice(source_p, parv[1], (conf != NULL)
                            ? "host mismatch" : "no oper {} block");
    return;
  }

  if (conf->rsa_public_key == NULL)
  {
    sendto_one (source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
		"is not enabled for your oper{} block.", me.name,
		source_p->name);
    return;
  }

  if (!generate_challenge(&challenge, &(source_p->localClient->response),
                          conf->rsa_public_key))
    sendto_one(source_p, form_str(RPL_RSACHALLENGE),
               me.name, source_p->name, challenge);

  source_p->localClient->auth_oper = xstrdup(conf->name);
  MyFree(challenge);
}