2017-09-05 18:52:39 +08:00
|
|
|
# Copyright © 1997—1999 Thomas Boutell <boutell@boutell.com>
|
|
|
|
# and Boutell.Com, Inc.
|
|
|
|
# © 2003—2017 Sam Hocevar <sam@hocevar.net>
|
|
|
|
#
|
|
|
|
# This software is released for free use under the terms of
|
|
|
|
# the GNU Public License, version 2 or higher. NO WARRANTY
|
|
|
|
# IS EXPRESSED OR IMPLIED. USE THIS SOFTWARE AT YOUR OWN RISK. */
|
|
|
|
|
2017-09-05 02:14:11 +08:00
|
|
|
%{
|
2017-09-05 18:52:39 +08:00
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2017-09-07 23:13:58 +08:00
|
|
|
#include "net.h"
|
2017-09-05 18:52:39 +08:00
|
|
|
#include "types.h"
|
|
|
|
#include "rinetd.h"
|
|
|
|
#include "parse.h"
|
|
|
|
|
2017-09-05 02:14:11 +08:00
|
|
|
#define YY_CTX_LOCAL 1
|
|
|
|
#define YY_CTX_MEMBERS \
|
2017-09-05 18:52:39 +08:00
|
|
|
FILE *fp; \
|
2017-09-06 19:01:10 +08:00
|
|
|
int currentLine; \
|
2017-09-05 18:52:39 +08:00
|
|
|
int isAuthAllow; \
|
|
|
|
char *tmpPort; \
|
|
|
|
int tmpPortNum, tmpProto; \
|
|
|
|
int bindPortNum, bindProto, connectPortNum, connectProto; \
|
2017-09-08 18:32:05 +08:00
|
|
|
int serverTimeout; \
|
2017-09-05 18:52:39 +08:00
|
|
|
char *bindAddress, *connectAddress;
|
2017-09-05 02:14:11 +08:00
|
|
|
#define YY_INPUT(yyctx, buf, result, max_size) \
|
|
|
|
{ \
|
2017-09-05 18:52:39 +08:00
|
|
|
int yyc = fgetc(yyctx->fp); \
|
|
|
|
result = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); \
|
2017-09-05 02:14:11 +08:00
|
|
|
}
|
|
|
|
#define PARSE_ERROR exit(1);
|
2017-09-05 18:52:39 +08:00
|
|
|
|
|
|
|
#if defined __clang__
|
|
|
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
2017-09-06 19:01:10 +08:00
|
|
|
#pragma clang diagnostic ignored "-Wunused-label"
|
2017-09-05 18:52:39 +08:00
|
|
|
#elif defined __GNUC__
|
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
2017-09-06 19:01:10 +08:00
|
|
|
#pragma GCC diagnostic ignored "-Wunused-label"
|
2017-09-05 18:52:39 +08:00
|
|
|
#endif
|
|
|
|
|
2017-09-05 02:14:11 +08:00
|
|
|
%}
|
|
|
|
|
2017-09-06 19:01:10 +08:00
|
|
|
file = (sol (line eol | invalid-syntax))*
|
|
|
|
line = -? (command -?)? comment?
|
2017-09-08 18:32:05 +08:00
|
|
|
command = (server-rule | auth-rule | logfile | pidlogfile | logcommon)
|
2017-09-05 02:14:11 +08:00
|
|
|
comment = "#" (!eol .)*
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
server-rule = bind-address - bind-port - connect-address - connect-port (-? "[" -? server-options -? "]")?
|
|
|
|
{
|
2017-09-05 07:45:00 +08:00
|
|
|
addServer(yy->bindAddress, yy->bindPortNum, yy->bindProto,
|
2017-09-08 18:32:05 +08:00
|
|
|
yy->connectAddress, yy->connectPortNum, yy->connectProto,
|
|
|
|
yy->serverTimeout > 0 ? yy->serverTimeout : RINETD_DEFAULT_UDP_TIMEOUT);
|
2017-09-05 02:14:11 +08:00
|
|
|
yy->bindAddress = yy->connectAddress = NULL;
|
2017-09-08 18:32:05 +08:00
|
|
|
yy->serverTimeout = 0;
|
2017-09-05 02:14:11 +08:00
|
|
|
}
|
|
|
|
|
2017-09-05 07:45:00 +08:00
|
|
|
bind-address = < ipv4 > { yy->bindAddress = strdup(yytext); }
|
|
|
|
connect-address = < ipv4 > { yy->connectAddress = strdup(yytext); }
|
|
|
|
bind-port = full-port { yy->bindPortNum = yy->tmpPortNum; yy->bindProto = yy->tmpProto; }
|
|
|
|
connect-port = full-port { yy->connectPortNum = yy->tmpPortNum; yy->connectProto = yy->tmpProto; }
|
2017-09-08 18:32:05 +08:00
|
|
|
server-options = ("timeout" -? "=" -? < number >) { yy->serverTimeout = atoi(yytext); }
|
2017-09-05 07:45:00 +08:00
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
full-port = port proto
|
|
|
|
{
|
2017-09-05 07:45:00 +08:00
|
|
|
char const *proto = yy->tmpProto == protoTcp ? "tcp" : "udp";
|
|
|
|
struct servent *service = getservbyname(yy->tmpPort, proto);
|
|
|
|
yy->tmpPortNum = service ? ntohs(service->s_port) : atoi(yy->tmpPort);
|
|
|
|
if (yy->tmpPortNum == 0 || yy->tmpPortNum >= 65536) {
|
|
|
|
syslog(LOG_ERR, "port %s/%s missing or out of range\n", yy->tmpPort, proto);
|
2017-09-05 02:14:11 +08:00
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:45:00 +08:00
|
|
|
port = < (number | service) > { yy->tmpPort = strdup(yytext); }
|
|
|
|
proto = '/tcp' { yy->tmpProto = protoTcp; }
|
|
|
|
| '/udp' { yy->tmpProto = protoUdp; }
|
|
|
|
| '' { yy->tmpProto = protoTcp; }
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
auth-rule = auth-key - < pattern >
|
|
|
|
{
|
2017-09-05 02:14:11 +08:00
|
|
|
allRules = (Rule *)
|
|
|
|
realloc(allRules, sizeof(Rule) * (allRulesCount + 1));
|
|
|
|
if (!allRules) {
|
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
allRules[allRulesCount].pattern = strdup(yytext);
|
|
|
|
if (!allRules[allRulesCount].pattern) {
|
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
allRules[allRulesCount].type = yy->isAuthAllow ? allowRule : denyRule;
|
|
|
|
if (seTotal > 0) {
|
|
|
|
if (seInfo[seTotal - 1].rulesStart == 0) {
|
|
|
|
seInfo[seTotal - 1].rulesStart = allRulesCount;
|
|
|
|
}
|
|
|
|
++seInfo[seTotal - 1].rulesCount;
|
|
|
|
} else {
|
|
|
|
++globalRulesCount;
|
|
|
|
}
|
|
|
|
++allRulesCount;
|
|
|
|
}
|
|
|
|
|
2017-09-05 07:45:00 +08:00
|
|
|
auth-key = < ("allow" | "deny") > { yy->isAuthAllow = (yytext[0] == 'a'); }
|
2017-09-05 02:14:11 +08:00
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
logfile = "logfile" - < filename >
|
|
|
|
{
|
2017-09-05 02:14:11 +08:00
|
|
|
logFileName = strdup(yytext);
|
|
|
|
if (!logFileName) {
|
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
pidlogfile = "pidlogfile" - < filename >
|
|
|
|
{
|
2017-09-05 02:14:11 +08:00
|
|
|
pidLogFileName = strdup(yytext);
|
|
|
|
if (!pidLogFileName) {
|
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
logcommon = "logcommon"
|
|
|
|
{
|
2017-09-05 02:14:11 +08:00
|
|
|
logFormatCommon = 1;
|
|
|
|
}
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
invalid_syntax = < (!eol .)+ > eol
|
|
|
|
{
|
2017-09-06 18:57:05 +08:00
|
|
|
fprintf(stderr, "rinetd: invalid syntax at line %d: %s\n",
|
|
|
|
yy->currentLine, yytext);
|
|
|
|
PARSE_ERROR; /* FIXME */
|
|
|
|
}
|
2017-09-05 02:14:11 +08:00
|
|
|
|
|
|
|
service = name
|
|
|
|
ipv4 = number [.] number [.] number [.] number | '0'
|
|
|
|
pattern = [0-9*?]+ ('.' [0-9*?]+ ('.' [0-9*?]+ ('.' [0-9*?]+)?)?)?
|
|
|
|
number = digit+
|
|
|
|
|
|
|
|
name = [a-zA-Z][a-zA-Z0-9_]*
|
|
|
|
filename = '"' [^"]+ '"'
|
|
|
|
| [^ \t\r\n]+
|
|
|
|
|
|
|
|
- = [ \t]+
|
|
|
|
digit = [0-9]
|
2017-09-06 18:57:05 +08:00
|
|
|
sol = { ++yy->currentLine; }
|
2017-09-05 02:14:11 +08:00
|
|
|
eol = '\r'? '\n' | eof
|
|
|
|
eof = '\0'
|
|
|
|
|
2017-09-05 18:52:39 +08:00
|
|
|
%%
|
|
|
|
|
2017-09-08 18:32:05 +08:00
|
|
|
void parseConfiguration(char const *file)
|
|
|
|
{
|
2017-09-05 18:52:39 +08:00
|
|
|
FILE *in = fopen(file, "r");
|
|
|
|
if (!in) {
|
|
|
|
PARSE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
yycontext ctx;
|
|
|
|
memset(&ctx, 0, sizeof(yycontext));
|
|
|
|
ctx.fp = in;
|
|
|
|
if (!yyparse(&ctx)) {
|
|
|
|
syslog(LOG_ERR, "invalid syntax "
|
|
|
|
"on file %s, line %d.\n", file, -1);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(in);
|
|
|
|
|
|
|
|
/* Avopid warnings for these unused functions */
|
|
|
|
(void)yySet; (void)yyPush; (void)yyPop; (void)yyAccept;
|
|
|
|
}
|
|
|
|
|