Changeset 745 for trunk/server/source4/torture/ntp
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/torture/ntp/ntp_signd.c
r414 r745 21 21 22 22 #include "includes.h" 23 #include "torture/torture.h"24 23 #include "torture/smbtorture.h" 25 24 #include <tevent.h> 26 #include "lib/socket/socket.h"27 25 #include "lib/stream/packet.h" 28 #include " auth/credentials/credentials.h"29 #include " torture/rpc/rpc.h"30 #include "torture/rpc/ netlogon.h"26 #include "lib/tsocket/tsocket.h" 27 #include "libcli/util/tstream.h" 28 #include "torture/rpc/torture_rpc.h" 31 29 #include "../lib/crypto/crypto.h" 32 30 #include "libcli/auth/libcli_auth.h" 33 31 #include "librpc/gen_ndr/ndr_netlogon_c.h" 34 #include "librpc/gen_ndr/ndr_netlogon.h"35 32 #include "librpc/gen_ndr/ndr_ntp_signd.h" 36 33 #include "param/param.h" 34 #include "system/network.h" 37 35 38 36 #define TEST_MACHINE_NAME "ntpsigndtest" 39 37 40 struct signd_client_socket { 41 struct socket_context *sock; 42 43 /* the fd event */ 44 struct tevent_fd *fde; 45 38 struct signd_client_state { 39 struct tsocket_address *local_address; 40 struct tsocket_address *remote_address; 41 42 struct tstream_context *tstream; 43 struct tevent_queue *send_queue; 44 45 uint8_t request_hdr[4]; 46 struct iovec request_iov[2]; 47 48 DATA_BLOB reply; 49 46 50 NTSTATUS status; 47 DATA_BLOB request, reply;48 49 struct packet_context *packet;50 51 size_t partial_read;52 51 }; 53 52 54 static NTSTATUS signd_client_full_packet(void *private_data, DATA_BLOB data)55 {56 struct signd_client_socket *signd_client = talloc_get_type(private_data, struct signd_client_socket);57 talloc_steal(signd_client, data.data);58 signd_client->reply = data;59 signd_client->reply.length -= 4;60 signd_client->reply.data += 4;61 return NT_STATUS_OK;62 }63 64 static void signd_client_error_handler(void *private_data, NTSTATUS status)65 {66 struct signd_client_socket *signd_client = talloc_get_type(private_data, struct signd_client_socket);67 signd_client->status = status;68 }69 70 53 /* 71 handle fd events on a signd_client_socket 72 */ 73 static void signd_client_socket_handler(struct tevent_context *ev, struct tevent_fd *fde, 74 uint16_t flags, void *private_data) 75 { 76 struct signd_client_socket *signd_client = talloc_get_type(private_data, struct signd_client_socket); 77 if (flags & TEVENT_FD_READ) { 78 packet_recv(signd_client->packet); 79 return; 80 } 81 if (flags & TEVENT_FD_WRITE) { 82 packet_queue_run(signd_client->packet); 83 return; 84 } 85 /* not reached */ 86 return; 87 } 88 89 /* A torture test to show that the unix domain socket protocol is 90 * operating correctly, and the signatures are as expected */ 91 92 static bool test_ntp_signd(struct torture_context *tctx, 54 * A torture test to show that the unix domain socket protocol is 55 * operating correctly, and the signatures are as expected 56 */ 57 static bool test_ntp_signd(struct torture_context *tctx, 93 58 struct dcerpc_pipe *p, 94 59 struct cli_credentials *credentials) … … 97 62 TALLOC_CTX *mem_ctx = talloc_new(tctx); 98 63 99 NTSTATUS status;100 64 struct netr_ServerReqChallenge r; 101 65 struct netr_ServerAuthenticate3 a; … … 110 74 DATA_BLOB sign_req_blob; 111 75 112 struct signd_client_socket *signd_client; 113 char *signd_socket_address; 76 struct signd_client_state *signd_client; 77 struct tevent_req *req; 78 char *unix_address; 79 int sys_errno; 114 80 115 81 struct MD5Context ctx; 116 82 uint8_t sig[16]; 117 83 enum ndr_err_code ndr_err; 84 bool ok; 85 int rc; 118 86 119 87 machine_name = cli_credentials_get_workstation(credentials); … … 128 96 generate_random_buffer(credentials1.data, sizeof(credentials1.data)); 129 97 130 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r); 131 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge"); 98 torture_assert_ntstatus_ok(tctx, 99 dcerpc_netr_ServerReqChallenge_r(p->binding_handle, tctx, &r), 100 "ServerReqChallenge failed"); 101 torture_assert_ntstatus_ok(tctx, r.out.result, 102 "ServerReqChallenge failed"); 132 103 133 104 a.in.server_name = NULL; … … 151 122 torture_comment(tctx, "Testing ServerAuthenticate3\n"); 152 123 153 status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a); 154 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3"); 155 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed"); 124 torture_assert_ntstatus_ok(tctx, 125 dcerpc_netr_ServerAuthenticate3_r(p->binding_handle, tctx, &a), 126 "ServerAuthenticate3 failed"); 127 torture_assert_ntstatus_ok(tctx, a.out.result, 128 "ServerAuthenticate3 failed"); 129 torture_assert(tctx, 130 netlogon_creds_client_check(creds, &credentials3), 131 "Credential chaining failed"); 156 132 157 133 sign_req.op = SIGN_TO_CLIENT; … … 160 136 sign_req.packet_to_sign = data_blob_string_const("I am a tea pot"); 161 137 162 ndr_err = ndr_push_struct_blob(&sign_req_blob, mem_ctx, NULL, &sign_req, (ndr_push_flags_fn_t)ndr_push_sign_request); 163 torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "Failed to push sign_req"); 164 165 signd_client = talloc(mem_ctx, struct signd_client_socket); 166 167 status = socket_create("unix", SOCKET_TYPE_STREAM, &signd_client->sock, 0); 168 169 signd_socket_address = talloc_asprintf(signd_client, "%s/socket", 170 lp_ntp_signd_socket_directory(tctx->lp_ctx)); 171 172 status = socket_connect_ev(signd_client->sock, NULL, 173 socket_address_from_strings(signd_client, 174 "unix", signd_socket_address, 0), 0, tctx->ev); 175 torture_assert_ntstatus_ok(tctx, status, "Failed to connect to signd!"); 176 177 /* Setup the FDE, start listening for read events 178 * from the start (otherwise we may miss a socket 179 * drop) and mark as AUTOCLOSE along with the fde */ 180 181 /* Ths is equivilant to EVENT_FD_READABLE(signd_client->fde) */ 182 signd_client->fde = tevent_add_fd(tctx->ev, signd_client->sock, 183 socket_get_fd(signd_client->sock), 184 TEVENT_FD_READ, 185 signd_client_socket_handler, signd_client); 186 /* its now the job of the event layer to close the socket */ 187 tevent_fd_set_close_fn(signd_client->fde, socket_tevent_fd_close_fn); 188 socket_set_flags(signd_client->sock, SOCKET_FLAG_NOCLOSE); 189 190 signd_client->status = NT_STATUS_OK; 191 signd_client->reply = data_blob(NULL, 0); 192 193 signd_client->packet = packet_init(signd_client); 194 if (signd_client->packet == NULL) { 195 talloc_free(signd_client); 196 return ENOMEM; 197 } 198 packet_set_private(signd_client->packet, signd_client); 199 packet_set_socket(signd_client->packet, signd_client->sock); 200 packet_set_callback(signd_client->packet, signd_client_full_packet); 201 packet_set_full_request(signd_client->packet, packet_full_request_u32); 202 packet_set_error_handler(signd_client->packet, signd_client_error_handler); 203 packet_set_event_context(signd_client->packet, tctx->ev); 204 packet_set_fde(signd_client->packet, signd_client->fde); 205 206 signd_client->request = data_blob_talloc(signd_client, NULL, sign_req_blob.length + 4); 207 RSIVAL(signd_client->request.data, 0, sign_req_blob.length); 208 memcpy(signd_client->request.data+4, sign_req_blob.data, sign_req_blob.length); 209 packet_send(signd_client->packet, signd_client->request); 210 211 while ((NT_STATUS_IS_OK(signd_client->status)) && !signd_client->reply.length) { 212 if (tevent_loop_once(tctx->ev) != 0) { 213 talloc_free(signd_client); 214 return EINVAL; 215 } 216 } 217 218 torture_assert_ntstatus_ok(tctx, signd_client->status, "Error reading signd_client reply packet"); 219 220 ndr_err = ndr_pull_struct_blob_all(&signd_client->reply, mem_ctx, 221 lp_iconv_convenience(tctx->lp_ctx), 138 ndr_err = ndr_push_struct_blob(&sign_req_blob, 139 mem_ctx, 140 &sign_req, 141 (ndr_push_flags_fn_t)ndr_push_sign_request); 142 torture_assert(tctx, 143 NDR_ERR_CODE_IS_SUCCESS(ndr_err), 144 "Failed to push sign_req"); 145 146 signd_client = talloc(mem_ctx, struct signd_client_state); 147 148 /* Create socket addresses */ 149 torture_comment(tctx, "Creating the socket addresses\n"); 150 rc = tsocket_address_unix_from_path(signd_client, "", 151 &signd_client->local_address); 152 torture_assert(tctx, rc == 0, 153 "Failed to create local address from unix path."); 154 155 unix_address = talloc_asprintf(signd_client, 156 "%s/socket", 157 lpcfg_ntp_signd_socket_directory(tctx->lp_ctx)); 158 rc = tsocket_address_unix_from_path(mem_ctx, 159 unix_address, 160 &signd_client->remote_address); 161 torture_assert(tctx, rc == 0, 162 "Failed to create remote address from unix path."); 163 164 /* Connect to the unix socket */ 165 torture_comment(tctx, "Connecting to the unix socket\n"); 166 req = tstream_unix_connect_send(signd_client, 167 tctx->ev, 168 signd_client->local_address, 169 signd_client->remote_address); 170 torture_assert(tctx, req != NULL, 171 "Failed to create a tstream unix connect request."); 172 173 ok = tevent_req_poll(req, tctx->ev); 174 torture_assert(tctx, ok == true, 175 "Failed to poll for tstream_unix_connect_send."); 176 177 rc = tstream_unix_connect_recv(req, 178 &sys_errno, 179 signd_client, 180 &signd_client->tstream); 181 TALLOC_FREE(req); 182 torture_assert(tctx, rc == 0, "Failed to connect to signd!"); 183 184 /* Allocate the send queue */ 185 signd_client->send_queue = tevent_queue_create(signd_client, 186 "signd_client_queue"); 187 torture_assert(tctx, signd_client->send_queue != NULL, 188 "Failed to create send queue!"); 189 190 /* 191 * Create the request buffer. 192 * First add the length of the request buffer 193 */ 194 RSIVAL(signd_client->request_hdr, 0, sign_req_blob.length); 195 signd_client->request_iov[0].iov_base = (char *) signd_client->request_hdr; 196 signd_client->request_iov[0].iov_len = 4; 197 198 signd_client->request_iov[1].iov_base = (char *) sign_req_blob.data; 199 signd_client->request_iov[1].iov_len = sign_req_blob.length; 200 201 /* Fire the request buffer */ 202 torture_comment(tctx, "Sending the request\n"); 203 req = tstream_writev_queue_send(signd_client, 204 tctx->ev, 205 signd_client->tstream, 206 signd_client->send_queue, 207 signd_client->request_iov, 2); 208 torture_assert(tctx, req != NULL, 209 "Failed to send the signd request."); 210 211 ok = tevent_req_poll(req, tctx->ev); 212 torture_assert(tctx, ok == true, 213 "Failed to poll for tstream_writev_queue_send."); 214 215 rc = tstream_writev_queue_recv(req, &sys_errno); 216 TALLOC_FREE(req); 217 torture_assert(tctx, rc > 0, "Failed to send data"); 218 219 /* Wait for a reply */ 220 torture_comment(tctx, "Waiting for the reply\n"); 221 req = tstream_read_pdu_blob_send(signd_client, 222 tctx->ev, 223 signd_client->tstream, 224 4, /*initial_read_size */ 225 packet_full_request_u32, 226 NULL); 227 torture_assert(tctx, req != NULL, 228 "Failed to setup a read for pdu_blob."); 229 230 ok = tevent_req_poll(req, tctx->ev); 231 torture_assert(tctx, ok == true, 232 "Failed to poll for tstream_read_pdu_blob_send."); 233 234 signd_client->status = tstream_read_pdu_blob_recv(req, 235 signd_client, 236 &signd_client->reply); 237 torture_assert_ntstatus_ok(tctx, signd_client->status, 238 "Error reading signd_client reply packet"); 239 240 /* Skip length header */ 241 signd_client->reply.data += 4; 242 signd_client->reply.length -= 4; 243 244 /* Check if the reply buffer is valid */ 245 torture_comment(tctx, "Validating the reply buffer\n"); 246 ndr_err = ndr_pull_struct_blob_all(&signd_client->reply, 247 mem_ctx, 222 248 &signed_reply, 223 249 (ndr_pull_flags_fn_t)ndr_pull_signed_reply); 224 torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), ndr_map_error2string(ndr_err)); 225 226 torture_assert_u64_equal(tctx, signed_reply.version, 227 NTP_SIGND_PROTOCOL_VERSION_0, "Invalid Version"); 228 torture_assert_u64_equal(tctx, signed_reply.packet_id, 250 torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 251 ndr_map_error2string(ndr_err)); 252 253 torture_assert_u64_equal(tctx, signed_reply.version, 254 NTP_SIGND_PROTOCOL_VERSION_0, 255 "Invalid Version"); 256 torture_assert_u64_equal(tctx, signed_reply.packet_id, 229 257 sign_req.packet_id, "Invalid Packet ID"); 230 torture_assert_u64_equal(tctx, signed_reply.op, 231 SIGNING_SUCCESS, "Should have replied with signing success"); 232 torture_assert_u64_equal(tctx, signed_reply.signed_packet.length, 233 sign_req.packet_to_sign.length + 20, "Invalid reply length from signd"); 234 torture_assert_u64_equal(tctx, rid, 235 IVAL(signed_reply.signed_packet.data, sign_req.packet_to_sign.length), 258 torture_assert_u64_equal(tctx, signed_reply.op, 259 SIGNING_SUCCESS, 260 "Should have replied with signing success"); 261 torture_assert_u64_equal(tctx, signed_reply.signed_packet.length, 262 sign_req.packet_to_sign.length + 20, 263 "Invalid reply length from signd"); 264 torture_assert_u64_equal(tctx, rid, 265 IVAL(signed_reply.signed_packet.data, 266 sign_req.packet_to_sign.length), 236 267 "Incorrect RID in reply"); 237 268 238 269 /* Check computed signature */ 239 240 270 MD5Init(&ctx); 241 271 MD5Update(&ctx, pwhash->hash, sizeof(pwhash->hash)); 242 MD5Update(&ctx, sign_req.packet_to_sign.data, sign_req.packet_to_sign.length); 272 MD5Update(&ctx, sign_req.packet_to_sign.data, 273 sign_req.packet_to_sign.length); 243 274 MD5Final(sig, &ctx); 244 275 245 torture_assert_mem_equal(tctx, &signed_reply.signed_packet.data[sign_req.packet_to_sign.length + 4], 276 torture_assert_mem_equal(tctx, 277 &signed_reply.signed_packet.data[sign_req.packet_to_sign.length + 4], 246 278 sig, 16, "Signature on reply was incorrect!"); 247 279 248 280 talloc_free(mem_ctx); 249 281 250 282 return true; 251 283 } … … 253 285 NTSTATUS torture_ntp_init(void) 254 286 { 255 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), " NTP");287 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "ntp"); 256 288 struct torture_rpc_tcase *tcase; 257 289 258 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "SIGND",259 290 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, 291 "signd", &ndr_table_netlogon, TEST_MACHINE_NAME); 260 292 261 293 torture_rpc_tcase_add_test_creds(tcase, "ntp_signd", test_ntp_signd);
Note:
See TracChangeset
for help on using the changeset viewer.