r14602@catbus: nickm | 2007-08-16 13:33:27 -0400
Make 0.1.2 give a warning on v0 control commands and close the connnection, rather than simply failing apart and yelling. svn:r11139
This commit is contained in:
parent
d0ecd468eb
commit
ebb8a62ad4
|
@ -1228,54 +1228,20 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If there is a complete version 0 control message waiting on buf, then store
|
/** Return 1 iff buf looks more like it has an (obsolete) v0 controller
|
||||||
* its contents into *<b>type_out</b>, store its body's length into
|
* command on it than any valid v1 controller command. */
|
||||||
* *<b>len_out</b>, allocate and store a string for its body into
|
|
||||||
* *<b>body_out</b>, and return 1. (body_out will always be NUL-terminated,
|
|
||||||
* even if the control message body doesn't end with NUL.)
|
|
||||||
*
|
|
||||||
* If there is not a complete control message waiting, return 0.
|
|
||||||
*
|
|
||||||
* Return -1 on error; return -2 on "seems to be control protocol v1."
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
fetch_from_buf_control0(buf_t *buf, uint32_t *len_out, uint16_t *type_out,
|
peek_buf_has_control0_command(buf_t *buf)
|
||||||
char **body_out, int check_for_v1)
|
|
||||||
{
|
{
|
||||||
uint32_t msglen;
|
if (buf->datalen >= 4) {
|
||||||
uint16_t type;
|
char header[4];
|
||||||
char tmp[4];
|
uint16_t cmd;
|
||||||
|
peek_from_buf(header, sizeof(header), buf);
|
||||||
tor_assert(buf);
|
cmd = ntohs(get_uint16(header+2));
|
||||||
tor_assert(len_out);
|
if (cmd <= 0x14)
|
||||||
tor_assert(type_out);
|
return 1; /* This is definitely not a v1 control command. */
|
||||||
tor_assert(body_out);
|
|
||||||
|
|
||||||
*len_out = 0;
|
|
||||||
*body_out = NULL;
|
|
||||||
|
|
||||||
if (buf->datalen < 4)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
peek_from_buf(tmp, 4, buf);
|
|
||||||
|
|
||||||
msglen = ntohs(get_uint16(tmp));
|
|
||||||
type = ntohs(get_uint16(tmp+2));
|
|
||||||
if (type > 255 && check_for_v1)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
if (buf->datalen < 4 + (unsigned)msglen)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*len_out = msglen;
|
|
||||||
*type_out = type;
|
|
||||||
buf_remove_from_front(buf, 4);
|
|
||||||
if (msglen) {
|
|
||||||
*body_out = tor_malloc(msglen+1);
|
|
||||||
fetch_from_buf(*body_out, msglen, buf);
|
|
||||||
(*body_out)[msglen] = '\0';
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper: return a pointer to the first instance of <b>c</b> in the
|
/** Helper: return a pointer to the first instance of <b>c</b> in the
|
||||||
|
|
|
@ -19,23 +19,6 @@ const char control_c_id[] =
|
||||||
* See control-spec.txt for full details on protocol.
|
* See control-spec.txt for full details on protocol.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Recognized version 0 error codes. Do not expand. */
|
|
||||||
#define ERR_UNSPECIFIED 0x0000
|
|
||||||
#define ERR_INTERNAL 0x0001
|
|
||||||
#define ERR_UNRECOGNIZED_TYPE 0x0002
|
|
||||||
#define ERR_SYNTAX 0x0003
|
|
||||||
#define ERR_UNRECOGNIZED_CONFIG_KEY 0x0004
|
|
||||||
#define ERR_INVALID_CONFIG_VALUE 0x0005
|
|
||||||
#define ERR_UNRECOGNIZED_EVENT_CODE 0x0006
|
|
||||||
#define ERR_UNAUTHORIZED 0x0007
|
|
||||||
#define ERR_REJECTED_AUTHENTICATION 0x0008
|
|
||||||
#define ERR_RESOURCE_EXHAUSTED 0x0009
|
|
||||||
#define ERR_NO_STREAM 0x000A
|
|
||||||
#define ERR_NO_CIRC 0x000B
|
|
||||||
#define ERR_NO_ROUTER 0x000C
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Recognized asynchronous event types. It's okay to expand this list
|
/* Recognized asynchronous event types. It's okay to expand this list
|
||||||
* because it is used both as a list of v0 event types, and as indices
|
* because it is used both as a list of v0 event types, and as indices
|
||||||
* into the bitfield to determine which controllers want which events.
|
* into the bitfield to determine which controllers want which events.
|
||||||
|
@ -2267,6 +2250,24 @@ connection_control_process_inbuf(control_connection_t *conn)
|
||||||
conn->incoming_cmd_cur_len = 0;
|
conn->incoming_cmd_cur_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
|
||||||
|
peek_buf_has_control0_command(conn->_base.inbuf)) {
|
||||||
|
/* Detect v0 commands and send a "no more v0" message. */
|
||||||
|
size_t body_len;
|
||||||
|
char buf[128];
|
||||||
|
set_uint16(buf+2, htons(0x0000)); /* type == error */
|
||||||
|
set_uint16(buf+4, htons(0x0001)); /* code == internal error */
|
||||||
|
strlcpy(buf+6, "The v0 control protocol is not supported by Tor 0.2.0.x "
|
||||||
|
"and later; use Tor 0.1.2.x or upgrade your controller",
|
||||||
|
sizeof(buf)-6);
|
||||||
|
body_len = 2+strlen(buf+6)+2; /* code, msg, nul. */
|
||||||
|
set_uint16(buf+0, htons(body_len));
|
||||||
|
connection_write_to_buf(buf, 4+body_len, TO_CONN(conn));
|
||||||
|
connection_mark_for_close(TO_CONN(conn));
|
||||||
|
conn->_base.hold_open_until_flushed = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t last_idx;
|
size_t last_idx;
|
||||||
|
|
|
@ -1923,8 +1923,7 @@ int fetch_from_buf_http(buf_t *buf,
|
||||||
int force_complete);
|
int force_complete);
|
||||||
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
||||||
int log_sockstype, int safe_socks);
|
int log_sockstype, int safe_socks);
|
||||||
int fetch_from_buf_control0(buf_t *buf, uint32_t *len_out, uint16_t *type_out,
|
int peek_buf_has_control0_command(buf_t *buf);
|
||||||
char **body_out, int check_for_v1);
|
|
||||||
int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
|
int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
|
||||||
int fetch_from_buf_line_lf(buf_t *buf, char *data_out, size_t *data_len);
|
int fetch_from_buf_line_lf(buf_t *buf, char *data_out, size_t *data_len);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue