diff options
-rw-r--r-- | source4/include/structs.h | 1 | ||||
-rw-r--r-- | source4/libcli/smb2/session.c | 70 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2.h | 1 | ||||
-rw-r--r-- | source4/torture/smb2/connect.c | 54 |
4 files changed, 120 insertions, 6 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h index b6bc1cc742..eb04436ea3 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -337,3 +337,4 @@ struct _krb5_krb_auth_data; struct smb2_request; struct smb2_transport; struct smb2_negprot; +struct smb2_session_setup; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 23fed70e17..2f9a979fea 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* initialise a smb2_session structure @@ -31,6 +32,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, TALLOC_CTX *parent_ctx, BOOL primary) { struct smb2_session *session; + NTSTATUS status; session = talloc_zero(parent_ctx, struct smb2_session); if (!session) { @@ -42,6 +44,74 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, session->transport = talloc_reference(session, transport); } + /* prepare a gensec context for later use */ + status = gensec_client_start(session, &session->gensec, + session->transport->socket->event.ctx); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(session); + return NULL; + } + return session; } +/* + send a session setup request +*/ +struct smb2_request *smb2_session_setup_send(struct smb2_session *session, + struct smb2_session_setup *io) +{ + struct smb2_request *req; + + req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, + 0x10 + io->in.secblob.length); + if (req == NULL) return NULL; + + SIVAL(req->out.body, 0x00, io->in.unknown1); + SIVAL(req->out.body, 0x04, io->in.unknown2); + SIVAL(req->out.body, 0x08, io->in.unknown3); + SSVAL(req->out.body, 0x0C, io->in.unknown4); + SSVAL(req->out.body, 0x0E, io->in.secblob.length); + memcpy(req->out.body+0x10, io->in.secblob.data, io->in.secblob.length); + + smb2_transport_send(req); + + return req; +} + + +/* + recv a session setup reply +*/ +NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, + struct smb2_session_setup *io) +{ + uint16_t blobsize; + + if (!smb2_request_receive(req) || + smb2_request_is_error(req)) { + return smb2_request_destroy(req); + } + + if (req->in.body_size < 0x08) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + io->out.unknown1 = IVAL(req->in.body, 0x00); + io->out.unknown2 = SVAL(req->in.body, 0x04); + blobsize = SVAL(req->in.body, 0x06); + io->out.secblob = smb2_pull_blob(req, req->in.body+0x08, blobsize); + talloc_steal(mem_ctx, io->out.secblob.data); + + return smb2_request_destroy(req); +} + +/* + sync session setup request +*/ +NTSTATUS smb2_session_setup(struct smb2_session *session, + TALLOC_CTX *mem_ctx, struct smb2_session_setup *io) +{ + struct smb2_request *req = smb2_session_setup_send(session, io); + return smb2_session_setup_recv(req, mem_ctx, io); +} diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 79b983206a..2262040b51 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -56,6 +56,7 @@ struct smb2_transport { */ struct smb2_session { struct smb2_transport *transport; + struct gensec_security *gensec; }; struct smb2_request_buffer { diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c index 7237bb704a..43029dd04d 100644 --- a/source4/torture/smb2/connect.c +++ b/source4/torture/smb2/connect.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_security.h" #include "lib/cmdline/popt_common.h" #include "lib/events/events.h" +#include "auth/gensec/gensec.h" #define BASEDIR "\\testsmb2" @@ -78,7 +79,6 @@ static struct smb2_transport *torture_smb2_negprot(TALLOC_CTX *mem_ctx, const ch return transport; } -#if 0 /* send a session setup */ @@ -86,11 +86,56 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor struct cli_credentials *credentials) { struct smb2_session *session; + struct smb2_session_setup io; NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(transport); - session = smb2_session_init(transport); + ZERO_STRUCT(io); + io.in.unknown1 = 0x11; + io.in.unknown2 = 0xF; + io.in.unknown3 = 0x00; + io.in.unknown4 = 0x50; + + session = smb2_session_init(transport, transport, True); + + status = gensec_set_credentials(session->gensec, credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", + nt_errstr(status))); + return NULL; + } + + status = gensec_set_target_hostname(session->gensec, transport->socket->hostname); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + return NULL; + } + + status = gensec_set_target_service(session->gensec, "cifs"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + nt_errstr(status))); + return NULL; + } + + status = gensec_start_mech_by_oid(session->gensec, GENSEC_OID_SPNEGO); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client - %s\n", + nt_errstr(status))); + return NULL; + } + + status = gensec_update(session->gensec, tmp_ctx, + session->transport->negotiate.secblob, + &io.in.secblob); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed initial gensec_update : %s\n", nt_errstr(status))); + return NULL; + } - status = smb2_session_setup(session, credentials) + status = smb2_session_setup(session, tmp_ctx, &io); if (!NT_STATUS_IS_OK(status)) { printf("session setup failed - %s\n", nt_errstr(status)); return NULL; @@ -98,7 +143,6 @@ static struct smb2_session *torture_smb2_session(struct smb2_transport *transpor return session; } -#endif /* basic testing of SMB2 connection calls @@ -112,9 +156,7 @@ BOOL torture_smb2_connect(void) struct cli_credentials *credentials = cmdline_credentials; transport = torture_smb2_negprot(mem_ctx, host); -#if 0 session = torture_smb2_session(transport, credentials); -#endif talloc_free(mem_ctx); |