Esempio n. 1
0
static int
me_gcap(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
		int parc, const char *parv[])
{
	char *t = LOCAL_COPY(parv[1]);
	char *s;
	char *p;

	if(!IsServer(source_p))
		return 0;

	/* already had GCAPAB?! */
	if(!EmptyString(source_p->serv->fullcaps))
	{
		source_p->serv->caps = 0;
		rb_free(source_p->serv->fullcaps);
	}

	source_p->serv->fullcaps = rb_strdup(parv[1]);

	for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
		source_p->serv->caps |= capability_get(serv_capindex, s);

	return 0;
}
Esempio n. 2
0
/* mr_user()
 *      parv[1] = username (login name, account)
 *      parv[2] = client host name (ignored)
 *      parv[3] = server host name (ignored)
 *      parv[4] = users gecos
 */
static int
mr_user(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    static char buf[BUFSIZE];
    char *p;

    if (strlen(client_p->id) == 3)
    {
        exit_client(client_p, client_p, client_p, "Mixing client and server protocol");
        return 0;
    }

    if(source_p->flags & FLAGS_SENTUSER)
        return 0;

    if((p = strchr(parv[1], '@')))
        *p = '\0';

    rb_snprintf(buf, sizeof(buf), "%s %s", parv[2], parv[3]);
    rb_free(source_p->localClient->fullcaps);
    source_p->localClient->fullcaps = rb_strdup(buf);

    do_local_user(client_p, source_p, parv[1], parv[4]);
    return 0;
}
Esempio n. 3
0
/*
 * mr_capab - CAPAB message handler
 *      parv[1] = space-separated list of capabilities
 *
 */
static int
mr_capab(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	int i;
	char *p;
	char *s;

	/* ummm, this shouldn't happen. Could argue this should be logged etc. */
	if(client_p->localClient == NULL)
		return 0;

	if(client_p->user)
		return 0;

	/* CAP_TS6 is set in PASS, so is valid.. */
	if((client_p->localClient->caps & ~CAP_TS6) != 0)
	{
		exit_client(client_p, client_p, client_p, "CAPAB received twice");
		return 0;
	}
	else
		client_p->localClient->caps |= CAP_CAP;

	rb_free(client_p->localClient->fullcaps);
	client_p->localClient->fullcaps = rb_strdup(parv[1]);

	for (i = 1; i < parc; i++)
	{
		char *t = LOCAL_COPY(parv[i]);
		for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
			client_p->localClient->caps |= capability_get(serv_capindex, s);
	}

	return 0;
}
Esempio n. 4
0
File: dns.c Progetto: ahf/charybdis
void
handle_resolve_dns(int parc, char *parv[])
{
	char *id = rb_strdup(parv[1]);
	char qtype = *parv[2];
	char *record = parv[3];
	int aftype = AF_INET;

	switch(qtype)
	{
	case '6':
		aftype = AF_INET6;
	case '4':
		if(!lookup_ip(record, aftype, submit_dns_answer, id))
			submit_dns_answer(NULL, false, qtype, NULL);
		break;
	case 'S':
	case 'R':
		if(!lookup_hostname(record, submit_dns_answer, id))
			submit_dns_answer(NULL, false, qtype, NULL);
		break;
	default:
		warn_opers(L_CRIT, "DNS: handle_resolve_dns got an unknown query: %c", qtype);
		exit(EX_DNS_ERROR);
	}
}
Esempio n. 5
0
static int
me_gcap(struct Client *client_p, struct Client *source_p,
        int parc, const char *parv[])
{
	struct Capability *cap;
	char *t = LOCAL_COPY(parv[1]);
	char *s;
	char *p;
	if (!IsServer(source_p))
		return 0;
	/* already had GCAPAB?! */
	if (!EmptyString(source_p->serv->fullcaps)) {
		source_p->serv->caps = 0;
		rb_free(source_p->serv->fullcaps);
	}
	source_p->serv->fullcaps = rb_strdup(parv[1]);
	for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) {
		for (cap = captab; cap->name; cap++) {
			if (!irccmp(cap->name, s)) {
				source_p->serv->caps |= cap->cap;
				break;
			}
		}
	}
	return 0;
}
Esempio n. 6
0
/*
 * mr_capab - CAPAB message handler
 *      parv[1] = space-separated list of capabilities
 *
 */
static int
mr_capab(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Capability *cap;
	int i;
	char *p;
	char *s;
	/* ummm, this shouldn't happen. Could argue this should be logged etc. */
	if (client_p->localClient == NULL)
		return 0;
	if (client_p->user)
		return 0;
	/* CAP_TS6 is set in PASS, so is valid.. */
	if ((client_p->localClient->caps & ~CAP_TS6) != 0) {
		exit_client(client_p, client_p, client_p, "CAPAB received twice");
		return 0;
	} else
		client_p->localClient->caps |= CAP_CAP;
	rb_free(client_p->localClient->fullcaps);
	client_p->localClient->fullcaps = rb_strdup(parv[1]);
	for (i = 1; i < parc; i++) {
		char *t = LOCAL_COPY(parv[i]);
		for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) {
			for (cap = captab; cap->name; cap++) {
				if (!irccmp(cap->name, s)) {
					client_p->localClient->caps |= cap->cap;
					break;
				}
			}
		}
	}
	return 0;
}
Esempio n. 7
0
/* rb_basename
 *
 * input        -
 * output       -
 * side effects -  
 */
char *
rb_basename(const char *path)
{
        const char *s;

        if(!(s = strrchr(path, '/')))
                s = path;
        else
                s++;
	return rb_strdup(s);
}
Esempio n. 8
0
/*
** me_certfp
**      parv[1] = certfp string
*/
static int
me_certfp(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if (!IsPerson(source_p))
		return 0;

	rb_free(source_p->certfp);
	source_p->certfp = NULL;
	if (!EmptyString(parv[1]))
		source_p->certfp = rb_strdup(parv[1]);
	return 0;
}
Esempio n. 9
0
static void
parse_windows_resolvers(void)
{
        const char *ns = get_windows_nameservers();
        char *server;
        char *p;
        char *buf = rb_strdup(ns);
        for(server = rb_strtok_r(buf, " ", &p); server != NULL;server = rb_strtok_r(NULL, " ", &p))
        {
                add_nameserver(server);
        }
        rb_free(buf);
}
Esempio n. 10
0
char *
rb_dirname (const char *path)
{
	char *s;

	s = strrchr(path, '/');
	if(s == NULL)
	{
		return rb_strdup(".");
	}	

	/* remove extra slashes */
	while(s > path && *s == '/')
		--s;

	return rb_strndup(path, ((uintptr_t)s - (uintptr_t)path) + 2); 
}
Esempio n. 11
0
/* mod_add_cmd
 *
 * inputs	- command name
 *		- pointer to struct Message
 * output	- none
 * side effects - load this one command name
 *		  msg->count msg->bytes is modified in place, in
 *		  modules address space. Might not want to do that...
 */
void
mod_add_cmd(struct Message *msg)
{
	struct MessageHash *ptr;
	struct MessageHash *last_ptr = NULL;
	struct MessageHash *new_ptr;
	int msgindex;

	s_assert(msg != NULL);
	if(msg == NULL)
		return;

	msgindex = cmd_hash(msg->cmd);

	for(ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
	{
		if(strcasecmp(msg->cmd, ptr->cmd) == 0)
			return;	/* Its already added */
		last_ptr = ptr;
	}

	new_ptr = rb_malloc(sizeof(struct MessageHash));

	new_ptr->next = NULL;
	new_ptr->cmd = rb_strdup(msg->cmd);
	new_ptr->msg = msg;

	msg->count = 0;
	msg->rcount = 0;
	msg->bytes = 0;

	if(last_ptr == NULL)
		msg_hash_table[msgindex] = new_ptr;
	else
		last_ptr->next = new_ptr;
}
Esempio n. 12
0
/* ms_ban()
 *
 * parv[1] - type
 * parv[2] - username mask or *
 * parv[3] - hostname mask
 * parv[4] - creation TS
 * parv[5] - duration (relative to creation)
 * parv[6] - lifetime (relative to creation)
 * parv[7] - oper or *
 * parv[8] - reason (possibly with |operreason)
 */
static int
ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	rb_dlink_node *ptr;
	struct ConfItem *aconf;
	unsigned int ntype;
	const char *oper, *stype;
	time_t now, created, hold, lifetime;
	char *p;
	int act;
	int valid;

	now = rb_current_time();
	if (strlen(parv[1]) != 1)
	{
		sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
				"Unknown BAN type %s from %s",
				parv[1], source_p->name);
		return 0;
	}
	switch (parv[1][0])
	{
		case 'K':
			ntype = CONF_KILL;
			stype = "K-Line";
			break;
		case 'X':
			ntype = CONF_XLINE;
			stype = "X-Line";
			break;
		case 'R':
			ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL :
				CONF_RESV_NICK;
			stype = "RESV";
			break;
		default:
			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
					"Unknown BAN type %s from %s",
					parv[1], source_p->name);
			return 0;
	}
	created = atol(parv[4]);
	hold = created + atoi(parv[5]);
	lifetime = created + atoi(parv[6]);
	if (!strcmp(parv[7], "*"))
		oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
	else
		oper = parv[7];
	ptr = find_prop_ban(ntype, parv[2], parv[3]);
	if (ptr != NULL)
	{
		/* We already know about this ban mask. */
		aconf = ptr->data;
		if (aconf->created > created ||
				(aconf->created == created &&
				 aconf->lifetime >= lifetime))
		{
			if (IsPerson(source_p))
				sendto_one_notice(source_p,
						":Your %s [%s%s%s] has been superseded",
						stype,
						aconf->user ? aconf->user : "",
						aconf->user ? "@" : "",
						aconf->host);
			return 0;
		}
		/* act indicates if something happened (from the oper's
		 * point of view). This is the case if the ban was
		 * previously active (not deleted) or if the new ban
		 * is not a removal and not already expired.
		 */
		act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
				hold > now);
		if (lifetime > aconf->lifetime)
			aconf->lifetime = lifetime;
		/* already expired, hmm */
		if (aconf->lifetime <= now)
			return 0;
		/* Deactivate, it will be reactivated later if appropriate. */
		deactivate_conf(aconf, ptr, now);
		rb_free(aconf->user);
		aconf->user = NULL;
		rb_free(aconf->host);
		aconf->host = NULL;
		operhash_delete(aconf->info.oper);
		aconf->info.oper = NULL;
		rb_free(aconf->passwd);
		aconf->passwd = NULL;
		rb_free(aconf->spasswd);
		aconf->spasswd = NULL;
	}
	else
	{
		/* New ban mask. */
		aconf = make_conf();
		aconf->status = CONF_ILLEGAL | ntype;
		aconf->lifetime = lifetime;
		rb_dlinkAddAlloc(aconf, &prop_bans);
		act = hold != created && hold > now;
	}
	aconf->flags &= ~CONF_FLAGS_MYOPER;
	aconf->flags |= CONF_FLAGS_TEMPORARY;
	aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
	aconf->host = rb_strdup(parv[3]);
	aconf->info.oper = operhash_add(oper);
	aconf->created = created;
	aconf->hold = hold;
	if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
		aconf->passwd = rb_strdup(parv[parc - 1]);
	else
	{
		aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
		aconf->spasswd = rb_strdup(p + 1);
	}
	/* The ban is fully filled in and in the prop_bans list
	 * but still deactivated. Now determine if it should be activated
	 * and send the server notices.
	 */
	/* We only reject *@* and the like here.
	 * Otherwise malformed bans are fairly harmless and can be removed.
	 */
	switch (ntype)
	{
		case CONF_KILL:
			valid = valid_wild_card(aconf->user, aconf->host);
			break;
		case CONF_RESV_CHANNEL:
			valid = 1;
			break;
		default:
			valid = valid_wild_card_simple(aconf->host);
			break;
	}
	if (act && hold != created && !valid)
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				       "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
				       (int)((hold - now) / 60),
				       stype,
				       IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				       strcmp(parv[7], "*") ? " on behalf of " : "",
				       strcmp(parv[7], "*") ? parv[7] : "",
				       aconf->user ? aconf->user : "",
				       aconf->user ? "@" : "",
				       aconf->host);
		if(IsPerson(source_p))
			sendto_one_notice(source_p,
					":Your %s [%s%s%s] has too few non-wildcard characters",
					stype,
					aconf->user ? aconf->user : "",
					aconf->user ? "@" : "",
					aconf->host);
		/* Propagate it, but do not apply it locally. */
	}
	else if (act && hold != created)
	{
		/* Keep the notices in sync with modules/m_kline.c etc. */
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				       "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
				       IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				       (int)((hold - now) / 60),
				       stype,
				       strcmp(parv[7], "*") ? " from " : "",
				       strcmp(parv[7], "*") ? parv[7] : "",
				       aconf->user ? aconf->user : "",
				       aconf->user ? "@" : "",
				       aconf->host,
				       parv[parc - 1]);
		ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1],
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				(int)((hold - now) / 60),
				aconf->user ? aconf->user : "",
				aconf->user ? " " : "",
				aconf->host,
				parv[parc - 1]);
		aconf->status &= ~CONF_ILLEGAL;
	}
	else if (act)
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"%s has removed the global %s for: [%s%s%s]%s%s",
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				stype,
				aconf->user ? aconf->user : "",
				aconf->user ? "@" : "",
				aconf->host,
				strcmp(parv[7], "*") ? " on behalf of " : "",
				strcmp(parv[7], "*") ? parv[7] : "");
		ilog(L_KLINE, "U%s %s %s%s %s", parv[1],
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				aconf->user ? aconf->user : "",
				aconf->user ? " " : "",
				aconf->host);
	}
	/* If CONF_ILLEGAL is still set at this point, remove entries from the
	 * reject cache (for klines and xlines).
	 * If CONF_ILLEGAL is not set, add the ban to the type-specific data
	 * structure and take action on matched clients/channels.
	 */
	switch (ntype)
	{
		case CONF_KILL:
			if (aconf->status & CONF_ILLEGAL)
				remove_reject_mask(aconf->user, aconf->host);
			else
			{
				add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
				if(ConfigFileEntry.kline_delay ||
						(IsServer(source_p) &&
						 !HasSentEob(source_p)))
				{
					if(kline_queued == 0)
					{
						rb_event_addonce("check_klines", check_klines_event, NULL,
							ConfigFileEntry.kline_delay ?
								ConfigFileEntry.kline_delay : 1);
						kline_queued = 1;
					}
				}
				else
					check_klines();
			}
			break;
		case CONF_XLINE:
			if (aconf->status & CONF_ILLEGAL)
				remove_reject_mask(aconf->host, NULL);
			else
			{
				rb_dlinkAddAlloc(aconf, &xline_conf_list);
				check_xlines();
			}
			break;
		case CONF_RESV_CHANNEL:
			if (!(aconf->status & CONF_ILLEGAL))
			{
				add_to_resv_hash(aconf->host, aconf);
				resv_chan_forcepart(aconf->host, aconf->passwd, hold - now);
			}
			break;
		case CONF_RESV_NICK:
			if (!(aconf->status & CONF_ILLEGAL))
				rb_dlinkAddAlloc(aconf, &resv_conf_list);
			break;
	}
	sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS,
			":%s BAN %s %s %s %s %s %s %s :%s",
			source_p->id,
			parv[1],
			parv[2],
			parv[3],
			parv[4],
			parv[5],
			parv[6],
			parv[7],
			parv[parc - 1]);
	return 0;
}
Esempio n. 13
0
int
main(int argc, char *argv[])
{
	char *plaintext = NULL;
	char *repeat_plaintext = NULL;
	char *crypt_passwd = NULL;
	int c;
	char *saltpara = NULL;
	char *salt;
	int flag = 0;
	int length = 0;		/* Not Set */
	int rounds = 0;		/* Not set, since extended DES needs 25 and blowfish needs
				 ** 4 by default, a side effect of this being the encryption
				 ** type parameter must be specified before the rounds
				 ** parameter.
				 */

	while((c = getopt(argc, argv, "xymdber:h?l:s:p:")) != -1)
	{
		switch (c)
		{
		case 'm':
			flag |= FLAG_MD5;
			break;
		case 'd':
			flag |= FLAG_DES;
			break;
		case 'b':
			flag |= FLAG_BLOWFISH;
			rounds = 4;
			break;
		case 'e':
			flag |= FLAG_EXT;
			rounds = 25;
			break;
		case 'l':
			flag |= FLAG_LENGTH;
			length = atoi(optarg);
			break;
		case 'r':
			flag |= FLAG_ROUNDS;
			rounds = atoi(optarg);
			break;
		case 's':
			flag |= FLAG_SALT;
			saltpara = optarg;
			break;
		case 'p':
			flag |= FLAG_PASS;
			plaintext = optarg;
			break;
		case 'x':
			flag |= FLAG_SHA256;
			break;
		case 'y':
			flag |= FLAG_SHA512;
			break;
		case 'h':
			full_usage();
			/* NOT REACHED */
			break;
		case '?':
			brief_usage();
			/* NOT REACHED */
			break;
		default:
			fprintf(stderr, "Invalid Option: -%c\n", c);
			break;
		}
	}

	if(flag & FLAG_MD5)
	{
		if(length == 0)
			length = 8;
		if(flag & FLAG_SALT)
			salt = make_md5_salt_para(saltpara);
		else
			salt = make_md5_salt(length);
	}
	else if(flag & FLAG_BLOWFISH)
	{
		if(length == 0)
			length = 22;
		if(flag & FLAG_SALT)
			salt = make_bf_salt_para(rounds, saltpara);
		else
			salt = make_bf_salt(rounds, length);
	}
	else if(flag & FLAG_SHA256)
	{
		if(length == 0)
			length = 16;
		if(flag & FLAG_SALT)
			salt = make_sha256_salt_para(saltpara);
		else
			salt = make_sha256_salt(length);
	}
	else if(flag & FLAG_SHA512)
	{
		if(length == 0)
			length = 16;
		if(flag & FLAG_SALT)
			salt = make_sha512_salt_para(saltpara);
		else
			salt = make_sha512_salt(length);
	}
	else if(flag & FLAG_EXT)
	{
		/* XXX - rounds needs to be done */
		if(flag & FLAG_SALT)
		{
			if((strlen(saltpara) == 4))
			{
				salt = make_ext_salt_para(rounds, saltpara);
			}
			else
			{
				fprintf(stderr, "Invalid salt, please enter 4 alphanumeric characters\n");
				exit(1);
			}
		}
		else
		{
			salt = make_ext_salt(rounds);
		}
	}
	else
	{
		if(flag & FLAG_SALT)
		{
			if((strlen(saltpara) == 2))
			{
				salt = saltpara;
			}
			else
			{
				fprintf(stderr, "Invalid salt, please enter 2 alphanumeric characters\n");
				exit(1);
			}
		}
		else
		{
			salt = make_des_salt();
		}
	}

	if(flag & FLAG_PASS)
	{
		if(!plaintext)
			fprintf(stderr, "Please enter a valid password\n");
	}
	else
	{
		plaintext = rb_strdup(getpass("Password: "******"Repeat Password: "******"Password mismatch\n");
			return 1;
		}
	}

	crypt_passwd = rb_crypt(plaintext, salt);
	if(!crypt_passwd)
	{
		fprintf(stderr, "Error while encryting password\n");
		return 1;
	}

	printf("%s\n", crypt_passwd);
	return 0;
}
Esempio n. 14
0
/*
 * m_challenge - generate RSA challenge for wouldbe oper
 * parv[1] = operator to challenge for, or +response
 *
 */
static int
m_challenge(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct oper_conf *oper_p;
	char *challenge = NULL; /* to placate gcc */
	char chal_line[CHALLENGE_WIDTH];
	unsigned char *b_response;
	size_t cnt;
	int len = 0;

	/* if theyre an oper, reprint oper motd and ignore */
	if(IsOper(source_p))
	{
		sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
		send_oper_motd(source_p);
		return 0;
	}

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

		if((rb_current_time() - source_p->localClient->chal_time) > CHALLENGE_EXPIRES)
		{
			sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
			ilog(L_FOPER, "EXPIRED CHALLENGE (%s) by (%s!%s@%s) (%s)",
			     source_p->localClient->opername, source_p->name,
			     source_p->username, source_p->host, source_p->sockhost);

			if(ConfigFileEntry.failed_oper_notice)
				sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
						     "Expired CHALLENGE attempt by %s (%s@%s)",
						     source_p->name, source_p->username,
						     source_p->host);
			cleanup_challenge(source_p);
			return 0;
		}

		parv[1]++;
		b_response = rb_base64_decode((const unsigned char *)parv[1], strlen(parv[1]), &len);

		if(len != SHA_DIGEST_LENGTH ||
		   memcmp(source_p->localClient->challenge, b_response, SHA_DIGEST_LENGTH))
		{
			sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
			ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s)",
			     source_p->localClient->opername, source_p->name,
			     source_p->username, source_p->host, source_p->sockhost);

			if(ConfigFileEntry.failed_oper_notice)
				sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
						     "Failed CHALLENGE attempt by %s (%s@%s)",
						     source_p->name, source_p->username,
						     source_p->host);

			rb_free(b_response);
			cleanup_challenge(source_p);
			return 0;
		}

		rb_free(b_response);

		oper_p = find_oper_conf(source_p->username, source_p->orighost,
					source_p->sockhost,
					source_p->localClient->opername);

		if(oper_p == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST));
			ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
			     source_p->localClient->opername, source_p->name,
			     source_p->username, source_p->host,
			     source_p->sockhost);

			if(ConfigFileEntry.failed_oper_notice)
				sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
						     "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)",
						     source_p->name, source_p->username,
						     source_p->host);
			return 0;
		}

		cleanup_challenge(source_p);

		oper_up(source_p, oper_p);

		ilog(L_OPERED, "OPER %s by %s!%s@%s (%s)",
		     source_p->localClient->opername, source_p->name,
		     source_p->username, source_p->host, source_p->sockhost);
		return 0;
	}

	cleanup_challenge(source_p);

	oper_p = find_oper_conf(source_p->username, source_p->orighost,
				source_p->sockhost, parv[1]);

	if(oper_p == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST));
		ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
		     parv[1], source_p->name,
		     source_p->username, source_p->host, source_p->sockhost);

		if(ConfigFileEntry.failed_oper_notice)
			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
					     "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)",
					     source_p->name, source_p->username, source_p->host);
		return 0;
	}

	if(!oper_p->rsa_pubkey)
	{
		sendto_one_notice(source_p, ":I'm sorry, PK authentication is not enabled for your oper{} block.");
		return 0;
	}

	if(IsOperConfNeedSSL(oper_p) && !IsSSLClient(source_p))
	{
		sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST));
		ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s) -- requires SSL/TLS",
		     parv[1], source_p->name, source_p->username, source_p->host,
		     source_p->sockhost);

		if(ConfigFileEntry.failed_oper_notice)
		{
			sendto_realops_snomask(SNO_GENERAL, L_ALL,
					     "Failed CHALLENGE attempt - missing SSL/TLS by %s (%s@%s)",
					     source_p->name, source_p->username, source_p->host);
		}
		return 0;
	}

	if (oper_p->certfp != NULL)
	{
		if (source_p->certfp == NULL || strcasecmp(source_p->certfp, oper_p->certfp))
		{
			sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST));
			ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s) -- client certificate fingerprint mismatch",
			     parv[1], source_p->name,
			     source_p->username, source_p->host, source_p->sockhost);

			if(ConfigFileEntry.failed_oper_notice)
			{
				sendto_realops_snomask(SNO_GENERAL, L_ALL,
						     "Failed OPER attempt - client certificate fingerprint mismatch by %s (%s@%s)",
						     source_p->name, source_p->username, source_p->host);
			}
			return 0;
		}
	}

	if(!generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey))
	{
		char *chal = challenge;
		source_p->localClient->chal_time = rb_current_time();
		for(;;)
		{
			cnt = rb_strlcpy(chal_line, chal, CHALLENGE_WIDTH);
			sendto_one(source_p, form_str(RPL_RSACHALLENGE2), me.name, source_p->name, chal_line);
			if(cnt > CHALLENGE_WIDTH)
				chal += CHALLENGE_WIDTH - 1;
			else
				break;

		}
		sendto_one(source_p, form_str(RPL_ENDOFRSACHALLENGE2),
			   me.name, source_p->name);
		rb_free(challenge);
		source_p->localClient->opername = rb_strdup(oper_p->name);
	}
	else
		sendto_one_notice(source_p, ":Failed to generate challenge.");

	return 0;
}
Esempio n. 15
0
static int
m_displaymsg(struct Client *source_p, const char *channel, int underline, int action, const char *nick, const char *text)
{
	struct Channel *chptr;
	struct membership *msptr;
	char nick2[NICKLEN+1];
	char *nick3 = rb_strdup(nick);
	char text2[BUFSIZE];

	if((chptr = find_channel(channel)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), channel);
		return 0;
	}

	if(!(msptr = find_channel_membership(chptr, source_p)))
	{
		sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
				   form_str(ERR_NOTONCHANNEL), chptr->chname);
		return 0;
	}

	if(!(chptr->mode.mode & chmode_flags['N']))
	{
		sendto_one_numeric(source_p, 573, "%s :Roleplay commands are not enabled on this channel.", chptr->chname);
		return 0;
	}

	if(!can_send(chptr, source_p, msptr))
	{
		sendto_one_numeric(source_p, 573, "%s :Cannot send to channel.", chptr->chname);
		return 0;
	}

	/* enforce flood stuff on roleplay commands */
	if(flood_attack_channel(0, source_p, chptr, chptr->chname))
		return 0;

	/* enforce target change on roleplay commands */
	if(!is_chanop_voiced(msptr) && !IsOper(source_p) && !add_channel_target(source_p, chptr))
	{
		sendto_one(source_p, form_str(ERR_TARGCHANGE),
			   me.name, source_p->name, chptr->chname);
		return 0;
	}

	if(underline)
		rb_snprintf(nick2, sizeof(nick2), "\x1F%s\x1F", strip_unprintable(nick3));
	else
		rb_snprintf(nick2, sizeof(nick2), "%s", strip_unprintable(nick3));

	/* don't allow nicks to be empty after stripping
	 * this prevents nastiness like fake factions, etc. */
	if(EmptyString(nick3))
	{
		sendto_one_numeric(source_p, 573, "%s :No visible non-stripped characters in nick.", chptr->chname);
		return 0;
	}

	if(action)
		rb_snprintf(text2, sizeof(text2), "\1ACTION %s\1", text);
	else
		rb_snprintf(text2, sizeof(text2), "%s", text);

	sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected] PRIVMSG %s :%s (%s)", nick2, source_p->name, channel, text2, source_p->name); 
	sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS, "ENCAP * ROLEPLAY %s %s :%s",
			channel, nick2, text2);
	return 0;
}
Esempio n. 16
0
/*
 * m_pass() - Added Sat, 4 March 1989
 *
 *
 * mr_pass - PASS message handler
 *      parv[0] = sender prefix
 *      parv[1] = password
 *      parv[2] = "TS" if this server supports TS.
 *      parv[3] = optional TS version field -- needed for TS6
 */
static int
mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if(client_p->localClient->passwd)
	{
		memset(client_p->localClient->passwd, 0, strlen(client_p->localClient->passwd));
		rb_free(client_p->localClient->passwd);
	}

	client_p->localClient->passwd = rb_strndup(parv[1], PASSWDLEN);

	if(parc > 2)
	{
#ifdef COMPAT_211
		/* detected 2.11 protocol? */
		if (strlen(parv[2]) == 10 && parc > 4) {
			if (strchr(parv[4], 'Z'))
				client_p->localClient->caps |= CAP_ZIP;
			if (strchr(parv[4], 'T'))
				client_p->localClient->caps |= CAP_TB;
			if (strchr(parv[4], 'j'))
				client_p->localClient->caps |= CAP_JAPANESE;

			if (!strcmp(parv[2], IRCNET_VERSTRING)) {
				/* nah, it's just us pretending, we're going to receive CAPAB.
				   Will fill the SID in server stage though. */
				client_p->localClient->caps |= CAP_TS6|CAPS_IRCNET;
			} else {
				/* True 2.11 */
				client_p->localClient->caps |= CAP_211|CAPS_IRCNET;
				/* As we're never going to receive CAPAB for this one */
				client_p->localClient->fullcaps =	
					rb_strdup(send_capabilities(NULL, client_p->localClient->caps));
			}
			return 0;
		}
#endif
		/* 
		 * It looks to me as if orabidoo wanted to have more
		 * than one set of option strings possible here...
		 * i.e. ":AABBTS" as long as TS was the last two chars
		 * however, as we are now using CAPAB, I think we can
		 * safely assume if there is a ":TS" then its a TS server
		 * -Dianora
		 */
		if(irccmp(parv[2], "TS") == 0 && client_p->tsinfo == 0)
			client_p->tsinfo = TS_DOESTS;

		if(parc == 5 && atoi(parv[3]) >= 6)
		{
			/* only mark as TS6 if the SID is valid.. */
			if(check_sid(parv[4]))
			{
				client_p->localClient->caps |= CAP_TS6;
				strcpy(client_p->id, parv[4]);
			}
		}
	}

	return 0;
}