mirror of
https://github.com/samhocevar/rinetd.git
synced 2025-03-22 15:50:08 +08:00
Move connection authorisation logic to a separate function.
This commit is contained in:
parent
b0511c6ab9
commit
6909d2c3de
125
rinetd.c
125
rinetd.c
@ -94,6 +94,7 @@ enum {
|
|||||||
logLocalBindFailed,
|
logLocalBindFailed,
|
||||||
logLocalConnectFailed,
|
logLocalConnectFailed,
|
||||||
logOpened,
|
logOpened,
|
||||||
|
logAllowed,
|
||||||
logNotAllowed,
|
logNotAllowed,
|
||||||
logDenied,
|
logDenied,
|
||||||
};
|
};
|
||||||
@ -111,6 +112,7 @@ static void handleAccept(ServerInfo const *srv);
|
|||||||
static ConnectionInfo *findAvailableConnection(void);
|
static ConnectionInfo *findAvailableConnection(void);
|
||||||
static void setConnectionCount(int newCount);
|
static void setConnectionCount(int newCount);
|
||||||
static int getAddress(char const *host, struct in_addr *iaddr);
|
static int getAddress(char const *host, struct in_addr *iaddr);
|
||||||
|
static int checkConnectionAllowed(ConnectionInfo const *cnx);
|
||||||
static void refuse(ConnectionInfo *cnx, int logCode);
|
static void refuse(ConnectionInfo *cnx, int logCode);
|
||||||
|
|
||||||
static int readArgs (int argc, char **argv, RinetdOptions *options);
|
static int readArgs (int argc, char **argv, RinetdOptions *options);
|
||||||
@ -570,7 +572,6 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
struct in_addr address;
|
|
||||||
#if HAVE_SOCKLEN_T
|
#if HAVE_SOCKLEN_T
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
#else
|
#else
|
||||||
@ -604,66 +605,17 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
cnx->remote.proto = srv->fromProto;
|
cnx->remote.proto = srv->fromProto;
|
||||||
cnx->remote.recvPos = cnx->remote.sentPos = 0;
|
cnx->remote.recvPos = cnx->remote.sentPos = 0;
|
||||||
cnx->remote.recvBytes = cnx->remote.sentBytes = 0;
|
cnx->remote.recvBytes = cnx->remote.sentBytes = 0;
|
||||||
|
cnx->reAddresses.s_addr = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
|
||||||
cnx->coClosing = 0;
|
cnx->coClosing = 0;
|
||||||
cnx->coLog = logUnknownError;
|
cnx->coLog = logUnknownError;
|
||||||
cnx->server = srv;
|
cnx->server = srv;
|
||||||
|
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *) &addr;
|
int logCode = checkConnectionAllowed(cnx);
|
||||||
cnx->reAddresses.s_addr = address.s_addr = sin->sin_addr.s_addr;
|
if (logCode != logAllowed) {
|
||||||
char const *addressText = inet_ntoa(address);
|
refuse(cnx, logCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* 1. Check global allow rules. If there are no
|
|
||||||
global allow rules, it's presumed OK at
|
|
||||||
this step. If there are any, and it doesn't
|
|
||||||
match at least one, kick it out. */
|
|
||||||
int good = 1;
|
|
||||||
for (int j = 0; j < globalRulesCount; ++j) {
|
|
||||||
if (allRules[j].type == allowRule) {
|
|
||||||
good = 0;
|
|
||||||
if (match(addressText, allRules[j].pattern)) {
|
|
||||||
good = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!good) {
|
|
||||||
refuse(cnx, logNotAllowed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* 2. Check global deny rules. If it matches
|
|
||||||
any of the global deny rules, kick it out. */
|
|
||||||
for (int j = 0; j < globalRulesCount; ++j) {
|
|
||||||
if (allRules[j].type == denyRule
|
|
||||||
&& match(addressText, allRules[j].pattern)) {
|
|
||||||
refuse(cnx, logDenied);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* 3. Check allow rules specific to this forwarding rule.
|
|
||||||
If there are none, it's OK. If there are any,
|
|
||||||
it must match at least one. */
|
|
||||||
good = 1;
|
|
||||||
for (int j = 0; j < srv->rulesCount; ++j) {
|
|
||||||
if (allRules[srv->rulesStart + j].type == allowRule) {
|
|
||||||
good = 0;
|
|
||||||
if (match(addressText,
|
|
||||||
allRules[srv->rulesStart + j].pattern)) {
|
|
||||||
good = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!good) {
|
|
||||||
refuse(cnx, logNotAllowed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* 4. Check deny rules specific to this forwarding rule. If
|
|
||||||
it matches any of the deny rules, kick it out. */
|
|
||||||
for (int j = 0; j < srv->rulesCount; ++j) {
|
|
||||||
if (allRules[srv->rulesStart + j].type == denyRule
|
|
||||||
&& match(addressText, allRules[srv->rulesStart + j].pattern)) {
|
|
||||||
refuse(cnx, logDenied);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Now open a connection to the local server.
|
/* Now open a connection to the local server.
|
||||||
This, too, is nonblocking. Why wait
|
This, too, is nonblocking. Why wait
|
||||||
for anything when you don't have to? */
|
for anything when you don't have to? */
|
||||||
@ -740,6 +692,67 @@ static void handleAccept(ServerInfo const *srv)
|
|||||||
logEvent(cnx, srv, logOpened);
|
logEvent(cnx, srv, logOpened);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int checkConnectionAllowed(ConnectionInfo const *cnx)
|
||||||
|
{
|
||||||
|
ServerInfo const *srv = cnx->server;
|
||||||
|
struct in_addr address;
|
||||||
|
address.s_addr = cnx->reAddresses.s_addr;
|
||||||
|
char const *addressText = inet_ntoa(address);
|
||||||
|
|
||||||
|
/* 1. Check global allow rules. If there are no
|
||||||
|
global allow rules, it's presumed OK at
|
||||||
|
this step. If there are any, and it doesn't
|
||||||
|
match at least one, kick it out. */
|
||||||
|
int good = 1;
|
||||||
|
for (int j = 0; j < globalRulesCount; ++j) {
|
||||||
|
if (allRules[j].type == allowRule) {
|
||||||
|
good = 0;
|
||||||
|
if (match(addressText, allRules[j].pattern)) {
|
||||||
|
good = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!good) {
|
||||||
|
return logNotAllowed;
|
||||||
|
}
|
||||||
|
/* 2. Check global deny rules. If it matches
|
||||||
|
any of the global deny rules, kick it out. */
|
||||||
|
for (int j = 0; j < globalRulesCount; ++j) {
|
||||||
|
if (allRules[j].type == denyRule
|
||||||
|
&& match(addressText, allRules[j].pattern)) {
|
||||||
|
return logDenied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 3. Check allow rules specific to this forwarding rule.
|
||||||
|
If there are none, it's OK. If there are any,
|
||||||
|
it must match at least one. */
|
||||||
|
good = 1;
|
||||||
|
for (int j = 0; j < srv->rulesCount; ++j) {
|
||||||
|
if (allRules[srv->rulesStart + j].type == allowRule) {
|
||||||
|
good = 0;
|
||||||
|
if (match(addressText,
|
||||||
|
allRules[srv->rulesStart + j].pattern)) {
|
||||||
|
good = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!good) {
|
||||||
|
return logNotAllowed;
|
||||||
|
}
|
||||||
|
/* 4. Check deny rules specific to this forwarding rule. If
|
||||||
|
it matches any of the deny rules, kick it out. */
|
||||||
|
for (int j = 0; j < srv->rulesCount; ++j) {
|
||||||
|
if (allRules[srv->rulesStart + j].type == denyRule
|
||||||
|
&& match(addressText, allRules[srv->rulesStart + j].pattern)) {
|
||||||
|
return logDenied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return logAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
static void refuse(ConnectionInfo *cnx, int logCode)
|
static void refuse(ConnectionInfo *cnx, int logCode)
|
||||||
{
|
{
|
||||||
/* Local fd is not open yet when we refuse(), so only
|
/* Local fd is not open yet when we refuse(), so only
|
||||||
|
Loading…
Reference in New Issue
Block a user