git-svn: trunk@4811
Török Edvin authored on 2009/02/18 03:04:48... | ... |
@@ -1,3 +1,12 @@ |
1 |
+Tue Feb 17 20:35:21 EET 2009 (edwin) |
|
2 |
+------------------------------------ |
|
3 |
+ * clamd/server-th.c, clamd/session.c, clamd/session.h, |
|
4 |
+ unit_tests/check_clamd.c: Reject new commands sent as new-style |
|
5 |
+ commands to avoid confusion. This means that IDSESSION/INSTREAM |
|
6 |
+ must be sent as nIDSESSION\n or zIDSESSION\0, ditto for INSTREAM. |
|
7 |
+ Adjust testcases accordingly. Old commands are still accepted when |
|
8 |
+ sent without delimiter. |
|
9 |
+ |
|
1 | 10 |
Tue Feb 17 20:06:02 EET 2009 (edwin) |
2 | 11 |
------------------------------------ |
3 | 12 |
* clamd/others.c, libclamunrar_iface/unrar_iface.h, shared/misc.c, |
... | ... |
@@ -243,7 +243,7 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti |
243 | 243 |
* Old-style non-prefixed commands are one packet, optionally delimited by \n, |
244 | 244 |
* with trailing \r|\n ignored |
245 | 245 |
*/ |
246 |
-static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *term) |
|
246 |
+static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *term, int *oldstyle) |
|
247 | 247 |
{ |
248 | 248 |
unsigned char *pos; |
249 | 249 |
if (!buf->off || off >= buf->off) { |
... | ... |
@@ -269,6 +269,7 @@ static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *te |
269 | 269 |
} else { |
270 | 270 |
*len = pos - buf->buffer - off; |
271 | 271 |
} |
272 |
+ *oldstyle = 0; |
|
272 | 273 |
return buf->buffer + off + 1; |
273 | 274 |
default: |
274 | 275 |
/* one packet = one command */ |
... | ... |
@@ -283,6 +284,7 @@ static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *te |
283 | 283 |
buf->buffer[buf->off] = '\0'; |
284 | 284 |
} |
285 | 285 |
cli_chomp(buf->buffer); |
286 |
+ *oldstyle = 1; |
|
286 | 287 |
return buf->buffer; |
287 | 288 |
} |
288 | 289 |
} |
... | ... |
@@ -876,6 +878,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
876 | 876 |
const unsigned char *cmd = NULL; |
877 | 877 |
size_t cmdlen = 0; |
878 | 878 |
char term = '\n'; |
879 |
+ int oldstyle = 0; |
|
879 | 880 |
int rc; |
880 | 881 |
/* New data available to read on socket. */ |
881 | 882 |
|
... | ... |
@@ -895,9 +898,16 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
895 | 895 |
conn.term = buf->term; |
896 | 896 |
/* Parse & dispatch commands */ |
897 | 897 |
while ((conn.mode == MODE_COMMAND) && |
898 |
- (cmd = get_cmd(buf, pos, &cmdlen, &term)) != NULL) { |
|
898 |
+ (cmd = get_cmd(buf, pos, &cmdlen, &term, &oldstyle)) != NULL) { |
|
899 | 899 |
const char *argument; |
900 |
- enum commands cmdtype = parse_command(cmd, &argument); |
|
900 |
+ enum commands cmdtype; |
|
901 |
+ if (conn.group && oldstyle) { |
|
902 |
+ logg("$Received oldstyle command inside IDSESSION: %s\n", cmd); |
|
903 |
+ conn_reply_error(&conn, "Only nCMDS\\n and zCMDS\\0 are accepted inside IDSESSION."); |
|
904 |
+ error = 1; |
|
905 |
+ break; |
|
906 |
+ } |
|
907 |
+ cmdtype = parse_command(cmd, &argument, oldstyle); |
|
901 | 908 |
logg("$got command %s (%u, %u), argument: %s\n", |
902 | 909 |
cmd, (unsigned)cmdlen, (unsigned)cmdtype, argument ? argument : ""); |
903 | 910 |
if (cmdtype == COMMAND_FILDES) { |
... | ... |
@@ -70,25 +70,26 @@ static struct { |
70 | 70 |
const size_t len; |
71 | 71 |
enum commands cmdtype; |
72 | 72 |
int need_arg; |
73 |
+ int support_old; |
|
73 | 74 |
} commands[] = { |
74 |
- {CMD1, sizeof(CMD1)-1, COMMAND_SCAN, 1}, |
|
75 |
- {CMD3, sizeof(CMD3)-1, COMMAND_SHUTDOWN, 0}, |
|
76 |
- {CMD4, sizeof(CMD4)-1, COMMAND_RELOAD, 0}, |
|
77 |
- {CMD5, sizeof(CMD5)-1, COMMAND_PING, 0}, |
|
78 |
- {CMD6, sizeof(CMD6)-1, COMMAND_CONTSCAN, 1}, |
|
79 |
- {CMD7, sizeof(CMD7)-1, COMMAND_VERSION, 0}, |
|
80 |
- {CMD8, sizeof(CMD8)-1, COMMAND_STREAM, 0}, |
|
81 |
- {CMD10, sizeof(CMD10)-1, COMMAND_END, 0}, |
|
82 |
- {CMD11, sizeof(CMD11)-1, COMMAND_SHUTDOWN, 0}, |
|
83 |
- {CMD13, sizeof(CMD13)-1, COMMAND_MULTISCAN, 1}, |
|
84 |
- {CMD14, sizeof(CMD14)-1, COMMAND_FILDES, 0}, |
|
85 |
- {CMD15, sizeof(CMD15)-1, COMMAND_STATS, 0}, |
|
86 |
- {CMD16, sizeof(CMD16)-1, COMMAND_IDSESSION, 0}, |
|
87 |
- {CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0} |
|
75 |
+ {CMD1, sizeof(CMD1)-1, COMMAND_SCAN, 1, 1}, |
|
76 |
+ {CMD3, sizeof(CMD3)-1, COMMAND_SHUTDOWN, 0, 1}, |
|
77 |
+ {CMD4, sizeof(CMD4)-1, COMMAND_RELOAD, 0, 1}, |
|
78 |
+ {CMD5, sizeof(CMD5)-1, COMMAND_PING, 0, 1}, |
|
79 |
+ {CMD6, sizeof(CMD6)-1, COMMAND_CONTSCAN, 1, 1}, |
|
80 |
+ {CMD7, sizeof(CMD7)-1, COMMAND_VERSION, 0, 1}, |
|
81 |
+ {CMD8, sizeof(CMD8)-1, COMMAND_STREAM, 0, 1}, |
|
82 |
+ {CMD10, sizeof(CMD10)-1, COMMAND_END, 0, 0}, |
|
83 |
+ {CMD11, sizeof(CMD11)-1, COMMAND_SHUTDOWN, 0, 1}, |
|
84 |
+ {CMD13, sizeof(CMD13)-1, COMMAND_MULTISCAN, 1, 1}, |
|
85 |
+ {CMD14, sizeof(CMD14)-1, COMMAND_FILDES, 0, 1}, |
|
86 |
+ {CMD15, sizeof(CMD15)-1, COMMAND_STATS, 0, 0}, |
|
87 |
+ {CMD16, sizeof(CMD16)-1, COMMAND_IDSESSION, 0, 0}, |
|
88 |
+ {CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0, 0} |
|
88 | 89 |
}; |
89 | 90 |
|
90 | 91 |
|
91 |
-enum commands parse_command(const char *cmd, const char **argument) |
|
92 |
+enum commands parse_command(const char *cmd, const char **argument, int oldstyle) |
|
92 | 93 |
{ |
93 | 94 |
size_t i; |
94 | 95 |
*argument = NULL; |
... | ... |
@@ -109,6 +110,10 @@ enum commands parse_command(const char *cmd, const char **argument) |
109 | 109 |
} |
110 | 110 |
*argument = NULL; |
111 | 111 |
} |
112 |
+ if (oldstyle && !commands[i].support_old) { |
|
113 |
+ logg("$Command sent as old-style when not supported: %s\n", commands[i].cmd); |
|
114 |
+ return COMMAND_UNKNOWN; |
|
115 |
+ } |
|
112 | 116 |
return commands[i].cmdtype; |
113 | 117 |
} |
114 | 118 |
} |
... | ... |
@@ -85,7 +85,7 @@ typedef struct client_conn_tag { |
85 | 85 |
} client_conn_t; |
86 | 86 |
|
87 | 87 |
int command(client_conn_t *conn, int *virus); |
88 |
-enum commands parse_command(const char *cmd, const char **argument); |
|
88 |
+enum commands parse_command(const char *cmd, const char **argument, int oldstyle); |
|
89 | 89 |
int execute_or_dispatch_command(client_conn_t *conn, enum commands command, const char *argument); |
90 | 90 |
|
91 | 91 |
int conn_reply(const client_conn_t *conn, const char *path, const char *msg, const char *status); |
... | ... |
@@ -124,35 +124,36 @@ static struct basic_test { |
124 | 124 |
const char *command; |
125 | 125 |
const char *extra; |
126 | 126 |
const char *reply; |
127 |
+ int support_old; |
|
127 | 128 |
} basic_tests[] = { |
128 |
- {"PING", NULL, "PONG"}, |
|
129 |
- {"RELOAD", NULL, "RELOADING"}, |
|
130 |
- {"VERSION", NULL, VERSION_REPLY}, |
|
131 |
- {"SCAN "SCANFILE, NULL, FOUNDREPLY}, |
|
132 |
- {"SCAN "CLEANFILE, NULL, CLEANREPLY}, |
|
133 |
- {"CONTSCAN "SCANFILE, NULL, FOUNDREPLY}, |
|
134 |
- {"CONTSCAN "CLEANFILE, NULL, CLEANREPLY}, |
|
135 |
- {"MULTISCAN "SCANFILE, NULL, FOUNDREPLY}, |
|
136 |
- {"MULTISCAN "CLEANFILE, NULL, CLEANREPLY}, |
|
129 |
+ {"PING", NULL, "PONG", 1}, |
|
130 |
+ {"RELOAD", NULL, "RELOADING", 1}, |
|
131 |
+ {"VERSION", NULL, VERSION_REPLY, 1}, |
|
132 |
+ {"SCAN "SCANFILE, NULL, FOUNDREPLY, 1}, |
|
133 |
+ {"SCAN "CLEANFILE, NULL, CLEANREPLY, 1}, |
|
134 |
+ {"CONTSCAN "SCANFILE, NULL, FOUNDREPLY, 1}, |
|
135 |
+ {"CONTSCAN "CLEANFILE, NULL, CLEANREPLY, 1}, |
|
136 |
+ {"MULTISCAN "SCANFILE, NULL, FOUNDREPLY, 1}, |
|
137 |
+ {"MULTISCAN "CLEANFILE, NULL, CLEANREPLY, 1}, |
|
137 | 138 |
/* unknown commnads */ |
138 |
- {"RANDOM", NULL, UNKNOWN_REPLY}, |
|
139 |
+ {"RANDOM", NULL, UNKNOWN_REPLY, 1}, |
|
139 | 140 |
/* commands invalid as first */ |
140 |
- {"END", NULL, UNKNOWN_REPLY}, |
|
141 |
+ {"END", NULL, UNKNOWN_REPLY, 1}, |
|
141 | 142 |
/* commands for nonexistent files */ |
142 |
- {"SCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY}, |
|
143 |
- {"CONTSCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY}, |
|
144 |
- {"MULTISCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY}, |
|
143 |
+ {"SCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY, 1}, |
|
144 |
+ {"CONTSCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY, 1}, |
|
145 |
+ {"MULTISCAN "NONEXISTENT, NULL, NONEXISTENT_REPLY, 1}, |
|
145 | 146 |
/* commands for access denied files */ |
146 |
- {"SCAN "ACCDENIED, NULL, ACCDENIED_REPLY}, |
|
147 |
- {"CONTSCAN "ACCDENIED, NULL, ACCDENIED_REPLY}, |
|
148 |
- {"MULTISCAN "ACCDENIED, NULL, ACCDENIED_REPLY}, |
|
147 |
+ {"SCAN "ACCDENIED, NULL, ACCDENIED_REPLY, 1}, |
|
148 |
+ {"CONTSCAN "ACCDENIED, NULL, ACCDENIED_REPLY, 1}, |
|
149 |
+ {"MULTISCAN "ACCDENIED, NULL, ACCDENIED_REPLY, 1}, |
|
149 | 150 |
/* commands with invalid/missing arguments */ |
150 |
- {"SCAN", NULL, UNKNOWN_REPLY}, |
|
151 |
- {"CONTSCAN", NULL, UNKNOWN_REPLY}, |
|
152 |
- {"MULTISCAN", NULL, UNKNOWN_REPLY}, |
|
151 |
+ {"SCAN", NULL, UNKNOWN_REPLY, 1}, |
|
152 |
+ {"CONTSCAN", NULL, UNKNOWN_REPLY, 1}, |
|
153 |
+ {"MULTISCAN", NULL, UNKNOWN_REPLY, 1}, |
|
153 | 154 |
/* commands with invalid data */ |
154 |
- {"INSTREAM", "\xff\xff\xff\xff", "INSTREAM size limit exceeded. ERROR"}, /* too big chunksize */ |
|
155 |
- {"FILDES", "X", "No file descriptor received. ERROR"}, /* FILDES w/o ancillary data */ |
|
155 |
+ {"INSTREAM", "\xff\xff\xff\xff", "INSTREAM size limit exceeded. ERROR", 0}, /* too big chunksize */ |
|
156 |
+ {"FILDES", "X", "No file descriptor received. ERROR", 1}, /* FILDES w/o ancillary data */ |
|
156 | 157 |
}; |
157 | 158 |
|
158 | 159 |
static void *recvpartial(int sd, size_t *len, int partial) |
... | ... |
@@ -231,9 +232,13 @@ START_TEST (test_compat_commands) |
231 | 231 |
struct basic_test *test = &basic_tests[_i]; |
232 | 232 |
char nsend[BUFSIZ], nreply[BUFSIZ]; |
233 | 233 |
|
234 |
- snprintf(nreply, sizeof(nreply), "%s\n", test->reply); |
|
234 |
+ if (!test->support_old) { |
|
235 |
+ snprintf(nreply, sizeof(nreply), "UNKNOWN COMMAND\n"); |
|
236 |
+ } else { |
|
237 |
+ snprintf(nreply, sizeof(nreply), "%s\n", test->reply); |
|
238 |
+ } |
|
239 |
+ /* one command = one packet, no delimiter */ |
|
235 | 240 |
if (!test->extra) { |
236 |
- /* one command = one packet, no delimiter */ |
|
237 | 241 |
conn_setup(); |
238 | 242 |
test_command(test->command, strlen(test->command), test->extra, nreply, strlen(nreply)); |
239 | 243 |
conn_teardown(); |