Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/torture/ntp/ntp_signd.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "torture/torture.h"
    2423#include "torture/smbtorture.h"
    2524#include <tevent.h>
    26 #include "lib/socket/socket.h"
    2725#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"
    3129#include "../lib/crypto/crypto.h"
    3230#include "libcli/auth/libcli_auth.h"
    3331#include "librpc/gen_ndr/ndr_netlogon_c.h"
    34 #include "librpc/gen_ndr/ndr_netlogon.h"
    3532#include "librpc/gen_ndr/ndr_ntp_signd.h"
    3633#include "param/param.h"
     34#include "system/network.h"
    3735
    3836#define TEST_MACHINE_NAME "ntpsigndtest"
    3937
    40 struct signd_client_socket {
    41         struct socket_context *sock;
    42        
    43         /* the fd event */
    44         struct tevent_fd *fde;
    45        
     38struct 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
    4650        NTSTATUS status;
    47         DATA_BLOB request, reply;
    48        
    49         struct packet_context *packet;
    50                
    51         size_t partial_read;
    5251};
    5352
    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 
    7053/*
    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 */
     57static bool test_ntp_signd(struct torture_context *tctx,
    9358                           struct dcerpc_pipe *p,
    9459                           struct cli_credentials *credentials)
     
    9762        TALLOC_CTX *mem_ctx = talloc_new(tctx);
    9863
    99         NTSTATUS status;
    10064        struct netr_ServerReqChallenge r;
    10165        struct netr_ServerAuthenticate3 a;
     
    11074        DATA_BLOB sign_req_blob;
    11175
    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;
    11480
    11581        struct MD5Context ctx;
    11682        uint8_t sig[16];
    11783        enum ndr_err_code ndr_err;
     84        bool ok;
     85        int rc;
    11886
    11987        machine_name = cli_credentials_get_workstation(credentials);
     
    12896        generate_random_buffer(credentials1.data, sizeof(credentials1.data));
    12997
    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");
    132103
    133104        a.in.server_name = NULL;
     
    151122        torture_comment(tctx, "Testing ServerAuthenticate3\n");
    152123
    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");
    156132
    157133        sign_req.op = SIGN_TO_CLIENT;
     
    160136        sign_req.packet_to_sign = data_blob_string_const("I am a tea pot");
    161137       
    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,
    222248                                           &signed_reply,
    223249                                           (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,
    229257                                 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),
    236267                                 "Incorrect RID in reply");
    237268
    238269        /* Check computed signature */
    239 
    240270        MD5Init(&ctx);
    241271        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);
    243274        MD5Final(sig, &ctx);
    244275
    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],
    246278                                 sig, 16, "Signature on reply was incorrect!");
    247        
     279
    248280        talloc_free(mem_ctx);
    249                
     281
    250282        return true;
    251283}
     
    253285NTSTATUS torture_ntp_init(void)
    254286{
    255         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "NTP");
     287        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "ntp");
    256288        struct torture_rpc_tcase *tcase;
    257289
    258         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "SIGND",
    259                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME);
     290        tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite,
     291                                  "signd", &ndr_table_netlogon, TEST_MACHINE_NAME);
    260292
    261293        torture_rpc_tcase_add_test_creds(tcase, "ntp_signd", test_ntp_signd);
Note: See TracChangeset for help on using the changeset viewer.