summaryrefslogtreecommitdiff
path: root/source4/torture/rpc/lsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/rpc/lsa.c')
-rw-r--r--source4/torture/rpc/lsa.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index 135e50fb5a..d30e6a535f 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -496,6 +496,153 @@ static BOOL test_CreateSecret(struct dcerpc_pipe *p,
return ret;
}
+
+static BOOL test_lsakey_puzzle(struct dcerpc_pipe *p_smb,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle_smb)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p_tcp;
+ struct policy_handle handle_tcp, sec_handle, sec_handle2;
+ struct lsa_CreateSecret cr;
+ struct lsa_OpenSecret or;
+ struct lsa_SetSecret sr;
+ struct lsa_QuerySecret qr;
+ char *secname;
+ const char *secret1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ DATA_BLOB session_key, blob1, blob2;
+ DATA_BLOB enc_key;
+ NTTIME old_mtime, new_mtime;
+ struct lsa_DATA_BUF buf1;
+ struct lsa_DATA_BUF_PTR bufp1;
+
+ status = torture_rpc_connection_transport(&p_tcp,
+ DCERPC_LSARPC_NAME,
+ DCERPC_LSARPC_UUID,
+ DCERPC_LSARPC_VERSION,
+ NCACN_IP_TCP);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ if (!test_OpenPolicy2(p_tcp, mem_ctx, &handle_tcp)) {
+ return False;
+ }
+
+ asprintf(&secname, "torturesecret-%u", (uint_t)random());
+
+ printf("calling CreateSecret on %s\n", secname);
+
+ init_lsa_Name(&cr.in.name, secname);
+
+ cr.in.handle = handle_smb;
+ cr.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ cr.out.sec_handle = &sec_handle;
+
+ status = dcerpc_lsa_CreateSecret(p_smb, mem_ctx, &cr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("CreateSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ status = dcerpc_fetch_session_key(p_smb, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ printf("SMB session key:\n");
+ dump_data(0, session_key.data, session_key.length);
+
+ enc_key = sess_encrypt_string(secret1, &session_key);
+
+ blob1 = data_blob_talloc(mem_ctx, enc_key.data, enc_key.length);
+ sess_crypt_blob(&blob1, &enc_key, &session_key, False);
+
+ printf("Plain-text:\n");
+ dump_data(0, blob1.data, blob1.length);
+
+ printf("SMB encrypted:\n");
+ dump_data(0, enc_key.data, enc_key.length);
+
+ sr.in.handle = &sec_handle;
+ sr.in.new_val = &buf1;
+ sr.in.old_val = NULL;
+ sr.in.new_val->data = enc_key.data;
+ sr.in.new_val->length = enc_key.length;
+ sr.in.new_val->size = enc_key.length;
+
+ printf("calling SetSecret\n");
+
+ status = dcerpc_lsa_SetSecret(p_smb, mem_ctx, &sr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ or.in.handle = &handle_tcp;
+ or.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ or.in.name = cr.in.name;
+ or.out.sec_handle = &sec_handle2;
+
+ printf("Calling OpenSecret\n");
+
+ status = dcerpc_lsa_OpenSecret(p_tcp, mem_ctx, &or);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("OpenSecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ ZERO_STRUCT(new_mtime);
+ ZERO_STRUCT(old_mtime);
+
+ /* fetch the secret back again */
+ qr.in.handle = &sec_handle2;
+ qr.in.new_val = &bufp1;
+ qr.in.new_mtime = &new_mtime;
+ qr.in.old_val = NULL;
+ qr.in.old_mtime = NULL;
+
+ bufp1.buf = NULL;
+
+ status = dcerpc_lsa_QuerySecret(p_tcp, mem_ctx, &qr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("QuerySecret failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ status = dcerpc_fetch_session_key(p_tcp, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ printf("TCP session key:\n");
+ dump_data(0, session_key.data, session_key.length);
+
+ blob1.data = qr.out.new_val->buf->data;
+ blob1.length = qr.out.new_val->buf->length;
+
+ printf("Encrypted blob:\n");
+ dump_data(0, blob1.data, blob1.length);
+
+ session_key.length = 16;
+ blob2 = data_blob_talloc(mem_ctx, blob1.data, blob1.length);
+
+ /* try a zero session key to decrypt. */
+ data_blob_clear(&session_key);
+ sess_crypt_blob(&blob2, &blob1, &session_key, False);
+ printf("Test-text:\n");
+ dump_data(0, blob2.data, blob2.length);
+
+ talloc_destroy(mem_ctx);
+ torture_rpc_close(p_smb);
+ torture_rpc_close(p_tcp);
+
+ return True;
+}
+
+
static BOOL test_EnumAccountRights(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
struct policy_handle *acct_handle,
@@ -893,6 +1040,11 @@ BOOL torture_rpc_lsa(int dummy)
ret = False;
}
+ if (!test_lsakey_puzzle(p, mem_ctx, &handle)) {
+ ret = False;
+ }
+ exit(1);
+
if (!test_many_LookupSids(p, mem_ctx, &handle)) {
ret = False;
}