|
@@ -339,6 +339,60 @@ static const char CONTROLPORT_IS_NOT_AN_HTTP_PROXY_MSG[] =
|
|
|
"</body>\n"
|
|
|
"</html>\n";
|
|
|
|
|
|
+/** Return an error on a control connection that tried to use the v0 protocol.
|
|
|
+ */
|
|
|
+static void
|
|
|
+control_send_v0_reject(control_connection_t *conn)
|
|
|
+{
|
|
|
+ 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.1.2.17 "
|
|
|
+ "and later; upgrade your controller.",
|
|
|
+ sizeof(buf)-6);
|
|
|
+ body_len = 2+strlen(buf+6)+2; /* code, msg, nul. */
|
|
|
+ set_uint16(buf+0, htons(body_len));
|
|
|
+ connection_buf_add(buf, 4+body_len, TO_CONN(conn));
|
|
|
+
|
|
|
+ connection_mark_and_flush(TO_CONN(conn));
|
|
|
+}
|
|
|
+
|
|
|
+/** Return an error on a control connection that tried to use HTTP.
|
|
|
+ */
|
|
|
+static void
|
|
|
+control_send_http_reject(control_connection_t *conn)
|
|
|
+{
|
|
|
+ connection_write_str_to_buf(CONTROLPORT_IS_NOT_AN_HTTP_PROXY_MSG, conn);
|
|
|
+ log_notice(LD_CONTROL, "Received HTTP request on ControlPort");
|
|
|
+ connection_mark_and_flush(TO_CONN(conn));
|
|
|
+}
|
|
|
+
|
|
|
+/** Check if a control connection has tried to use a known invalid protocol.
|
|
|
+ * If it has, then:
|
|
|
+ * - send a reject response,
|
|
|
+ * - log a notice-level message, and
|
|
|
+ * - return false. */
|
|
|
+static bool
|
|
|
+control_protocol_is_valid(control_connection_t *conn)
|
|
|
+{
|
|
|
+ /* Detect v0 commands and send a "no more v0" message. */
|
|
|
+ if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH &&
|
|
|
+ peek_connection_has_control0_command(TO_CONN(conn))) {
|
|
|
+ control_send_v0_reject(conn);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If the user has the HTTP proxy port and the control port confused. */
|
|
|
+ if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH &&
|
|
|
+ peek_connection_has_http_command(TO_CONN(conn))) {
|
|
|
+ control_send_http_reject(conn);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
/** Called when data has arrived on a v1 control connection: Try to fetch
|
|
|
* commands from conn->inbuf, and execute them.
|
|
|
*/
|
|
@@ -359,30 +413,7 @@ connection_control_process_inbuf(control_connection_t *conn)
|
|
|
conn->incoming_cmd_cur_len = 0;
|
|
|
}
|
|
|
|
|
|
- if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH &&
|
|
|
- peek_connection_has_control0_command(TO_CONN(conn))) {
|
|
|
- /* 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.1.2.17 "
|
|
|
- "and later; upgrade your controller.",
|
|
|
- sizeof(buf)-6);
|
|
|
- body_len = 2+strlen(buf+6)+2; /* code, msg, nul. */
|
|
|
- set_uint16(buf+0, htons(body_len));
|
|
|
- connection_buf_add(buf, 4+body_len, TO_CONN(conn));
|
|
|
-
|
|
|
- connection_mark_and_flush(TO_CONN(conn));
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- /* If the user has the HTTP proxy port and the control port confused. */
|
|
|
- if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH &&
|
|
|
- peek_connection_has_http_command(TO_CONN(conn))) {
|
|
|
- connection_write_str_to_buf(CONTROLPORT_IS_NOT_AN_HTTP_PROXY_MSG, conn);
|
|
|
- log_notice(LD_CONTROL, "Received HTTP request on ControlPort");
|
|
|
- connection_mark_and_flush(TO_CONN(conn));
|
|
|
+ if (!control_protocol_is_valid(conn)) {
|
|
|
return 0;
|
|
|
}
|
|
|
|