示例#1
0
const struct remote_security_filter *load_security_filter(int tType, const char **dData, load_reference lLoad)
{
	if (initialized) return NULL;

#ifdef HAVE_GCRYPT_H
	if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P))
	{
	gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);

	gcry_check_version(NULL); //no need to check as of now

	gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
	gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
	}
#endif

	gnutls_global_set_log_function(&gnutls_logging);
	gnutls_global_set_log_level(PARAM_RSVX_TLS_LOGGING);

	gnutls_global_init();

	forwarder_type = tType;

	const char **initializers = dData, **current = initializers;
	int argument_count = 0;

	if (current) while (*current++) argument_count++;

	if (argument_count > 0 && (current = initializers))
	//srp initialization
	{
	use_srp_auth = true;

	const char *passwd          = (*current)? *current++ : NULL;
	const char *srp_passwd      = (*current)? *current++ : NULL;
	const char *srp_passwd_conf = (*current)? *current++ : NULL;

	if (passwd && strlen(passwd))
	 {
	srp_file = passwd;

	if (!parse_passwd())
	  {
	gnutls_global_deinit();
	return NULL;
	  }
	 }

	gnutls_global_init_extra();

	if (srp_passwd && strlen(srp_passwd) && srp_passwd_conf &&
	  strlen(srp_passwd_conf))
	 {
	gnutls_srp_allocate_server_credentials(&srp_server);
	gnutls_srp_set_server_credentials_file(srp_server, srp_passwd,
	  srp_passwd_conf);
	 }
	}

	else
	//anonymouns initialization
	{
	gnutls_anon_allocate_server_credentials(&credentials);

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_generate2(dh_params, 1024);

	gnutls_anon_set_server_dh_params(credentials, dh_params);
	}

	return &internal_filter;
}
示例#2
0
/* (re)load the client-ID and password database
 * -1=failed to find target,  0=sick file,  1=ok,  2=file unchanged */
int
load_ids(DCC_EMSG emsg,
	 DCC_CLNT_ID tgt_id,		/* DCC_ID_ANON or needed ID */
	 const ID_TBL **tgt_tbl,
	 u_char force,
	 u_char debug)
{
	DCC_PATH tmp;
	DCC_FNM_LNO_BUF fnm_buf;
	ID_TBL t, *tp, **tpp, **bin;
	FILE *f;
	int lno, passwords;
	u_char found_it;
	int result;
	char buf[sizeof(ID_TBL)*2+1];
	const char *bufp, *passbuf;
	char id_buf[30];
	struct stat sb;
	char *p, *p1;

	if (!id_tbl_blocks) {
		id_make_blocks(debug);
		id_tbl_expand_hash(debug);
	}

	if (tgt_tbl)
		*tgt_tbl = 0;

	if (!set_ids_path(emsg, 0))
		return -1;

	if (!force) {
		if (!dcc_ck_private(emsg, &sb, ids_path, -1)) {
			ids_mtime = 0;
			return -1;
		}

		if (ids_mtime == sb.st_mtime)
			return 2;
	}

	f = fopen(ids_path, "r");
	if (!f) {
		dcc_pemsg(EX_NOINPUT, emsg, "fopen(%s): %s",
			  dcc_fnm2abs_msg(tmp, ids_path), ERROR_STR());
		return -1;
	}

	/* the file contains passwords, so refuse to use it if anyone else
	 * can read it */
	if (!dcc_ck_private(emsg, &sb, ids_path, fileno(f))) {
		fclose(f);
		ids_mtime = 0;
		return -1;
	}

	/* empty the table by making all entries into placeholders */
	memset(&t, 0, sizeof(t));
	for (tpp = &id_tbl_hash[0]; tpp < &id_tbl_hash[id_tbl_bins]; ++tpp) {
		for (tp = *tpp; tp; tp = tp->hfwd) {
			t.hfwd = tp->hfwd;
			t.hbak = tp->hbak;
			t.id = tp->id;
			*tp = t;
		}
	}

	ids_mtime = sb.st_mtime;

	passwords = 0;
	lno = 0;
	result = 1;
	found_it = (tgt_id == DCC_ID_ANON);
	for (;;) {
		/* read and parse a line contain a client-ID and key(s) */
		bufp = fgets(buf, sizeof(buf), f);
		if (!bufp) {
			if (ferror(f) && result > 0) {
				dcc_pemsg(EX_IOERR, emsg, "fgets(%s): %s",
					  dcc_fnm2abs_msg(tmp, ids_path),
					  ERROR_STR());
				result = 0;
			}
			break;
		}
		++lno;

		/* Ignore blank lines and lines starting with '#'.
		 * Note that '#' flags a comment only at the start of
		 * the line to avoid dealing with the escaping hassles
		 * of allowing '#' in passwords. */
		bufp += strspn(bufp, DCC_WHITESPACE);
		if (*bufp == '\0' || *bufp == '#')
			continue;

		memset(&t, 0, sizeof(t));
		t.delay_inflate = DCC_ANON_INFLATE_OFF;

		/* Each substantive line has the form:
		 *	ID[,trace][,rpt-ok][,delay=ms[*inflate]] passwd1 passwd2
		 *	ID,delay=forever
		 *
		 * Placeholders have the from
		 *	ID
		 * or for servers on masters
		 *	ID,simple|ignore|rogue|commerical
		 *
		 *  Both passwords are always accepted.  They are intended
		 *  to be the previous and current or the current and
		 *  next to allow the password to be changed at both the
		 *  client and the server without loss of service. */

		passbuf = dcc_parse_word(emsg, id_buf, sizeof(id_buf),
					 bufp, "ID", ids_path, lno);
		if (!passbuf) {
			result = 0;	/* line too long */
			continue;
		}

		/* stop parsing the line if the server-ID is bad */
		p = strchr(id_buf, ',');
		if (p)
			*p++ = '\0';
		t.id = dcc_get_id(emsg, id_buf, ids_path, lno);
		if (t.id == DCC_ID_INVALID) {
			result = 0;
			continue;
		}
		if (t.id == DCC_ID_ANON) {
			dcc_pemsg(EX_DATAERR, emsg,
				  "invalid ID \"%s\"%s",
				  id_buf, dcc_fnm_lno(&fnm_buf, ids_path, lno));
			result = 0;
			continue;
		}

		/* parse the options */
		for (; p; p = p1) {
			p1 = strchr(p, ',');
			if (p1)
				*p1++ = '\0';

			if (!strcasecmp(p, "trace")) {
				if (!client_server(emsg, 0, t.id, p, lno)) {
					result = 0;
				} else {
					t.flags |= ID_FLG_TRACE;
				}
				continue;
			}

			if (!strcasecmp(p, "rpt-ok")
			    || !strcasecmp(p, "rpt_ok")) {
				if (!client_server(emsg, 0, t.id, p, lno)) {
					result = 0;
				} else {
					t.flags |= ID_FLG_RPT_OK;
				}
				continue;
			}

			if (!CLITCMP(p, "delay=")) {
				if (!client_server(emsg, 0, t.id, p, lno)) {
					result = 0;
				} else if (!parse_dccd_delay(emsg, &t.delay_us,
							&t.delay_inflate,
							p+LITZ("delay="),
							ids_path, lno)) {
					result = 0;
				} else {
					t.flags |= ID_FLG_DELAY_SET;
				}
				continue;
			}

			if (!strcasecmp(p, DCC_XHDR_ID_SIMPLE)) {
				if (!client_server(emsg, 1, t.id, p, lno)) {
					result = 0;
				} else {
				}
				continue;
			}
			if (!strcasecmp(p, DCC_XHDR_ID_IGNORE)) {
				if (!client_server(emsg, 1, t.id, p, lno)) {
					result = 0;
				}
				continue;
			}
			if (!strcasecmp(p, DCC_XHDR_ID_ROGUE)) {
				if (!client_server(emsg, 1, t.id, p, lno)) {
					result = 0;
				}
				continue;
			}
			if (!strcasecmp(p, DCC_XHDR_ID_REP_OK)) {
				if (!client_server(emsg, 1, t.id, p, lno)) {
					result = 0;
				}
				continue;
			}

			dcc_pemsg(EX_DATAERR, emsg,
				  "invalid option \"%s\"%s", p,
				  dcc_fnm_lno(&fnm_buf, ids_path, lno));
			result = 0;
		}

		if (*passbuf != '\0') {
			passbuf = parse_passwd(emsg, t.cur_passwd,
					       passbuf, "current password",
					       ids_path, lno);
			if (!passbuf) {
				result = 0; /* line too long */
				continue;
			}
			passbuf = parse_passwd(emsg, t.next_passwd,
					       passbuf, "next password",
					       ids_path, lno);
			if (!passbuf) {
				result = 0; /* line too long */
				continue;
			}
			if (*passbuf != '\0') {
				dcc_pemsg(EX_DATAERR, emsg,
					  "invalid next password%s",
					  dcc_fnm_lno(&fnm_buf, ids_path, lno));
				result = 0;
				continue;
			}
		}

		/* put the entry into the hash table if not already present */
		bin = &ID_HASH_ENTRY(t.id);
		tp = *bin;
		for (;;) {
			if (tp == 0) {
				tp = add_id_tbl(t.id, &bin, debug);
				break;
			} else if (tp->id == t.id) {
				break;
			}
			tp = tp->hfwd;
		}

		/* If the ID is already present, the file is bad unless
		 * the previous or current line is only a placeholder
		 * showing that the ID exists.
		 * Merge from the old entry to the new entry. */
		if (!(t.flags & ID_FLG_DELAY_SET)) {
			t.delay_us = tp->delay_us;
			t.delay_inflate = tp->delay_inflate;
			if (tp->flags & ID_FLG_DELAY_SET)
				t.flags |= ID_FLG_DELAY_SET;
		} else if ((tp->flags & ID_FLG_DELAY_SET)
			   && (t.delay_us != tp->delay_us
			       || t.delay_inflate != tp->delay_inflate)) {
			dcc_pemsg(EX_DATAERR, emsg,
				  "conflicting delays for ID %d%s",
				  t.id, dcc_fnm_lno(&fnm_buf, ids_path, lno));
			result = 0;
			continue;
		}
		if (t.cur_passwd[0] == '\0') {
			memcpy(t.cur_passwd, tp->cur_passwd,
			       sizeof(t.cur_passwd));
			memcpy(t.next_passwd, tp->next_passwd,
			       sizeof(t.next_passwd));
		} else {
			if (tp->cur_passwd[0] != '\0'
			    && (memcmp(t.cur_passwd, tp->cur_passwd,
				       sizeof(t.cur_passwd))
				|| memcmp(t.next_passwd, tp->next_passwd,
					  sizeof(t.next_passwd)))) {
				dcc_pemsg(EX_DATAERR, emsg,
					  "conflicting passwords for ID %d%s",
					  t.id,
					  dcc_fnm_lno(&fnm_buf, ids_path, lno));
				result = 0;
				continue;
			}
			++passwords;

			/* remember the target */
			if (t.id == tgt_id) {
				found_it = 1;
				if (tgt_tbl)
					*tgt_tbl = tp;
			}
		}
		t.flags |= (tp->flags & (ID_FLG_TRACE | ID_FLG_RPT_OK));
		t.hfwd = tp->hfwd;
		t.hbak = tp->hbak;
		*tp = t;
	}
	fclose(f);

	if (!passwords) {
		if (result > 0)
			dcc_pemsg(EX_DATAERR, emsg, "%s contains no passwords",
				  dcc_fnm2abs_msg(tmp, ids_path));
		result = -1;
	}
	if (!found_it) {
		if (result > 0)
			dcc_pemsg(EX_DATAERR, emsg,
				  "%s does not contain the password for ID %d",
				  dcc_fnm2abs_msg(tmp, ids_path), tgt_id);
		result = -1;
	}

	id_probes = 0;
	id_searches = 0;

	return result;
}
示例#3
0
static void set_client_passwd(gnutls_srp_client_credentials_t &cCredentials,
const struct sockaddr *aAddress, socklen_t lLength, const char *aActual)
{
	//check for updates, but use previous if the file is inaccessible
	parse_passwd();

	gnutls_srp_allocate_client_credentials(&cCredentials);

	std::string address;

	int position = data::not_found;


	if (forwarder_type == RSERVR_REMOTE_NET)
	{
	if (!aAddress || lLength != sizeof(struct sockaddr_in)) return;

	char address_buffer[PARAM_DEFAULT_FORMAT_BUFFER];
	int port = ntohs(((const struct sockaddr_in*) aAddress)->sin_port);

	//try the verbatim request first...
	if (aActual)
	 {
	snprintf(address_buffer, sizeof address_buffer, "%s:%i", aActual, port);
	position = srp_clients.f_find(address_buffer, &check_srp_key_regex);
	 }

	//then try IP lookup...
	if (position == data::not_found)
	 {
	address = inet_ntoa(((const struct sockaddr_in*) aAddress)->sin_addr);
	snprintf(address_buffer, sizeof address_buffer, "%s:%i", address.c_str(), port);
	position = srp_clients.f_find(address_buffer, &check_srp_key_regex);
	 }

	if (position == data::not_found)
	//then try DNS lookup
	 {
	char name_buffer[PARAM_DEFAULT_FORMAT_BUFFER];
	if (getnameinfo(aAddress, lLength, name_buffer, sizeof name_buffer, NULL, 0, 0x00))
	snprintf(address_buffer, sizeof address_buffer, "%s:%i", name_buffer, port);
	position = srp_clients.f_find(address_buffer, &check_srp_key_regex);
	 }
	}

	else if (forwarder_type == RSERVR_REMOTE_LOCAL)
	{
	if (!aAddress) return;

	//try the verbatim request first...
	if (aActual)
	position = srp_clients.f_find(aActual, &check_srp_key_regex);

	if (position == data::not_found)
	//then try the socket specs (probably the same file name)
	 {
	address.resize(lLength);
	strncpy(&address[0], ((const struct sockaddr_un*) aAddress)->sun_path,
	  lLength);
	position = srp_clients.f_find(address.c_str(), &check_srp_key_regex);
	 }
	}

	else return;


	if (position != data::not_found)
	gnutls_srp_set_client_credentials(cCredentials,
	  srp_clients[position].value().user.c_str(),
	  srp_clients[position].value().passwd.c_str());
}