Merge branch 'socks_trunnel4_squashed_merged'

This commit is contained in:
Nick Mathewson 2018-07-15 17:07:20 -04:00
commit ef234ba303
11 changed files with 5932 additions and 366 deletions

6
changes/ticket3569_part1 Normal file
View File

@ -0,0 +1,6 @@
o Code simplification and refactoring:
- Rework Tor SOCKS server code to use Trunnel and benefit from
autogenerated functions for parsing and generating SOCKS wire
format. New implementation is cleaner, more maintainable and
should be less prone to heartbleed-style vulnerabilities.
Implements a significant fraction of ticket 3569.

View File

@ -12,6 +12,7 @@ FUZZERS = """
http-connect
iptsv2
microdesc
socks
vrs
"""

View File

@ -70,6 +70,8 @@ struct socks_request_t {
/** The negotiated password value if any (for socks5). This value is NOT
* nul-terminated; see passwordlen for its length. */
char *password;
uint8_t socks5_atyp; /* SOCKS5 address type */
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define BUFFERS_PRIVATE
#include "core/or/or.h"
#include "lib/container/buffers.h"
#include "lib/err/backtrace.h"
#include "lib/log/log.h"
#include "core/proto/proto_socks.h"
#include "feature/client/addressmap.h"
#include "test/fuzz/fuzzing.h"
int
fuzz_init(void)
{
addressmap_init();
return 0;
}
int
fuzz_cleanup(void)
{
addressmap_free_all();
return 0;
}
int
fuzz_main(const uint8_t *stdin_buf, size_t data_size)
{
buf_t *buffer = buf_new_with_data((char*)stdin_buf, data_size);
if (!buffer) {
tor_assert(data_size==0);
buffer = buf_new();
}
socks_request_t *request = socks_request_new();
int r = fetch_from_buf_socks(buffer, request, 0, 0);
log_info(LD_GENERAL, "Socks request status: %d", r);
/* Reset. */
buf_free(buffer);
socks_request_free(request);
return 0;
}

View File

@ -17,7 +17,7 @@ FUZZING_LIBS = \
@TOR_ZSTD_LIBS@
oss-fuzz-prereqs: \
$(TOR_INTERNAL_TESTING_LIBS)
$(TOR_INTERNAL_TESTING_LIBS)
noinst_HEADERS += \
src/test/fuzz/fuzzing.h
@ -120,6 +120,14 @@ src_test_fuzz_fuzz_microdesc_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_microdesc_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_microdesc_LDADD = $(FUZZING_LIBS)
src_test_fuzz_fuzz_socks_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_socks.c
src_test_fuzz_fuzz_socks_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_socks_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_socks_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_socks_LDADD = $(FUZZING_LIBS)
src_test_fuzz_fuzz_vrs_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_vrs.c
@ -140,6 +148,7 @@ FUZZERS = \
src/test/fuzz/fuzz-http-connect \
src/test/fuzz/fuzz-iptsv2 \
src/test/fuzz/fuzz-microdesc \
src/test/fuzz/fuzz-socks \
src/test/fuzz/fuzz-vrs
# ===== libfuzzer
@ -222,6 +231,13 @@ src_test_fuzz_lf_fuzz_microdesc_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_microdesc_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_microdesc_LDADD = $(LIBFUZZER_LIBS)
src_test_fuzz_lf_fuzz_socks_SOURCES = \
$(src_test_fuzz_fuzz_socks_SOURCES)
src_test_fuzz_lf_fuzz_socks_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_socks_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_socks_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_socks_LDADD = $(LIBFUZZER_LIBS)
src_test_fuzz_lf_fuzz_vrs_SOURCES = \
$(src_test_fuzz_fuzz_vrs_SOURCES)
src_test_fuzz_lf_fuzz_vrs_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
@ -241,6 +257,7 @@ LIBFUZZER_FUZZERS = \
src/test/fuzz/lf-fuzz-http-connect \
src/test/fuzz/lf-fuzz-iptsv2 \
src/test/fuzz/lf-fuzz-microdesc \
src/test/fuzz/lf-fuzz-socks \
src/test/fuzz/lf-fuzz-vrs
else
@ -305,6 +322,11 @@ src_test_fuzz_liboss_fuzz_microdesc_a_SOURCES = \
src_test_fuzz_liboss_fuzz_microdesc_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_microdesc_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
src_test_fuzz_liboss_fuzz_socks_a_SOURCES = \
$(src_test_fuzz_fuzz_socks_SOURCES)
src_test_fuzz_liboss_fuzz_socks_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_socks_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
src_test_fuzz_liboss_fuzz_vrs_a_SOURCES = \
$(src_test_fuzz_fuzz_vrs_SOURCES)
src_test_fuzz_liboss_fuzz_vrs_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
@ -322,6 +344,7 @@ OSS_FUZZ_FUZZERS = \
src/test/fuzz/liboss-fuzz-http-connect.a \
src/test/fuzz/liboss-fuzz-iptsv2.a \
src/test/fuzz/liboss-fuzz-microdesc.a \
src/test/fuzz/liboss-fuzz-socks.a \
src/test/fuzz/liboss-fuzz-vrs.a
else

View File

@ -84,7 +84,7 @@ test_socks_4_supported_commands(void *ptr)
tt_int_op(0,OP_EQ, buf_datalen(buf));
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.3:4370 */
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks),
@ -100,7 +100,7 @@ test_socks_4_supported_commands(void *ptr)
tt_int_op(0,OP_EQ, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.4:4369 with userid*/
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, 1);
@ -166,7 +166,7 @@ test_socks_4_bad_arguments(void *ptr)
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, -1);
buf_clear(buf);
expect_log_msg_containing("user name too long; rejecting.");
expect_log_msg_containing("socks4: parsing failed - invalid request.");
mock_clean_saved_logs();
/* Try with 2000-byte hostname */
@ -194,7 +194,7 @@ test_socks_4_bad_arguments(void *ptr)
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, -1);
buf_clear(buf);
expect_log_msg_containing("Destaddr too long.");
expect_log_msg_containing("parsing failed - invalid request.");
mock_clean_saved_logs();
/* Socks4, bogus hostname */
@ -648,7 +648,8 @@ test_socks_5_malformed_commands(void *ptr)
tt_int_op(5,OP_EQ,socks->socks_version);
tt_int_op(10,OP_EQ,socks->replylen);
tt_int_op(5,OP_EQ,socks->reply[0]);
tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
/* trunnel parsing will fail with -1 */
tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
tt_int_op(1,OP_EQ,socks->reply[3]);
done:

View File

@ -10,7 +10,8 @@ TRUNNELINPUTS = \
src/trunnel/ed25519_cert.trunnel \
src/trunnel/link_handshake.trunnel \
src/trunnel/pwbox.trunnel \
src/trunnel/channelpadding_negotiation.trunnel
src/trunnel/channelpadding_negotiation.trunnel \
src/trunner/socks5.trunnel
TRUNNELSOURCES = \
src/ext/trunnel/trunnel.c \
@ -21,7 +22,8 @@ TRUNNELSOURCES = \
src/trunnel/hs/cell_establish_intro.c \
src/trunnel/hs/cell_introduce1.c \
src/trunnel/hs/cell_rendezvous.c \
src/trunnel/channelpadding_negotiation.c
src/trunnel/channelpadding_negotiation.c \
src/trunnel/socks5.c
TRUNNELHEADERS = \
src/ext/trunnel/trunnel.h \
@ -34,7 +36,8 @@ TRUNNELHEADERS = \
src/trunnel/hs/cell_establish_intro.h \
src/trunnel/hs/cell_introduce1.h \
src/trunnel/hs/cell_rendezvous.h \
src/trunnel/channelpadding_negotiation.h
src/trunnel/channelpadding_negotiation.h \
src/trunnel/socks5.h
src_trunnel_libor_trunnel_a_SOURCES = $(TRUNNELSOURCES)
src_trunnel_libor_trunnel_a_CPPFLAGS = \

3978
src/trunnel/socks5.c Normal file

File diff suppressed because it is too large Load Diff

995
src/trunnel/socks5.h Normal file
View File

@ -0,0 +1,995 @@
/* socks5.h -- generated by Trunnel v1.5.2.
* https://gitweb.torproject.org/trunnel.git
* You probably shouldn't edit this file.
*/
#ifndef TRUNNEL_SOCKS5_H
#define TRUNNEL_SOCKS5_H
#include <stdint.h>
#include "trunnel.h"
#define CMD_CONNECT 1
#define CMD_BIND 2
#define CMD_UDP_ASSOCIATE 3
#define CMD_RESOLVE 240
#define CMD_RESOLVE_PTR 241
#define ATYPE_IPV4 1
#define ATYPE_IPV6 4
#define ATYPE_DOMAINNAME 3
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_DOMAINNAME)
struct domainname_st {
uint8_t len;
trunnel_string_t name;
uint8_t trunnel_error_code_;
};
#endif
typedef struct domainname_st domainname_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS4_CLIENT_REQUEST)
struct socks4_client_request_st {
uint8_t version;
uint8_t command;
uint16_t port;
uint32_t addr;
char *username;
char *socks4a_addr_hostname;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks4_client_request_st socks4_client_request_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS4_SERVER_REPLY)
struct socks4_server_reply_st {
uint8_t version;
uint8_t status;
uint16_t port;
uint32_t addr;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks4_server_reply_st socks4_server_reply_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_CLIENT_USERPASS_AUTH)
struct socks5_client_userpass_auth_st {
uint8_t version;
uint8_t username_len;
trunnel_string_t username;
uint8_t passwd_len;
trunnel_string_t passwd;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_client_userpass_auth_st socks5_client_userpass_auth_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_CLIENT_VERSION)
struct socks5_client_version_st {
uint8_t version;
uint8_t n_methods;
TRUNNEL_DYNARRAY_HEAD(, uint8_t) methods;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_client_version_st socks5_client_version_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_SERVER_METHOD)
struct socks5_server_method_st {
uint8_t version;
uint8_t method;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_server_method_st socks5_server_method_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_SERVER_USERPASS_AUTH)
struct socks5_server_userpass_auth_st {
uint8_t version;
uint8_t status;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_server_userpass_auth_st socks5_server_userpass_auth_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_CLIENT_REQUEST)
struct socks5_client_request_st {
uint8_t version;
uint8_t command;
uint8_t reserved;
uint8_t atype;
uint32_t dest_addr_ipv4;
uint8_t dest_addr_ipv6[16];
struct domainname_st *dest_addr_domainname;
uint16_t dest_port;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_client_request_st socks5_client_request_t;
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SOCKS5_SERVER_REPLY)
struct socks5_server_reply_st {
uint8_t version;
uint8_t reply;
uint8_t reserved;
uint8_t atype;
uint32_t bind_addr_ipv4;
uint8_t bind_addr_ipv6[16];
struct domainname_st *bind_addr_domainname;
uint16_t bind_port;
uint8_t trunnel_error_code_;
};
#endif
typedef struct socks5_server_reply_st socks5_server_reply_t;
/** Return a newly allocated domainname with all elements set to zero.
*/
domainname_t *domainname_new(void);
/** Release all storage held by the domainname in 'victim'. (Do
* nothing if 'victim' is NULL.)
*/
void domainname_free(domainname_t *victim);
/** Try to parse a domainname from the buffer in 'input', using up to
* 'len_in' bytes from the input buffer. On success, return the number
* of bytes consumed and set *output to the newly allocated
* domainname_t. On failure, return -2 if the input appears truncated,
* and -1 if the input is otherwise invalid.
*/
ssize_t domainname_parse(domainname_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* domainname in 'obj'. On failure, return a negative value. Note that
* this value may be an overestimate, and can even be an underestimate
* for certain unencodeable objects.
*/
ssize_t domainname_encoded_len(const domainname_t *obj);
/** Try to encode the domainname from 'input' into the buffer at
* 'output', using up to 'avail' bytes of the output buffer. On
* success, return the number of bytes used. On failure, return -2 if
* the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t domainname_encode(uint8_t *output, size_t avail, const domainname_t *input);
/** Check whether the internal state of the domainname in 'obj' is
* consistent. Return NULL if it is, and a short message if it is not.
*/
const char *domainname_check(const domainname_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int domainname_clear_errors(domainname_t *obj);
/** Return the value of the len field of the domainname_t in 'inp'
*/
uint8_t domainname_get_len(const domainname_t *inp);
/** Set the value of the len field of the domainname_t in 'inp' to
* 'val'. Return 0 on success; return -1 and set the error code on
* 'inp' on failure.
*/
int domainname_set_len(domainname_t *inp, uint8_t val);
/** Return the length of the dynamic array holding the name field of
* the domainname_t in 'inp'.
*/
size_t domainname_getlen_name(const domainname_t *inp);
/** Return the element at position 'idx' of the dynamic array field
* name of the domainname_t in 'inp'.
*/
char domainname_get_name(domainname_t *inp, size_t idx);
/** As domainname_get_name, but take and return a const pointer
*/
char domainname_getconst_name(const domainname_t *inp, size_t idx);
/** Change the element at position 'idx' of the dynamic array field
* name of the domainname_t in 'inp', so that it will hold the value
* 'elt'.
*/
int domainname_set_name(domainname_t *inp, size_t idx, char elt);
/** Append a new element 'elt' to the dynamic array field name of the
* domainname_t in 'inp'.
*/
int domainname_add_name(domainname_t *inp, char elt);
/** Return a pointer to the variable-length array field name of 'inp'.
*/
char * domainname_getarray_name(domainname_t *inp);
/** As domainname_get_name, but take and return a const pointer
*/
const char * domainname_getconstarray_name(const domainname_t *inp);
/** Change the length of the variable-length array field name of 'inp'
* to 'newlen'.Fill extra elements with 0. Return 0 on success; return
* -1 and set the error code on 'inp' on failure.
*/
int domainname_setlen_name(domainname_t *inp, size_t newlen);
/** Return the value of the name field of a domainname_t as a NUL-
* terminated string.
*/
const char * domainname_getstr_name(domainname_t *inp);
/** Set the value of the name field of a domainname_t to a given
* string of length 'len'. Return 0 on success; return -1 and set the
* error code on 'inp' on failure.
*/
int domainname_setstr0_name(domainname_t *inp, const char *val, size_t len);
/** Set the value of the name field of a domainname_t to a given NUL-
* terminated string. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int domainname_setstr_name(domainname_t *inp, const char *val);
/** Return a newly allocated socks4_client_request with all elements
* set to zero.
*/
socks4_client_request_t *socks4_client_request_new(void);
/** Release all storage held by the socks4_client_request in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks4_client_request_free(socks4_client_request_t *victim);
/** Try to parse a socks4_client_request from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks4_client_request_t. On failure, return -2 if the
* input appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks4_client_request_parse(socks4_client_request_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks4_client_request in 'obj'. On failure, return a negative
* value. Note that this value may be an overestimate, and can even be
* an underestimate for certain unencodeable objects.
*/
ssize_t socks4_client_request_encoded_len(const socks4_client_request_t *obj);
/** Try to encode the socks4_client_request from 'input' into the
* buffer at 'output', using up to 'avail' bytes of the output buffer.
* On success, return the number of bytes used. On failure, return -2
* if the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks4_client_request_encode(uint8_t *output, size_t avail, const socks4_client_request_t *input);
/** Check whether the internal state of the socks4_client_request in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks4_client_request_check(const socks4_client_request_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks4_client_request_clear_errors(socks4_client_request_t *obj);
/** Return the value of the version field of the
* socks4_client_request_t in 'inp'
*/
uint8_t socks4_client_request_get_version(const socks4_client_request_t *inp);
/** Set the value of the version field of the socks4_client_request_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_client_request_set_version(socks4_client_request_t *inp, uint8_t val);
/** Return the value of the command field of the
* socks4_client_request_t in 'inp'
*/
uint8_t socks4_client_request_get_command(const socks4_client_request_t *inp);
/** Set the value of the command field of the socks4_client_request_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_client_request_set_command(socks4_client_request_t *inp, uint8_t val);
/** Return the value of the port field of the socks4_client_request_t
* in 'inp'
*/
uint16_t socks4_client_request_get_port(const socks4_client_request_t *inp);
/** Set the value of the port field of the socks4_client_request_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_client_request_set_port(socks4_client_request_t *inp, uint16_t val);
/** Return the value of the addr field of the socks4_client_request_t
* in 'inp'
*/
uint32_t socks4_client_request_get_addr(const socks4_client_request_t *inp);
/** Set the value of the addr field of the socks4_client_request_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_client_request_set_addr(socks4_client_request_t *inp, uint32_t val);
/** Return the value of the username field of the
* socks4_client_request_t in 'inp'
*/
const char * socks4_client_request_get_username(const socks4_client_request_t *inp);
/** Set the value of the username field of the socks4_client_request_t
* in 'inp' to 'val'. Free the old value if any. Does not steal the
* reference to 'val'.Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_client_request_set_username(socks4_client_request_t *inp, const char *val);
/** Return the value of the socks4a_addr_hostname field of the
* socks4_client_request_t in 'inp'
*/
const char * socks4_client_request_get_socks4a_addr_hostname(const socks4_client_request_t *inp);
/** Set the value of the socks4a_addr_hostname field of the
* socks4_client_request_t in 'inp' to 'val'. Free the old value if
* any. Does not steal the reference to 'val'.Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks4_client_request_set_socks4a_addr_hostname(socks4_client_request_t *inp, const char *val);
/** Return a newly allocated socks4_server_reply with all elements set
* to zero.
*/
socks4_server_reply_t *socks4_server_reply_new(void);
/** Release all storage held by the socks4_server_reply in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks4_server_reply_free(socks4_server_reply_t *victim);
/** Try to parse a socks4_server_reply from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks4_server_reply_t. On failure, return -2 if the input
* appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks4_server_reply_parse(socks4_server_reply_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks4_server_reply in 'obj'. On failure, return a negative value.
* Note that this value may be an overestimate, and can even be an
* underestimate for certain unencodeable objects.
*/
ssize_t socks4_server_reply_encoded_len(const socks4_server_reply_t *obj);
/** Try to encode the socks4_server_reply from 'input' into the buffer
* at 'output', using up to 'avail' bytes of the output buffer. On
* success, return the number of bytes used. On failure, return -2 if
* the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks4_server_reply_encode(uint8_t *output, size_t avail, const socks4_server_reply_t *input);
/** Check whether the internal state of the socks4_server_reply in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks4_server_reply_check(const socks4_server_reply_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks4_server_reply_clear_errors(socks4_server_reply_t *obj);
/** Return the value of the version field of the socks4_server_reply_t
* in 'inp'
*/
uint8_t socks4_server_reply_get_version(const socks4_server_reply_t *inp);
/** Set the value of the version field of the socks4_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_server_reply_set_version(socks4_server_reply_t *inp, uint8_t val);
/** Return the value of the status field of the socks4_server_reply_t
* in 'inp'
*/
uint8_t socks4_server_reply_get_status(const socks4_server_reply_t *inp);
/** Set the value of the status field of the socks4_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_server_reply_set_status(socks4_server_reply_t *inp, uint8_t val);
/** Return the value of the port field of the socks4_server_reply_t in
* 'inp'
*/
uint16_t socks4_server_reply_get_port(const socks4_server_reply_t *inp);
/** Set the value of the port field of the socks4_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_server_reply_set_port(socks4_server_reply_t *inp, uint16_t val);
/** Return the value of the addr field of the socks4_server_reply_t in
* 'inp'
*/
uint32_t socks4_server_reply_get_addr(const socks4_server_reply_t *inp);
/** Set the value of the addr field of the socks4_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks4_server_reply_set_addr(socks4_server_reply_t *inp, uint32_t val);
/** Return a newly allocated socks5_client_userpass_auth with all
* elements set to zero.
*/
socks5_client_userpass_auth_t *socks5_client_userpass_auth_new(void);
/** Release all storage held by the socks5_client_userpass_auth in
* 'victim'. (Do nothing if 'victim' is NULL.)
*/
void socks5_client_userpass_auth_free(socks5_client_userpass_auth_t *victim);
/** Try to parse a socks5_client_userpass_auth from the buffer in
* 'input', using up to 'len_in' bytes from the input buffer. On
* success, return the number of bytes consumed and set *output to the
* newly allocated socks5_client_userpass_auth_t. On failure, return
* -2 if the input appears truncated, and -1 if the input is otherwise
* invalid.
*/
ssize_t socks5_client_userpass_auth_parse(socks5_client_userpass_auth_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_client_userpass_auth in 'obj'. On failure, return a negative
* value. Note that this value may be an overestimate, and can even be
* an underestimate for certain unencodeable objects.
*/
ssize_t socks5_client_userpass_auth_encoded_len(const socks5_client_userpass_auth_t *obj);
/** Try to encode the socks5_client_userpass_auth from 'input' into
* the buffer at 'output', using up to 'avail' bytes of the output
* buffer. On success, return the number of bytes used. On failure,
* return -2 if the buffer was not long enough, and -1 if the input
* was invalid.
*/
ssize_t socks5_client_userpass_auth_encode(uint8_t *output, size_t avail, const socks5_client_userpass_auth_t *input);
/** Check whether the internal state of the
* socks5_client_userpass_auth in 'obj' is consistent. Return NULL if
* it is, and a short message if it is not.
*/
const char *socks5_client_userpass_auth_check(const socks5_client_userpass_auth_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_client_userpass_auth_clear_errors(socks5_client_userpass_auth_t *obj);
/** Return the value of the version field of the
* socks5_client_userpass_auth_t in 'inp'
*/
uint8_t socks5_client_userpass_auth_get_version(const socks5_client_userpass_auth_t *inp);
/** Set the value of the version field of the
* socks5_client_userpass_auth_t in 'inp' to 'val'. Return 0 on
* success; return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_userpass_auth_set_version(socks5_client_userpass_auth_t *inp, uint8_t val);
/** Return the value of the username_len field of the
* socks5_client_userpass_auth_t in 'inp'
*/
uint8_t socks5_client_userpass_auth_get_username_len(const socks5_client_userpass_auth_t *inp);
/** Set the value of the username_len field of the
* socks5_client_userpass_auth_t in 'inp' to 'val'. Return 0 on
* success; return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_userpass_auth_set_username_len(socks5_client_userpass_auth_t *inp, uint8_t val);
/** Return the length of the dynamic array holding the username field
* of the socks5_client_userpass_auth_t in 'inp'.
*/
size_t socks5_client_userpass_auth_getlen_username(const socks5_client_userpass_auth_t *inp);
/** Return the element at position 'idx' of the dynamic array field
* username of the socks5_client_userpass_auth_t in 'inp'.
*/
char socks5_client_userpass_auth_get_username(socks5_client_userpass_auth_t *inp, size_t idx);
/** As socks5_client_userpass_auth_get_username, but take and return a
* const pointer
*/
char socks5_client_userpass_auth_getconst_username(const socks5_client_userpass_auth_t *inp, size_t idx);
/** Change the element at position 'idx' of the dynamic array field
* username of the socks5_client_userpass_auth_t in 'inp', so that it
* will hold the value 'elt'.
*/
int socks5_client_userpass_auth_set_username(socks5_client_userpass_auth_t *inp, size_t idx, char elt);
/** Append a new element 'elt' to the dynamic array field username of
* the socks5_client_userpass_auth_t in 'inp'.
*/
int socks5_client_userpass_auth_add_username(socks5_client_userpass_auth_t *inp, char elt);
/** Return a pointer to the variable-length array field username of
* 'inp'.
*/
char * socks5_client_userpass_auth_getarray_username(socks5_client_userpass_auth_t *inp);
/** As socks5_client_userpass_auth_get_username, but take and return a
* const pointer
*/
const char * socks5_client_userpass_auth_getconstarray_username(const socks5_client_userpass_auth_t *inp);
/** Change the length of the variable-length array field username of
* 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_userpass_auth_setlen_username(socks5_client_userpass_auth_t *inp, size_t newlen);
/** Return the value of the username field of a
* socks5_client_userpass_auth_t as a NUL-terminated string.
*/
const char * socks5_client_userpass_auth_getstr_username(socks5_client_userpass_auth_t *inp);
/** Set the value of the username field of a
* socks5_client_userpass_auth_t to a given string of length 'len'.
* Return 0 on success; return -1 and set the error code on 'inp' on
* failure.
*/
int socks5_client_userpass_auth_setstr0_username(socks5_client_userpass_auth_t *inp, const char *val, size_t len);
/** Set the value of the username field of a
* socks5_client_userpass_auth_t to a given NUL-terminated string.
* Return 0 on success; return -1 and set the error code on 'inp' on
* failure.
*/
int socks5_client_userpass_auth_setstr_username(socks5_client_userpass_auth_t *inp, const char *val);
/** Return the value of the passwd_len field of the
* socks5_client_userpass_auth_t in 'inp'
*/
uint8_t socks5_client_userpass_auth_get_passwd_len(const socks5_client_userpass_auth_t *inp);
/** Set the value of the passwd_len field of the
* socks5_client_userpass_auth_t in 'inp' to 'val'. Return 0 on
* success; return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_userpass_auth_set_passwd_len(socks5_client_userpass_auth_t *inp, uint8_t val);
/** Return the length of the dynamic array holding the passwd field of
* the socks5_client_userpass_auth_t in 'inp'.
*/
size_t socks5_client_userpass_auth_getlen_passwd(const socks5_client_userpass_auth_t *inp);
/** Return the element at position 'idx' of the dynamic array field
* passwd of the socks5_client_userpass_auth_t in 'inp'.
*/
char socks5_client_userpass_auth_get_passwd(socks5_client_userpass_auth_t *inp, size_t idx);
/** As socks5_client_userpass_auth_get_passwd, but take and return a
* const pointer
*/
char socks5_client_userpass_auth_getconst_passwd(const socks5_client_userpass_auth_t *inp, size_t idx);
/** Change the element at position 'idx' of the dynamic array field
* passwd of the socks5_client_userpass_auth_t in 'inp', so that it
* will hold the value 'elt'.
*/
int socks5_client_userpass_auth_set_passwd(socks5_client_userpass_auth_t *inp, size_t idx, char elt);
/** Append a new element 'elt' to the dynamic array field passwd of
* the socks5_client_userpass_auth_t in 'inp'.
*/
int socks5_client_userpass_auth_add_passwd(socks5_client_userpass_auth_t *inp, char elt);
/** Return a pointer to the variable-length array field passwd of
* 'inp'.
*/
char * socks5_client_userpass_auth_getarray_passwd(socks5_client_userpass_auth_t *inp);
/** As socks5_client_userpass_auth_get_passwd, but take and return a
* const pointer
*/
const char * socks5_client_userpass_auth_getconstarray_passwd(const socks5_client_userpass_auth_t *inp);
/** Change the length of the variable-length array field passwd of
* 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_userpass_auth_setlen_passwd(socks5_client_userpass_auth_t *inp, size_t newlen);
/** Return the value of the passwd field of a
* socks5_client_userpass_auth_t as a NUL-terminated string.
*/
const char * socks5_client_userpass_auth_getstr_passwd(socks5_client_userpass_auth_t *inp);
/** Set the value of the passwd field of a
* socks5_client_userpass_auth_t to a given string of length 'len'.
* Return 0 on success; return -1 and set the error code on 'inp' on
* failure.
*/
int socks5_client_userpass_auth_setstr0_passwd(socks5_client_userpass_auth_t *inp, const char *val, size_t len);
/** Set the value of the passwd field of a
* socks5_client_userpass_auth_t to a given NUL-terminated string.
* Return 0 on success; return -1 and set the error code on 'inp' on
* failure.
*/
int socks5_client_userpass_auth_setstr_passwd(socks5_client_userpass_auth_t *inp, const char *val);
/** Return a newly allocated socks5_client_version with all elements
* set to zero.
*/
socks5_client_version_t *socks5_client_version_new(void);
/** Release all storage held by the socks5_client_version in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks5_client_version_free(socks5_client_version_t *victim);
/** Try to parse a socks5_client_version from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks5_client_version_t. On failure, return -2 if the
* input appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks5_client_version_parse(socks5_client_version_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_client_version in 'obj'. On failure, return a negative
* value. Note that this value may be an overestimate, and can even be
* an underestimate for certain unencodeable objects.
*/
ssize_t socks5_client_version_encoded_len(const socks5_client_version_t *obj);
/** Try to encode the socks5_client_version from 'input' into the
* buffer at 'output', using up to 'avail' bytes of the output buffer.
* On success, return the number of bytes used. On failure, return -2
* if the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks5_client_version_encode(uint8_t *output, size_t avail, const socks5_client_version_t *input);
/** Check whether the internal state of the socks5_client_version in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks5_client_version_check(const socks5_client_version_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_client_version_clear_errors(socks5_client_version_t *obj);
/** Return the value of the version field of the
* socks5_client_version_t in 'inp'
*/
uint8_t socks5_client_version_get_version(const socks5_client_version_t *inp);
/** Set the value of the version field of the socks5_client_version_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_client_version_set_version(socks5_client_version_t *inp, uint8_t val);
/** Return the value of the n_methods field of the
* socks5_client_version_t in 'inp'
*/
uint8_t socks5_client_version_get_n_methods(const socks5_client_version_t *inp);
/** Set the value of the n_methods field of the
* socks5_client_version_t in 'inp' to 'val'. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_version_set_n_methods(socks5_client_version_t *inp, uint8_t val);
/** Return the length of the dynamic array holding the methods field
* of the socks5_client_version_t in 'inp'.
*/
size_t socks5_client_version_getlen_methods(const socks5_client_version_t *inp);
/** Return the element at position 'idx' of the dynamic array field
* methods of the socks5_client_version_t in 'inp'.
*/
uint8_t socks5_client_version_get_methods(socks5_client_version_t *inp, size_t idx);
/** As socks5_client_version_get_methods, but take and return a const
* pointer
*/
uint8_t socks5_client_version_getconst_methods(const socks5_client_version_t *inp, size_t idx);
/** Change the element at position 'idx' of the dynamic array field
* methods of the socks5_client_version_t in 'inp', so that it will
* hold the value 'elt'.
*/
int socks5_client_version_set_methods(socks5_client_version_t *inp, size_t idx, uint8_t elt);
/** Append a new element 'elt' to the dynamic array field methods of
* the socks5_client_version_t in 'inp'.
*/
int socks5_client_version_add_methods(socks5_client_version_t *inp, uint8_t elt);
/** Return a pointer to the variable-length array field methods of
* 'inp'.
*/
uint8_t * socks5_client_version_getarray_methods(socks5_client_version_t *inp);
/** As socks5_client_version_get_methods, but take and return a const
* pointer
*/
const uint8_t * socks5_client_version_getconstarray_methods(const socks5_client_version_t *inp);
/** Change the length of the variable-length array field methods of
* 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_version_setlen_methods(socks5_client_version_t *inp, size_t newlen);
/** Return a newly allocated socks5_server_method with all elements
* set to zero.
*/
socks5_server_method_t *socks5_server_method_new(void);
/** Release all storage held by the socks5_server_method in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks5_server_method_free(socks5_server_method_t *victim);
/** Try to parse a socks5_server_method from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks5_server_method_t. On failure, return -2 if the
* input appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks5_server_method_parse(socks5_server_method_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_server_method in 'obj'. On failure, return a negative value.
* Note that this value may be an overestimate, and can even be an
* underestimate for certain unencodeable objects.
*/
ssize_t socks5_server_method_encoded_len(const socks5_server_method_t *obj);
/** Try to encode the socks5_server_method from 'input' into the
* buffer at 'output', using up to 'avail' bytes of the output buffer.
* On success, return the number of bytes used. On failure, return -2
* if the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks5_server_method_encode(uint8_t *output, size_t avail, const socks5_server_method_t *input);
/** Check whether the internal state of the socks5_server_method in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks5_server_method_check(const socks5_server_method_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_server_method_clear_errors(socks5_server_method_t *obj);
/** Return the value of the version field of the
* socks5_server_method_t in 'inp'
*/
uint8_t socks5_server_method_get_version(const socks5_server_method_t *inp);
/** Set the value of the version field of the socks5_server_method_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_method_set_version(socks5_server_method_t *inp, uint8_t val);
/** Return the value of the method field of the socks5_server_method_t
* in 'inp'
*/
uint8_t socks5_server_method_get_method(const socks5_server_method_t *inp);
/** Set the value of the method field of the socks5_server_method_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_method_set_method(socks5_server_method_t *inp, uint8_t val);
/** Return a newly allocated socks5_server_userpass_auth with all
* elements set to zero.
*/
socks5_server_userpass_auth_t *socks5_server_userpass_auth_new(void);
/** Release all storage held by the socks5_server_userpass_auth in
* 'victim'. (Do nothing if 'victim' is NULL.)
*/
void socks5_server_userpass_auth_free(socks5_server_userpass_auth_t *victim);
/** Try to parse a socks5_server_userpass_auth from the buffer in
* 'input', using up to 'len_in' bytes from the input buffer. On
* success, return the number of bytes consumed and set *output to the
* newly allocated socks5_server_userpass_auth_t. On failure, return
* -2 if the input appears truncated, and -1 if the input is otherwise
* invalid.
*/
ssize_t socks5_server_userpass_auth_parse(socks5_server_userpass_auth_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_server_userpass_auth in 'obj'. On failure, return a negative
* value. Note that this value may be an overestimate, and can even be
* an underestimate for certain unencodeable objects.
*/
ssize_t socks5_server_userpass_auth_encoded_len(const socks5_server_userpass_auth_t *obj);
/** Try to encode the socks5_server_userpass_auth from 'input' into
* the buffer at 'output', using up to 'avail' bytes of the output
* buffer. On success, return the number of bytes used. On failure,
* return -2 if the buffer was not long enough, and -1 if the input
* was invalid.
*/
ssize_t socks5_server_userpass_auth_encode(uint8_t *output, size_t avail, const socks5_server_userpass_auth_t *input);
/** Check whether the internal state of the
* socks5_server_userpass_auth in 'obj' is consistent. Return NULL if
* it is, and a short message if it is not.
*/
const char *socks5_server_userpass_auth_check(const socks5_server_userpass_auth_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_server_userpass_auth_clear_errors(socks5_server_userpass_auth_t *obj);
/** Return the value of the version field of the
* socks5_server_userpass_auth_t in 'inp'
*/
uint8_t socks5_server_userpass_auth_get_version(const socks5_server_userpass_auth_t *inp);
/** Set the value of the version field of the
* socks5_server_userpass_auth_t in 'inp' to 'val'. Return 0 on
* success; return -1 and set the error code on 'inp' on failure.
*/
int socks5_server_userpass_auth_set_version(socks5_server_userpass_auth_t *inp, uint8_t val);
/** Return the value of the status field of the
* socks5_server_userpass_auth_t in 'inp'
*/
uint8_t socks5_server_userpass_auth_get_status(const socks5_server_userpass_auth_t *inp);
/** Set the value of the status field of the
* socks5_server_userpass_auth_t in 'inp' to 'val'. Return 0 on
* success; return -1 and set the error code on 'inp' on failure.
*/
int socks5_server_userpass_auth_set_status(socks5_server_userpass_auth_t *inp, uint8_t val);
/** Return a newly allocated socks5_client_request with all elements
* set to zero.
*/
socks5_client_request_t *socks5_client_request_new(void);
/** Release all storage held by the socks5_client_request in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks5_client_request_free(socks5_client_request_t *victim);
/** Try to parse a socks5_client_request from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks5_client_request_t. On failure, return -2 if the
* input appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks5_client_request_parse(socks5_client_request_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_client_request in 'obj'. On failure, return a negative
* value. Note that this value may be an overestimate, and can even be
* an underestimate for certain unencodeable objects.
*/
ssize_t socks5_client_request_encoded_len(const socks5_client_request_t *obj);
/** Try to encode the socks5_client_request from 'input' into the
* buffer at 'output', using up to 'avail' bytes of the output buffer.
* On success, return the number of bytes used. On failure, return -2
* if the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks5_client_request_encode(uint8_t *output, size_t avail, const socks5_client_request_t *input);
/** Check whether the internal state of the socks5_client_request in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks5_client_request_check(const socks5_client_request_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_client_request_clear_errors(socks5_client_request_t *obj);
/** Return the value of the version field of the
* socks5_client_request_t in 'inp'
*/
uint8_t socks5_client_request_get_version(const socks5_client_request_t *inp);
/** Set the value of the version field of the socks5_client_request_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_client_request_set_version(socks5_client_request_t *inp, uint8_t val);
/** Return the value of the command field of the
* socks5_client_request_t in 'inp'
*/
uint8_t socks5_client_request_get_command(const socks5_client_request_t *inp);
/** Set the value of the command field of the socks5_client_request_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_client_request_set_command(socks5_client_request_t *inp, uint8_t val);
/** Return the value of the reserved field of the
* socks5_client_request_t in 'inp'
*/
uint8_t socks5_client_request_get_reserved(const socks5_client_request_t *inp);
/** Set the value of the reserved field of the socks5_client_request_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_client_request_set_reserved(socks5_client_request_t *inp, uint8_t val);
/** Return the value of the atype field of the socks5_client_request_t
* in 'inp'
*/
uint8_t socks5_client_request_get_atype(const socks5_client_request_t *inp);
/** Set the value of the atype field of the socks5_client_request_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_client_request_set_atype(socks5_client_request_t *inp, uint8_t val);
/** Return the value of the dest_addr_ipv4 field of the
* socks5_client_request_t in 'inp'
*/
uint32_t socks5_client_request_get_dest_addr_ipv4(const socks5_client_request_t *inp);
/** Set the value of the dest_addr_ipv4 field of the
* socks5_client_request_t in 'inp' to 'val'. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_request_set_dest_addr_ipv4(socks5_client_request_t *inp, uint32_t val);
/** Return the (constant) length of the array holding the
* dest_addr_ipv6 field of the socks5_client_request_t in 'inp'.
*/
size_t socks5_client_request_getlen_dest_addr_ipv6(const socks5_client_request_t *inp);
/** Return the element at position 'idx' of the fixed array field
* dest_addr_ipv6 of the socks5_client_request_t in 'inp'.
*/
uint8_t socks5_client_request_get_dest_addr_ipv6(socks5_client_request_t *inp, size_t idx);
/** As socks5_client_request_get_dest_addr_ipv6, but take and return a
* const pointer
*/
uint8_t socks5_client_request_getconst_dest_addr_ipv6(const socks5_client_request_t *inp, size_t idx);
/** Change the element at position 'idx' of the fixed array field
* dest_addr_ipv6 of the socks5_client_request_t in 'inp', so that it
* will hold the value 'elt'.
*/
int socks5_client_request_set_dest_addr_ipv6(socks5_client_request_t *inp, size_t idx, uint8_t elt);
/** Return a pointer to the 16-element array field dest_addr_ipv6 of
* 'inp'.
*/
uint8_t * socks5_client_request_getarray_dest_addr_ipv6(socks5_client_request_t *inp);
/** As socks5_client_request_get_dest_addr_ipv6, but take and return a
* const pointer
*/
const uint8_t * socks5_client_request_getconstarray_dest_addr_ipv6(const socks5_client_request_t *inp);
/** Return the value of the dest_addr_domainname field of the
* socks5_client_request_t in 'inp'
*/
struct domainname_st * socks5_client_request_get_dest_addr_domainname(socks5_client_request_t *inp);
/** As socks5_client_request_get_dest_addr_domainname, but take and
* return a const pointer
*/
const struct domainname_st * socks5_client_request_getconst_dest_addr_domainname(const socks5_client_request_t *inp);
/** Set the value of the dest_addr_domainname field of the
* socks5_client_request_t in 'inp' to 'val'. Free the old value if
* any. Steals the referenceto 'val'.Return 0 on success; return -1
* and set the error code on 'inp' on failure.
*/
int socks5_client_request_set_dest_addr_domainname(socks5_client_request_t *inp, struct domainname_st *val);
/** As socks5_client_request_set_dest_addr_domainname, but does not
* free the previous value.
*/
int socks5_client_request_set0_dest_addr_domainname(socks5_client_request_t *inp, struct domainname_st *val);
/** Return the value of the dest_port field of the
* socks5_client_request_t in 'inp'
*/
uint16_t socks5_client_request_get_dest_port(const socks5_client_request_t *inp);
/** Set the value of the dest_port field of the
* socks5_client_request_t in 'inp' to 'val'. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_client_request_set_dest_port(socks5_client_request_t *inp, uint16_t val);
/** Return a newly allocated socks5_server_reply with all elements set
* to zero.
*/
socks5_server_reply_t *socks5_server_reply_new(void);
/** Release all storage held by the socks5_server_reply in 'victim'.
* (Do nothing if 'victim' is NULL.)
*/
void socks5_server_reply_free(socks5_server_reply_t *victim);
/** Try to parse a socks5_server_reply from the buffer in 'input',
* using up to 'len_in' bytes from the input buffer. On success,
* return the number of bytes consumed and set *output to the newly
* allocated socks5_server_reply_t. On failure, return -2 if the input
* appears truncated, and -1 if the input is otherwise invalid.
*/
ssize_t socks5_server_reply_parse(socks5_server_reply_t **output, const uint8_t *input, const size_t len_in);
/** Return the number of bytes we expect to need to encode the
* socks5_server_reply in 'obj'. On failure, return a negative value.
* Note that this value may be an overestimate, and can even be an
* underestimate for certain unencodeable objects.
*/
ssize_t socks5_server_reply_encoded_len(const socks5_server_reply_t *obj);
/** Try to encode the socks5_server_reply from 'input' into the buffer
* at 'output', using up to 'avail' bytes of the output buffer. On
* success, return the number of bytes used. On failure, return -2 if
* the buffer was not long enough, and -1 if the input was invalid.
*/
ssize_t socks5_server_reply_encode(uint8_t *output, size_t avail, const socks5_server_reply_t *input);
/** Check whether the internal state of the socks5_server_reply in
* 'obj' is consistent. Return NULL if it is, and a short message if
* it is not.
*/
const char *socks5_server_reply_check(const socks5_server_reply_t *obj);
/** Clear any errors that were set on the object 'obj' by its setter
* functions. Return true iff errors were cleared.
*/
int socks5_server_reply_clear_errors(socks5_server_reply_t *obj);
/** Return the value of the version field of the socks5_server_reply_t
* in 'inp'
*/
uint8_t socks5_server_reply_get_version(const socks5_server_reply_t *inp);
/** Set the value of the version field of the socks5_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_reply_set_version(socks5_server_reply_t *inp, uint8_t val);
/** Return the value of the reply field of the socks5_server_reply_t
* in 'inp'
*/
uint8_t socks5_server_reply_get_reply(const socks5_server_reply_t *inp);
/** Set the value of the reply field of the socks5_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_reply_set_reply(socks5_server_reply_t *inp, uint8_t val);
/** Return the value of the reserved field of the
* socks5_server_reply_t in 'inp'
*/
uint8_t socks5_server_reply_get_reserved(const socks5_server_reply_t *inp);
/** Set the value of the reserved field of the socks5_server_reply_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_reply_set_reserved(socks5_server_reply_t *inp, uint8_t val);
/** Return the value of the atype field of the socks5_server_reply_t
* in 'inp'
*/
uint8_t socks5_server_reply_get_atype(const socks5_server_reply_t *inp);
/** Set the value of the atype field of the socks5_server_reply_t in
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_reply_set_atype(socks5_server_reply_t *inp, uint8_t val);
/** Return the value of the bind_addr_ipv4 field of the
* socks5_server_reply_t in 'inp'
*/
uint32_t socks5_server_reply_get_bind_addr_ipv4(const socks5_server_reply_t *inp);
/** Set the value of the bind_addr_ipv4 field of the
* socks5_server_reply_t in 'inp' to 'val'. Return 0 on success;
* return -1 and set the error code on 'inp' on failure.
*/
int socks5_server_reply_set_bind_addr_ipv4(socks5_server_reply_t *inp, uint32_t val);
/** Return the (constant) length of the array holding the
* bind_addr_ipv6 field of the socks5_server_reply_t in 'inp'.
*/
size_t socks5_server_reply_getlen_bind_addr_ipv6(const socks5_server_reply_t *inp);
/** Return the element at position 'idx' of the fixed array field
* bind_addr_ipv6 of the socks5_server_reply_t in 'inp'.
*/
uint8_t socks5_server_reply_get_bind_addr_ipv6(socks5_server_reply_t *inp, size_t idx);
/** As socks5_server_reply_get_bind_addr_ipv6, but take and return a
* const pointer
*/
uint8_t socks5_server_reply_getconst_bind_addr_ipv6(const socks5_server_reply_t *inp, size_t idx);
/** Change the element at position 'idx' of the fixed array field
* bind_addr_ipv6 of the socks5_server_reply_t in 'inp', so that it
* will hold the value 'elt'.
*/
int socks5_server_reply_set_bind_addr_ipv6(socks5_server_reply_t *inp, size_t idx, uint8_t elt);
/** Return a pointer to the 16-element array field bind_addr_ipv6 of
* 'inp'.
*/
uint8_t * socks5_server_reply_getarray_bind_addr_ipv6(socks5_server_reply_t *inp);
/** As socks5_server_reply_get_bind_addr_ipv6, but take and return a
* const pointer
*/
const uint8_t * socks5_server_reply_getconstarray_bind_addr_ipv6(const socks5_server_reply_t *inp);
/** Return the value of the bind_addr_domainname field of the
* socks5_server_reply_t in 'inp'
*/
struct domainname_st * socks5_server_reply_get_bind_addr_domainname(socks5_server_reply_t *inp);
/** As socks5_server_reply_get_bind_addr_domainname, but take and
* return a const pointer
*/
const struct domainname_st * socks5_server_reply_getconst_bind_addr_domainname(const socks5_server_reply_t *inp);
/** Set the value of the bind_addr_domainname field of the
* socks5_server_reply_t in 'inp' to 'val'. Free the old value if any.
* Steals the referenceto 'val'.Return 0 on success; return -1 and set
* the error code on 'inp' on failure.
*/
int socks5_server_reply_set_bind_addr_domainname(socks5_server_reply_t *inp, struct domainname_st *val);
/** As socks5_server_reply_set_bind_addr_domainname, but does not free
* the previous value.
*/
int socks5_server_reply_set0_bind_addr_domainname(socks5_server_reply_t *inp, struct domainname_st *val);
/** Return the value of the bind_port field of the
* socks5_server_reply_t in 'inp'
*/
uint16_t socks5_server_reply_get_bind_port(const socks5_server_reply_t *inp);
/** Set the value of the bind_port field of the socks5_server_reply_t
* in 'inp' to 'val'. Return 0 on success; return -1 and set the error
* code on 'inp' on failure.
*/
int socks5_server_reply_set_bind_port(socks5_server_reply_t *inp, uint16_t val);
#endif

View File

@ -0,0 +1,94 @@
// Example: here's a quickie implementation of the messages in the
// socks5 protocol.
struct socks5_client_version {
u8 version IN [5];
u8 n_methods;
u8 methods[n_methods];
}
struct socks5_server_method {
u8 version IN [5];
u8 method;
}
const CMD_CONNECT = 1;
const CMD_BIND = 2;
const CMD_UDP_ASSOCIATE = 3;
// This is a tor extension
const CMD_RESOLVE = 0xF0;
const CMD_RESOLVE_PTR = 0xF1;
const ATYPE_IPV4 = 1;
const ATYPE_IPV6 = 4;
const ATYPE_DOMAINNAME = 3;
struct domainname {
u8 len;
char name[len];
}
struct socks5_client_request {
u8 version IN [5];
u8 command IN [CMD_CONNECT, CMD_BIND, CMD_UDP_ASSOCIATE, CMD_RESOLVE, CMD_RESOLVE_PTR];
u8 reserved IN [0];
u8 atype;
union dest_addr[atype] {
ATYPE_IPV4: u32 ipv4;
ATYPE_IPV6: u8 ipv6[16];
ATYPE_DOMAINNAME: struct domainname domainname;
default: fail;
};
u16 dest_port;
}
struct socks5_server_reply {
u8 version IN [5];
u8 reply;
u8 reserved IN [0];
u8 atype;
union bind_addr[atype] {
ATYPE_IPV4: u32 ipv4;
ATYPE_IPV6: u8 ipv6[16];
ATYPE_DOMAINNAME: struct domainname domainname;
default: fail;
};
u16 bind_port;
}
struct socks5_client_userpass_auth {
u8 version IN [1];
u8 username_len;
char username[username_len];
u8 passwd_len;
char passwd[passwd_len];
}
struct socks5_server_userpass_auth {
u8 version IN [1];
u8 status;
}
// Oh why not. Here's socks4 and socks4a.
struct socks4_client_request {
u8 version IN [4];
u8 command IN [CMD_CONNECT,CMD_BIND,CMD_RESOLVE,CMD_RESOLVE_PTR];
u16 port;
u32 addr;
nulterm username;
union socks4a_addr[addr] {
1..255:
nulterm hostname;
default:
;
};
}
struct socks4_server_reply {
u8 version IN [4];
u8 status;
u16 port;
u32 addr;
}