Skip to content

Commit

Permalink
Merge pull request #370 from bdodge/bdd/pdu-passthrough
Browse files Browse the repository at this point in the history
Bdd/pdu passthrough
  • Loading branch information
sahlberg committed Oct 1, 2024
2 parents ba342cb + 4f57f37 commit bb4977a
Show file tree
Hide file tree
Showing 32 changed files with 1,718 additions and 492 deletions.
10 changes: 7 additions & 3 deletions examples/smb2-server-sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,10 @@ static int logoff_handler(struct smb2_server *srvr, struct smb2_context *smb2)

static int tree_connect_handler(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_tree_connect_request *req,
struct smb2_tree_connect_reply *rep,
uint32_t *tree_id)
struct smb2_tree_connect_reply *rep)
{
rep->share_type = SMB2_SHARE_TYPE_DISK;
rep->maximal_access = 0x101f01ff;
*tree_id = 0x50625678;

if (req->path && req->path_length) {
int ei = (req->path_length / 2) - 4;
Expand Down Expand Up @@ -414,6 +412,7 @@ static int query_info_handler(struct smb2_server *srvr, struct smb2_context *smb
}

struct smb2_server_request_handlers test_handlers = {
NULL,
authorize_handler,
session_handler,
logoff_handler,
Expand All @@ -429,7 +428,9 @@ struct smb2_server_request_handlers test_handlers = {
cancel_handler,
echo_handler,
query_directory_handler,
NULL,
query_info_handler,
NULL
};

struct smb2_server server;
Expand Down Expand Up @@ -474,6 +475,9 @@ int main(int argc, char **argv)
memset(&server, 0, sizeof(server));
server.handlers = &test_handlers;

server.signing_enabled = 1;
server.allow_anonymous = 1;

server.port = strtoul(argv[1], NULL, 0);

err = smb2_serve_port(&server, 1, on_new_client, (void *)&smb2);
Expand Down
32 changes: 31 additions & 1 deletion include/libsmb2-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ enum smb2_sec {
SMB2_SEC_KRB5,
};

/* current tree id stack, note: index 0 in the stack is not used
*/
#define SMB2_MAX_TREE_NESTING 32
#define smb2_tree_id(smb2) (((smb2)->tree_id_cur >= 0)?smb2->tree_id[(smb2)->tree_id_cur]:0xdeadbeef)

#define MAX_CREDITS 1024
#define SMB2_SALT_SIZE 32

Expand Down Expand Up @@ -152,7 +157,9 @@ struct smb2_context {

char client_guid[16];

uint32_t tree_id;
uint32_t tree_id[SMB2_MAX_TREE_NESTING];
int tree_id_top;
int tree_id_cur;
uint64_t message_id;
uint64_t session_id;
uint8_t *session_key;
Expand Down Expand Up @@ -202,6 +209,18 @@ struct smb2_context {
* (if this context is a server)
*/
struct smb2_pdu *next_pdu;

/* flag indicated command packers/unpackers can pass "extra"
* content without trying to decode or encode it. this is
* useful for proxies and applies only to the commands with
* complex data: query-info, query-directory, ioctl, and
* create (contexts). the command fixed part is always
* de/en-coded regardless of this setting
*/
int passthrough;

/* last file_id in a create-reply, for "related requests" */
smb2_file_id last_file_id;

/* Server capabilities */
uint8_t supports_multi_credit;
Expand Down Expand Up @@ -288,6 +307,9 @@ struct smb2_iovec *smb2_add_iovector(struct smb2_context *smb2,

int smb2_pad_to_64bit(struct smb2_context *smb2, struct smb2_io_vectors *v);

int smb2_connect_tree_id(struct smb2_context *smb2, uint32_t tree_id);
int smb2_disconnect_tree_id(struct smb2_context *smb2, uint32_t tree_id);

struct smb2_pdu *smb2_allocate_pdu(struct smb2_context *smb2,
enum smb2_command command,
smb2_command_cb cb, void *cb_data);
Expand Down Expand Up @@ -357,6 +379,12 @@ int smb2_process_query_directory_request_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_query_directory_request_variable(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_change_notify_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_change_notify_variable(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_change_notify_request_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_query_info_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_query_info_variable(struct smb2_context *smb2,
Expand Down Expand Up @@ -399,6 +427,8 @@ int smb2_process_flush_request_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_read_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_read_variable(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_read_request_fixed(struct smb2_context *smb2,
struct smb2_pdu *pdu);
int smb2_process_read_request_variable(struct smb2_context *smb2,
Expand Down
33 changes: 27 additions & 6 deletions include/smb2/libsmb2-raw.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct smb2_pdu *smb2_cmd_tree_connect_async(struct smb2_context *smb2,

struct smb2_pdu *smb2_cmd_tree_connect_reply_async(struct smb2_context *smb2,
struct smb2_tree_connect_reply *rep,
uint32_t tree_id,
smb2_command_cb cb, void *cb_data);
/*
* Asynchronous SMB2 Tree Disconnect
Expand Down Expand Up @@ -244,12 +245,33 @@ struct smb2_pdu *smb2_cmd_query_directory_async(struct smb2_context *smb2,
smb2_command_cb cb, void *cb_data);

struct smb2_pdu *smb2_cmd_query_directory_reply_async(struct smb2_context *smb2,
uint8_t info_class,
uint8_t flags,
uint32_t room,
struct smb2_query_directory_request *req,
struct smb2_query_directory_reply *rep,
smb2_command_cb cb, void *cb_data);

/*
* Asynchronous SMB2 Change Notify
*
* Returns:
* pdu : If the call was initiated and a connection will be attempted.
* Result of the close will be reported through the callback function.
* NULL : If there was an error. The callback function will not be invoked.
*
* Callback parameters :
* status can be either of :
* 0 : Close was successful.
* Command_data is a struct smb2_close_reply.
*
* !0 : Status is NT status code. Command_data is NULL.
*/
struct smb2_pdu *smb2_cmd_change_notify_async(struct smb2_context *smb2,
struct smb2_change_notify_request *req,
smb2_command_cb cb, void *cb_data);

struct smb2_pdu *smb2_cmd_change_notify_reply_async(struct smb2_context *smb2,
struct smb2_change_notify_reply *rep,
smb2_command_cb cb, void *cb_data);

/*
* Asynchronous SMB2 Query Info
*
Expand All @@ -273,9 +295,7 @@ struct smb2_pdu *smb2_cmd_query_info_async(struct smb2_context *smb2,
smb2_command_cb cb, void *cb_data);

struct smb2_pdu *smb2_cmd_query_info_reply_async(struct smb2_context *smb2,
uint8_t info_type,
uint8_t file_info_class,
uint32_t room,
struct smb2_query_info_request *req,
struct smb2_query_info_reply *rep,
smb2_command_cb cb, void *cb_data);

Expand Down Expand Up @@ -366,6 +386,7 @@ struct smb2_pdu *smb2_cmd_echo_reply_async(struct smb2_context *smb2,
* command_data is always NULL.
*/
struct smb2_pdu *smb2_cmd_lock_async(struct smb2_context *smb2,
struct smb2_lock_request *req,
smb2_command_cb cb, void *cb_data);

struct smb2_pdu *smb2_cmd_lock_reply_async(struct smb2_context *smb2,
Expand Down
75 changes: 72 additions & 3 deletions include/smb2/libsmb2.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ typedef int t_socket;
*/
struct smb2_context *smb2_init_context(void);

/*
* Close an SMB2 context
*
* closes socket if open, and clears keys but leave
* context allocated. the context will be destroyed
* at a time later when it won't be in-use
*/
void smb2_close_context(struct smb2_context *smb2);

/*
* Destroy an smb2 context.
*
Expand All @@ -139,6 +148,12 @@ void smb2_destroy_context(struct smb2_context *smb2);
*/
struct smb2_context *smb2_active_contexts(void);

/*
* Determine of the context is currently active. This lets
* code know if the context was destroyed in a callback for example
*/
int smb2_context_active(struct smb2_context *smb2);

/*
* EVENT SYSTEM INTEGRATION
* ========================
Expand Down Expand Up @@ -242,6 +257,27 @@ int smb2_service_fd(struct smb2_context *smb2, t_socket fd, int revents);
*/
void smb2_set_timeout(struct smb2_context *smb2, int seconds);

/*
* Set passthrough-enable. Passthrough allows command packers
* and unpackers to keep the extra data on complex commands
* in its on-the-wire format without any interpretation. this
* is useful for proxy use cases where there might be no need
* to fully parse things like query-info replies or ioctl
* requests. If passthrough is not set, any command that
* that is processed that can't interpret the data will fail
* Most client use case will not need this
*
* Default is 0: no-passthrough
*/
void smb2_set_passthrough(struct smb2_context *smb2,
int passthrough);

/*
* Get the current passthrough setting
*/
void smb2_get_passthrough(struct smb2_context *smb2,
int *passthrough);

/*
* Set which version of SMB to negotiate.
* Default is to let the server pick the version.
Expand Down Expand Up @@ -470,6 +506,28 @@ int smb2_disconnect_share_async(struct smb2_context *smb2,
*/
int smb2_disconnect_share(struct smb2_context *smb2);

/*
* Select a tree id that was previously connected. Sets the tree_id
* in the context to be used for subsequent requests
*
* Returns:
* 0 : OK
* -errno : tree wasn't connected
*/
int smb2_select_tree_id(struct smb2_context *smb2, uint32_t tree_id);

struct smb2_pdu;

/*
* Get/Set the tree id of a pdu
*
* Returns:
* 0 : OK
* -errno : tree wasn't connected | no pdu | no context
*/
int smb2_get_tree_id_for_pdu(struct smb2_context *smb2, struct smb2_pdu *pdu, uint32_t *tree_id);
int smb2_set_tree_id_for_pdu(struct smb2_context *smb2, struct smb2_pdu *pdu, uint32_t tree_id);

/*
* This function returns a description of the last encountered error.
*/
Expand Down Expand Up @@ -507,7 +565,6 @@ int nterror_to_errno(uint32_t status);
struct smb2_url *smb2_parse_url(struct smb2_context *smb2, const char *url);
void smb2_destroy_url(struct smb2_url *url);

struct smb2_pdu;
/*
* The functions are used when creating compound low level commands.
* The general pattern for compound chains is
Expand All @@ -528,6 +585,7 @@ void smb2_add_compound_pdu(struct smb2_context *smb2,
struct smb2_pdu *pdu, struct smb2_pdu *next_pdu);
void smb2_free_pdu(struct smb2_context *smb2, struct smb2_pdu *pdu);
void smb2_queue_pdu(struct smb2_context *smb2, struct smb2_pdu *pdu);
int smb2_pdu_is_compound(struct smb2_context *smb2);

/*
* OPENDIR
Expand Down Expand Up @@ -1128,6 +1186,7 @@ const char *smb2_utf16_to_utf8(const uint16_t *str, size_t len);
struct smb2_server;

struct smb2_server_request_handlers {
int (*destruction_event)(struct smb2_server *srvr, struct smb2_context *smb2);
int (*authorize_user)(struct smb2_server *srvr, struct smb2_context *smb2,
const char *user,
const char *domain,
Expand All @@ -1136,8 +1195,7 @@ struct smb2_server_request_handlers {
int (*logoff_cmd)(struct smb2_server *srvr, struct smb2_context *smb2);
int (*tree_connect_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_tree_connect_request *req,
struct smb2_tree_connect_reply *rep,
uint32_t *tree_id);
struct smb2_tree_connect_reply *rep);
int (*tree_disconnect_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
const uint32_t tree_id);
int (*create_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
Expand All @@ -1164,9 +1222,17 @@ struct smb2_server_request_handlers {
int (*query_directory_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_query_directory_request *req,
struct smb2_query_directory_reply *rep);
int (*change_notify_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_change_notify_request *req);
int (*query_info_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_query_info_request *req,
struct smb2_query_info_reply *rep);
int (*set_info_cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_set_info_request *req);
/*
int (*oplock_break cmd)(struct smb2_server *srvr, struct smb2_context *smb2,
struct smb2_oplock_break_request *req);
*/
};

struct smb2_server {
Expand All @@ -1175,10 +1241,13 @@ struct smb2_server {
char domain[128];
int fd;
uint16_t port;
uint64_t session_counter;
struct smb2_server_request_handlers *handlers;
uint32_t max_transact_size;
uint32_t max_read_size;
uint32_t max_write_size;
int signing_enabled;
int allow_anonymous;
/* saved from negotiate to be used in validate negotiate info */
uint32_t capabilities;
uint32_t security_mode;
Expand Down
Loading

0 comments on commit bb4977a

Please sign in to comment.