Tor
0.4.7.0-alpha-dev
|
Implementations for SOCKS4 and SOCKS5 protocols. More...
#include "core/or/or.h"
#include "feature/client/addressmap.h"
#include "lib/buf/buffers.h"
#include "core/mainloop/connection.h"
#include "feature/control/control_events.h"
#include "app/config/config.h"
#include "lib/crypt_ops/crypto_util.h"
#include "feature/relay/ext_orport.h"
#include "core/proto/proto_socks.h"
#include "core/or/reasons.h"
#include "core/or/socks_request_st.h"
#include "trunnel/socks5.h"
Go to the source code of this file.
Macros | |
#define | SOCKS_VER_5 0x05 /* First octet of non-auth SOCKS5 messages */ |
#define | SOCKS_VER_4 0x04 /* SOCKS4 messages */ |
#define | SOCKS_AUTH 0x01 /* SOCKS5 auth messages */ |
#define | SOCKS_WARN_INTERVAL 5 |
#define | MAX_SOCKS_MESSAGE_LEN 512 |
Enumerations | |
enum | socks_result_t { SOCKS_RESULT_INVALID = -1 , SOCKS_RESULT_TRUNCATED = 0 , SOCKS_RESULT_DONE = 1 , SOCKS_RESULT_MORE_EXPECTED = 2 } |
Functions | |
static void | socks_request_set_socks5_error (socks_request_t *req, socks5_reply_status_t reason) |
static socks_result_t | parse_socks (const char *data, size_t datalen, socks_request_t *req, int log_sockstype, int safe_socks, size_t *drain_out) |
static int | parse_socks_client (const uint8_t *data, size_t datalen, int state, char **reason, ssize_t *drain_out) |
static void | log_unsafe_socks_warning (int socks_protocol, const char *address, uint16_t port, int safe_socks) |
socks_request_t * | socks_request_new (void) |
void | socks_request_free_ (socks_request_t *req) |
static socks_result_t | parse_socks4_request (const uint8_t *raw_data, socks_request_t *req, size_t datalen, int *is_socks4a, size_t *drain_out) |
static socks_result_t | process_socks4_request (const socks_request_t *req, int is_socks4a, int log_sockstype, int safe_socks) |
static socks_result_t | parse_socks5_methods_request (const uint8_t *raw_data, socks_request_t *req, size_t datalen, int *have_user_pass, int *have_no_auth, size_t *drain_out) |
static socks_result_t | process_socks5_methods_request (socks_request_t *req, int have_user_pass, int have_no_auth) |
static socks_result_t | parse_socks5_userpass_auth (const uint8_t *raw_data, socks_request_t *req, size_t datalen, size_t *drain_out) |
static socks_result_t | process_socks5_userpass_auth (socks_request_t *req) |
static socks_result_t | parse_socks5_client_request (const uint8_t *raw_data, socks_request_t *req, size_t datalen, size_t *drain_out) |
static socks_result_t | process_socks5_client_request (socks_request_t *req, int log_sockstype, int safe_socks) |
static socks_result_t | handle_socks_message (const uint8_t *raw_data, size_t datalen, socks_request_t *req, int log_sockstype, int safe_socks, size_t *drain_out) |
int | fetch_from_buf_socks (buf_t *buf, socks_request_t *req, int log_sockstype, int safe_socks) |
int | fetch_from_buf_socks_client (buf_t *buf, int state, char **reason) |
Variables | |
static const char | SOCKS_PROXY_IS_NOT_AN_HTTP_PROXY_MSG [] |
Implementations for SOCKS4 and SOCKS5 protocols.
Definition in file proto_socks.c.
#define MAX_SOCKS_MESSAGE_LEN 512 |
Do not attempt to parse socks messages longer than this. This value is actually significantly higher than the longest possible socks message.
Definition at line 83 of file proto_socks.c.
#define SOCKS_WARN_INTERVAL 5 |
Wait this many seconds before warning the user about using SOCKS unsafely again.
Definition at line 53 of file proto_socks.c.
int fetch_from_buf_socks | ( | buf_t * | buf, |
socks_request_t * | req, | ||
int | log_sockstype, | ||
int | safe_socks | ||
) |
There is a (possibly incomplete) socks handshake on buf, of one of the forms
If it's invalid or too big, return -1.
Else it's not all there yet, leave buf alone and return 0.
If you want to specify the socks reply, write it into req->reply and set req->replylen, else leave req->replylen alone.
If log_sockstype is non-zero, then do a notice-level log of whether the connection is possibly leaking DNS requests locally or not.
If safe_socks is true, then reject unsafe socks protocols.
If returning 0 or -1, req->address and req->port are undefined.
Definition at line 829 of file proto_socks.c.
int fetch_from_buf_socks_client | ( | buf_t * | buf, |
int | state, | ||
char ** | reason | ||
) |
Inspect a reply from SOCKS server stored in buf according to state, removing the protocol data upon success. Return 0 on incomplete response, 1 on success and -1 on error, in which case reason is set to a descriptive message (free() when finished with it).
As a special case, 2 is returned when user/pass is required during SOCKS5 handshake and user/pass is configured.
Definition at line 1005 of file proto_socks.c.
Referenced by connection_fetch_from_buf_socks_client().
|
static |
Handle (parse, validate, process, respond) a single SOCKS message in buffer raw_data of length datalen. Update relevant fields of req. If log_sockstype is true, log a warning about possible DNS leaks on local system. If safe_socks is true, disallow insecure usage of SOCKS protocol. Set *drain_out to number of bytes in raw_data that we processed so far and that can be safely drained from buffer.
Return:
Definition at line 702 of file proto_socks.c.
|
static |
Warn that the user application has made an unsafe socks request using protocol socks_protocol on port port. Don't warn more than once per SOCKS_WARN_INTERVAL, unless safe_socks is set.
Definition at line 59 of file proto_socks.c.
Referenced by process_socks4_request().
|
static |
Implementation helper to implement fetch_from_*_socks. Instead of looking at a buffer's contents, we look at the datalen bytes of data in data. Instead of removing data from the buffer, we set drain_out to the amount of data that should be removed (or -1 if the buffer should be cleared). Instead of pulling more data into the first chunk of the buffer, we set *want_length_out to the number of bytes we'd like to see in the input buffer, if they're available.
Definition at line 948 of file proto_socks.c.
|
static |
Parse a single SOCKS4 request from buffer raw_data of length datalen and update relevant fields of req. If SOCKS4a request is detected, set *is_socks4a to true. Set *drain_out to number of bytes we parsed so far.
Return SOCKS_RESULT_DONE if parsing succeeded, SOCKS_RESULT_INVALID if parsing failed because of invalid input or SOCKS_RESULT_TRUNCATED if it failed due to incomplete (truncated) input.
Definition at line 121 of file proto_socks.c.
|
static |
Parse a single SOCKS5 client request (RFC 1928 section 4) from buffer raw_data of length datalen and update relevant field of req. Set *drain_out to number of bytes we parsed so far.
Return SOCKS_RESULT_DONE if parsing succeeded, SOCKS_RESULT_INVALID if parsing failed because of invalid input or SOCKS_RESULT_TRUNCATED if it failed due to incomplete (truncated) input.
Definition at line 542 of file proto_socks.c.
|
static |
Parse a single SOCKS5 version identifier/method selection message from buffer raw_data (of length datalen). Update relevant fields of req (if any). Set *have_user_pass to true if username/password method is found. Set *have_no_auth if no-auth method is found. Set *drain_out to number of bytes we parsed so far.
Return SOCKS_RESULT_DONE if parsing succeeded, SOCKS_RESULT_INVALID if parsing failed because of invalid input or SOCKS_RESULT_TRUNCATED if it failed due to incomplete (truncated) input.
Definition at line 283 of file proto_socks.c.
|
static |
Parse SOCKS5/RFC1929 username/password request from buffer raw_data of length datalen and update relevant fields of req. Set *drain_out to number of bytes we parsed so far.
Return SOCKS_RESULT_DONE if parsing succeeded, SOCKS_RESULT_INVALID if parsing failed because of invalid input or SOCKS_RESULT_TRUNCATED if it failed due to incomplete (truncated) input.
Yes, we allow username and/or password to be empty. Yes, that does violate RFC 1929. However, some client software can send a username/ password message with these fields being empty and we want to allow them to be used with Tor.
Definition at line 422 of file proto_socks.c.
|
static |
Implementation logic for fetch_from_*_socks_client.
Definition at line 1030 of file proto_socks.c.
Referenced by fetch_from_buf_socks_client().
|
static |
Validate SOCKS4/4a related fields in req. Expect SOCKS4a if is_socks4a is true. If log_sockstype is true, log a notice about possible DNS leaks on local system. If safe_socks is true, reject insecure usage of SOCKS protocol.
Return SOCKS_RESULT_DONE if validation passed or SOCKS_RESULT_INVALID if it failed.
Definition at line 233 of file proto_socks.c.
|
static |
Validate and respond to SOCKS5 request we parsed in parse_socks5_client_request (corresponding to req. Write appropriate response to req->reply (in SOCKS5 wire format). If log_sockstype is true, log a notice about possible DNS leaks on local system. If safe_socks is true, disallow insecure usage of SOCKS protocol. Return SOCKS_RESULT_DONE on success or SOCKS_RESULT_INVALID on failure.
Definition at line 620 of file proto_socks.c.
|
static |
Validate and respond to version identifier/method selection message we parsed in parse_socks5_methods_request (corresponding to req and having user/pass method if have_user_pass is true, no-auth method if have_no_auth is true). Set req->reply to an appropriate response (in SOCKS5 wire format).
On success, return SOCKS_RESULT_DONE. On failure, return SOCKS_RESULT_INVALID.
Definition at line 356 of file proto_socks.c.
|
static |
Validate and respond to SOCKS5 username/password request we parsed in parse_socks5_userpass_auth (corresponding to req. Set req->reply to appropriate response. Return SOCKS_RESULT_DONE on success or SOCKS_RESULT_INVALID on failure.
Definition at line 486 of file proto_socks.c.
void socks_request_free_ | ( | socks_request_t * | req | ) |
Free all storage held in the socks_request_t req.
Definition at line 94 of file proto_socks.c.
socks_request_t* socks_request_new | ( | void | ) |
Return a new socks_request_t.
Definition at line 87 of file proto_socks.c.
|
static |
Create a SOCKS5 reply message with reason in its REP field and have Tor send it as error response to req.
Definition at line 883 of file proto_socks.c.
|
static |
Definition at line 914 of file proto_socks.c.