⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serverconfig.c

📁 sock protocol ,it is useful!
💻 C
📖 第 1 页 / 共 2 页
字号:
				strcheck(visdata = str2vis(data, count)));				free(visdata);			}			else if (rule->log.iooperation)				slog(LOG_INFO, "%s(%d): %s: %s -> %s (%lu)",				rule->verdict == VERDICT_BLOCK ? VERDICT_BLOCKs : VERDICT_PASSs,				rule->number, protocol2string(state->protocol),				srcstring, dststring, (unsigned long)count);			break;		default:			SERRX(operation);	}}intrulespermit(s, match, state, src, dst)	int s;	struct rule_t *match;	struct connectionstate_t *state;	const struct sockshost_t *src;	const struct sockshost_t *dst;{	const char *function = "rulespermit()";	static int init;	static struct rule_t defrule;	struct rule_t *rule;	struct connectionstate_t ostate;#if HAVE_LIBWRAP	struct request_info libwraprequest;	libwrapinit(s, &libwraprequest);#else /* !HAVE_LIBWRAP */	void *libwraprequest = NULL;#endif	/* make a somewhat sensible default rule for entries with no match. */	if (!init) {		defrule.verdict							= VERDICT_BLOCK;		defrule.number								= 0;		defrule.src.atype							= SOCKS_ADDR_IPV4;		defrule.src.addr.ipv4.ip.s_addr		= htonl(INADDR_ANY);		defrule.src.addr.ipv4.mask.s_addr	= htonl(0);		defrule.src.port.tcp						= htons(0);		defrule.src.port.udp						= htons(0);		defrule.src.portend						= htons(0);		defrule.src.operator						= none;		defrule.dst									= defrule.src;		if (config.option.debug) {			defrule.log.connect		= 1;			defrule.log.disconnect	= 1;			defrule.log.error			= 1;			defrule.log.iooperation	= 1;		}		else {			memset(&defrule.log, 0, sizeof(defrule.log));			defrule.log.connect = 1;		}		memset(&defrule.state.command, UCHAR_MAX, sizeof(defrule.state.command));		defrule.state.methodc = 0;		memset(&defrule.state.protocol, UCHAR_MAX,		sizeof(defrule.state.protocol));		memset(&defrule.state.proxyprotocol, UCHAR_MAX,		sizeof(defrule.state.proxyprotocol));#if HAVE_LIBWRAP		*defrule.libwrap = NUL;#endif  /* HAVE_LIBWRAP */		init = 1;	}	/* what rulebase to use.  XXX nicer way to do this. */	switch (state->command) {		case SOCKS_ACCEPT:			/* only set by negotiate children so must be clientrule. */			rule = config.crule;			break;		default:			/* everyone else, socksrules. */			rule = config.srule;			break;	}	/* let "state" be unchanged from original unless we actually get a match. */	for (ostate = *state; rule != NULL; rule = rule->next, *state = ostate) {		char *name, *password;		/* current rule covers desired command? */		switch (state->command) {			case SOCKS_BIND:				if (!rule->state.command.bind)					continue;				break;			case SOCKS_CONNECT:				if (!rule->state.command.connect)					continue;				break;			case SOCKS_UDPASSOCIATE:				if (!rule->state.command.udpassociate)					continue;				break;			/* pseudo commands. */			case SOCKS_BINDREPLY:				if (!rule->state.command.bindreply)					continue;				break;			case SOCKS_UDPREPLY:				if (!rule->state.command.udpreply)					continue;				break;			/* client-rule commands. */			case SOCKS_ACCEPT:				break;			default:				SERRX(state->command);		}		/* current rule covers desired protocol? */		switch (state->protocol) {			case SOCKS_TCP:				if (!rule->state.protocol.tcp)					continue;				break;			case SOCKS_UDP:				if (!rule->state.protocol.udp)					continue;				break;			default:				SERRX(state->protocol);		}		/* current rule covers desired version? */		switch (state->version) {			case SOCKS_V4:				if (!rule->state.proxyprotocol.socks_v4)					continue;				break;			case SOCKS_V5:				if (!rule->state.proxyprotocol.socks_v5)					continue;				break;			default:				SERRX(state->version);		}		/* current rule allows for selected authentication? */		if (!methodisset(state->auth.method, rule->state.methodv,		(size_t)rule->state.methodc))			/*			 * There are some "extra" methods that are independent of			 * socks protocol negotiation and it's thus possible			 * to get a match on them even if above check failed.			 * Currently it's only rfc931.			 */#if HAVE_LIBWRAP			if (methodisset(AUTHMETHOD_RFC931, rule->state.methodv,			(size_t)rule->state.methodc)) {				strncpy(state->auth.mdata.rfc931.name, eval_user(&libwraprequest),				sizeof(state->auth.mdata.rfc931.name) - 1);				if (state->auth.mdata.rfc931.name[				sizeof(state->auth.mdata.rfc931.name) - 1] != NUL) {					slog(LOG_INFO, "%s: rfc931 name truncated", function);					state->auth.mdata.rfc931.name[					sizeof(state->auth.mdata.rfc931.name) - 1] = NUL;				}				state->auth.method = AUTHMETHOD_RFC931;			}			else#endif /* HAVE_LIBWRAP */				continue;		SASSERTX(methodisset(state->auth.method, rule->state.methodv,		(size_t)rule->state.methodc));		switch (state->auth.method) {			case AUTHMETHOD_UNAME:				name		= state->auth.mdata.uname.name;				password	= state->auth.mdata.uname.password;				break;			case AUTHMETHOD_RFC931:				name		= state->auth.mdata.rfc931.name;				password	= NULL;				break;			default:				name = password = NULL;		}		if (name != NULL && rule->user != NULL) {			const char *methodname;			char srcstring[MAXSOCKSHOSTSTRING];			struct linkedname_t *ruleuser;			/*			 * The rule->user names restricts access further, only names			 * appearing there and in the passwordfile are matched.			 * An alias for "everyone" is a name that is the same as the			 * name of the selected method.			 */			methodname = method2string(state->auth.method);			ruleuser = rule->user;			do {				if (strcmp(methodname, ruleuser->name) == 0)					break; /* all usernames "match" here. */				else if (string2method(name) >= 0)					slog(LOG_INFO, "%s: suspicious username from %s: %s",					function, sockshost2string(src, srcstring, sizeof(srcstring)),					name);				else if (strcmp(name, ruleuser->name) == 0)					break;			} while ((ruleuser = ruleuser->next) != NULL);			if (ruleuser == NULL)				continue; /* no match. */			if (!state->auth.matched) { /* may have been checked at lower level. */				/* all users must also be in passwordfile. */				if (passwordcheck(name, password) != 0)					continue;				state->auth.matched = 1;			}		}		/*		 * This is a little tricky, but for some commands we may not		 * have all info at time of (preliminary) rulechecks.		 * What we want to do if there is no (complete) address given is		 * to see if there's any chance at all the rules will permit this		 * request when the address (later) becomes available.		 * We therefore continue to scan the rules until we either get		 * a pass (ignoring peer with missing info), or the default block		 * is triggered.		 */		if (src != NULL) {			if (!addressmatch(&rule->src, src, state->protocol, 0))				continue;		}		else			if (rule->verdict == VERDICT_BLOCK)				continue; /* continue scan. */		if (dst != NULL) {			if (!addressmatch(&rule->dst, dst, state->protocol, 0))				continue;		}		else			if (rule->verdict == VERDICT_BLOCK)				continue; /* continue scan. */		break;	}	if (rule == NULL) /* no rules matched; match default rule. */		rule = &defrule;	*match = *rule;	/*	 * got our rule, now check connection.  Connectioncheck	 * requires the rule matched so needs to be delayed til here.	 */	if (!connectisok(&libwraprequest, match, state))		match->verdict = VERDICT_BLOCK;	/*	 * specialcases that we delay til here to get correct addr/rule match,	 * even if we could have decided on the final answer before.	 */	switch (state->command) {		case SOCKS_BIND:			if (dst->atype == SOCKS_ADDR_IPV4 && dst->addr.ipv4.s_addr == htonl(0))				if (!config.extension.bind) {					slog(LOG_DEBUG, "%s: client requested disabled extension: bind",					function);					match->verdict = VERDICT_BLOCK;				}			break;	}	return match->verdict == VERDICT_PASS;}static struct rule_t *addrule(newrule, rulebase)	const struct rule_t *newrule;	struct rule_t **rulebase;{	static const struct serverstate_t state;	const char *function = "addrule()";	struct rule_t *rule;	if ((rule = malloc(sizeof(*rule))) == NULL)		serrx(1, "%s: %s", function, NOMEM);	*rule = *newrule;	/* try to set values not set to a sensible default. */	if (config.option.debug) {		rule->log.connect			= 1;		rule->log.disconnect		= 1;		rule->log.error			= 1;		rule->log.iooperation	= 1;	}	/* else; don't touch logging, no logging is ok. */	/* if no command set, set all. */	if (memcmp(&state.command, &rule->state.command, sizeof(state.command)) == 0)		memset(&rule->state.command, UCHAR_MAX, sizeof(rule->state.command));	/*	 * If no method set, set all we support.  This in practice	 * limits the methods we accept here to the globally set methods	 * (config.methodv), since they are checked before we get to	 * rulespesific checks.  We can't just copy config.methodv	 * since it may not be set yet.	 */	if (rule->state.methodc == 0) {		int *methodv = rule->state.methodv;		int *methodc = &rule->state.methodc;		if (rule->user == NULL)			methodv[(*methodc)++] = AUTHMETHOD_NONE;		methodv[(*methodc)++] = AUTHMETHOD_UNAME;#if HAVE_LIBWRAP		methodv[(*methodc)++] = AUTHMETHOD_RFC931;#endif	}	/* if no protocol set, set all. */	if (memcmp(&state.protocol, &rule->state.protocol, sizeof(state.protocol))	== 0)		memset(&rule->state.protocol, UCHAR_MAX, sizeof(rule->state.protocol));	/* if no proxyprotocol set, set all except msproxy. */	if (memcmp(&state.proxyprotocol, &rule->state.proxyprotocol,	sizeof(state.proxyprotocol)) == 0) {		memset(&rule->state.proxyprotocol, UCHAR_MAX,		sizeof(rule->state.proxyprotocol));		rule->state.proxyprotocol.msproxy_v2 = 0;	}	if (*rulebase == NULL) {		*rulebase = rule;		(*rulebase)->number = 1;	}	else {		struct rule_t *lastrule;		/* append this rule to the end of our list. */		lastrule = *rulebase;		while (lastrule->next != NULL)			lastrule = lastrule->next;		rule->number = lastrule->number + 1;		lastrule->next = rule;	}	rule->next = NULL;	return rule;}static voidcheckrule(rule)	const struct rule_t *rule;{	if (rule->user != NULL)		if (rule->state.methodc == 0)			yyerror("rule restricts by name, but no username-based method given");}static voidshowuser(user)	const struct linkedname_t *user;{	char buf[10240];	size_t bufused;	bufused = snprintf(buf, sizeof(buf), "user: ");	for (; user != NULL; user = user->next)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		user->name);	if (bufused > sizeof("user: "))		slog(LOG_INFO, buf);}static voidshowlog(log)	const struct log_t *log;{	char buf[1024];	size_t bufused;	bufused = snprintf(buf, sizeof(buf), "log: ");	if (log->connect)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		LOG_CONNECTs);	if (log->disconnect)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		LOG_DISCONNECTs);	if (log->data)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		LOG_DATAs);	if (log->error)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		LOG_ERRORs);	if (log->iooperation)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		LOG_IOOPERATIONs);	slog(LOG_INFO, buf);}#if HAVE_LIBWRAPstatic voidlibwrapinit(s, request)	int s;	struct request_info *request;{	request_init(request, RQ_FILE, s, RQ_DAEMON, __progname, 0);	fromhost(request);}#endif /* HAVE_LIBWRAP */static intconnectisok(request, rule, state)#if HAVE_LIBWRAP	struct request_info *request;#else	void *request;#endif	const struct rule_t *rule;	struct connectionstate_t *state;{#if HAVE_LIBWRAP	/* do we need to involve libwrap for this rule? */	if (*rule->libwrap != NUL	||  config.srchost.nomismatch	||  config.srchost.nounknown) {		const char *function = "connectisok()";		char libwrap[LIBWRAPBUF];		uid_t euid;		int checkforname;		socks_seteuid(&euid, config.uid.libwrap);		/* libwrap modifies the passed buffer. */		SASSERTX(strlen(rule->libwrap) < sizeof(libwrap));		strcpy(libwrap, rule->libwrap);		/* Wietse Venema says something along the lines of: */		if (setjmp(tcpd_buf) != 0) {			socks_reseteuid(config.uid.libwrap, euid);			swarnx("%s: failed libwrap line: %s", function, libwrap);			return 0;	/* something got screwed up. */		}		process_options(libwrap, request);		/*		 * check if we got a username and won't clobber anything by saving it.		 */		switch (state->auth.method) {			case AUTHMETHOD_NONE:	/* doesn't take any memory from rfc931. */				checkforname = 1;				break;			default:				checkforname = 0;	/* can't take it or should already have it. */		}		if (checkforname) {			/* XXX can't use eval_user() since it always does rfc931 lookup. */			if (*request->user != NUL) {				strncpy(state->auth.mdata.rfc931.name, request->user,				sizeof(state->auth.mdata.rfc931.name) - 1);				if (state->auth.mdata.rfc931.name				[sizeof(state->auth.mdata.rfc931.name) - 1] != NUL) {					slog(LOG_DEBUG, "%s: rfc931 name too long, truncated", function);					state->auth.mdata.rfc931.name					[sizeof(state->auth.mdata.rfc931.name)					- 1] = NUL;				}			}		}		if (config.srchost.nounknown)			if (strcmp(eval_hostname(request->client), STRING_UNKNOWN) == 0) {				slog(LOG_INFO, "%s: srchost unknown",				eval_hostaddr(request->client));				socks_reseteuid(config.uid.libwrap, euid);				return 0;		}		if (config.srchost.nomismatch)			if (strcmp(eval_hostname(request->client), STRING_PARANOID) == 0) {				slog(LOG_INFO, "%s: srchost ip/host mismatch",				eval_hostaddr(request->client));				socks_reseteuid(config.uid.libwrap, euid);				return 0;		}		socks_reseteuid(config.uid.libwrap, euid);	}#else	/* !HAVE_LIBWRAP */#endif  /* !HAVE_LIBWRAP */	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -