⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpc_message.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
    buffers[3].pvBuffer = auth_value;    if (dir == SECURE_PACKET_SEND)    {        if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr))        {            sec_status = EncryptMessage(&Connection->ctx, 0, &message, 0 /* FIXME */);            if (sec_status != SEC_E_OK)            {                ERR("EncryptMessage failed with 0x%08x\n", sec_status);                return RPC_S_SEC_PKG_ERROR;            }        }        else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)        {            sec_status = MakeSignature(&Connection->ctx, 0, &message, 0 /* FIXME */);            if (sec_status != SEC_E_OK)            {                ERR("MakeSignature failed with 0x%08x\n", sec_status);                return RPC_S_SEC_PKG_ERROR;            }        }    }    else if (dir == SECURE_PACKET_RECEIVE)    {        if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr))        {            sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0);            if (sec_status != SEC_E_OK)            {                ERR("EncryptMessage failed with 0x%08x\n", sec_status);                return RPC_S_SEC_PKG_ERROR;            }        }        else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)        {            sec_status = VerifySignature(&Connection->ctx, &message, 0 /* FIXME */, NULL);            if (sec_status != SEC_E_OK)            {                ERR("VerifySignature failed with 0x%08x\n", sec_status);                return RPC_S_SEC_PKG_ERROR;            }        }    }    return RPC_S_OK;}         /*********************************************************************** *           RPCRT4_SendAuth (internal) *  * Transmit a packet with authorization data over connection in acceptable fragments. */static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,                                  void *Buffer, unsigned int BufferLength,                                  void *Auth, unsigned int AuthLength){  PUCHAR buffer_pos;  DWORD hdr_size;  LONG count;  unsigned char *pkt;  LONG alen;  RPC_STATUS status;  buffer_pos = Buffer;  /* The packet building functions save the packet header size, so we can use it. */  hdr_size = Header->common.frag_len;  if (AuthLength)    Header->common.auth_len = AuthLength;  else if (Connection->AuthInfo && packet_has_auth_verifier(Header))  {    if ((Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(Header))      Header->common.auth_len = Connection->encryption_auth_len;    else      Header->common.auth_len = Connection->signature_auth_len;  }  else    Header->common.auth_len = 0;  Header->common.flags |= RPC_FLG_FIRST;  Header->common.flags &= ~RPC_FLG_LAST;  alen = RPC_AUTH_VERIFIER_LEN(&Header->common);  while (!(Header->common.flags & RPC_FLG_LAST)) {    unsigned char auth_pad_len = Header->common.auth_len ? ROUND_UP_AMOUNT(BufferLength, AUTH_ALIGNMENT) : 0;    unsigned int pkt_size = BufferLength + hdr_size + alen + auth_pad_len;    /* decide if we need to split the packet into fragments */   if (pkt_size <= Connection->MaxTransmissionSize) {     Header->common.flags |= RPC_FLG_LAST;     Header->common.frag_len = pkt_size;    } else {      auth_pad_len = 0;      /* make sure packet payload will be a multiple of 16 */      Header->common.frag_len =        ((Connection->MaxTransmissionSize - hdr_size - alen) & ~(AUTH_ALIGNMENT-1)) +        hdr_size + alen;    }    pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len);    memcpy(pkt, Header, hdr_size);    /* fragment consisted of header only and is the last one */    if (hdr_size == Header->common.frag_len)      goto write;    memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - auth_pad_len - alen);    /* add the authorization info */    if (Connection->AuthInfo && packet_has_auth_verifier(Header))    {      RpcAuthVerifier *auth_hdr = (RpcAuthVerifier *)&pkt[Header->common.frag_len - alen];      auth_hdr->auth_type = Connection->AuthInfo->AuthnSvc;      auth_hdr->auth_level = Connection->AuthInfo->AuthnLevel;      auth_hdr->auth_pad_length = auth_pad_len;      auth_hdr->auth_reserved = 0;      /* a unique number... */      auth_hdr->auth_context_id = (unsigned long)Connection;      if (AuthLength)        memcpy(auth_hdr + 1, Auth, AuthLength);      else      {        status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_SEND,            (RpcPktHdr *)pkt, hdr_size,            pkt + hdr_size, Header->common.frag_len - hdr_size - alen,            auth_hdr,            (unsigned char *)(auth_hdr + 1), Header->common.auth_len);        if (status != RPC_S_OK)        {          HeapFree(GetProcessHeap(), 0, pkt);          return status;        }      }    }write:    count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len);    HeapFree(GetProcessHeap(), 0, pkt);    if (count<0) {      WARN("rpcrt4_conn_write failed (auth)\n");      return RPC_S_PROTOCOL_ERROR;    }    buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len;    BufferLength -= Header->common.frag_len - hdr_size - alen - auth_pad_len;    Header->common.flags &= ~RPC_FLG_FIRST;  }  return RPC_S_OK;}/*********************************************************************** *           RPCRT4_ClientAuthorize (internal) * * Authorize a client connection. A NULL in param signifies a new connection. */static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,                                         SecBuffer *out){  SECURITY_STATUS r;  SecBufferDesc out_desc;  SecBufferDesc inp_desc;  SecPkgContext_Sizes secctx_sizes;  BOOL continue_needed;  ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE |                      ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE;  if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)    context_req |= ISC_REQ_INTEGRITY;  else if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY)    context_req |= ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY;  out->BufferType = SECBUFFER_TOKEN;  out->cbBuffer = conn->AuthInfo->cbMaxToken;  out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer);  if (!out->pvBuffer) return ERROR_OUTOFMEMORY;  out_desc.ulVersion = 0;  out_desc.cBuffers = 1;  out_desc.pBuffers = out;  inp_desc.cBuffers = 1;  inp_desc.pBuffers = in;  inp_desc.ulVersion = 0;  r = InitializeSecurityContextA(&conn->AuthInfo->cred, in ? &conn->ctx : NULL,        NULL, context_req, 0, SECURITY_NETWORK_DREP,        in ? &inp_desc : NULL, 0, &conn->ctx, &out_desc, &conn->attr,        &conn->exp);  if (FAILED(r))  {      WARN("InitializeSecurityContext failed with error 0x%08x\n", r);      goto failed;  }  TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr);  continue_needed = ((r == SEC_I_CONTINUE_NEEDED) ||                     (r == SEC_I_COMPLETE_AND_CONTINUE));  if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE))  {      TRACE("complete needed\n");      r = CompleteAuthToken(&conn->ctx, &out_desc);      if (FAILED(r))      {          WARN("CompleteAuthToken failed with error 0x%08x\n", r);          goto failed;      }  }  TRACE("cbBuffer = %ld\n", out->cbBuffer);  if (!continue_needed)  {      r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes);      if (FAILED(r))      {          WARN("QueryContextAttributes failed with error 0x%08x\n", r);          goto failed;      }      conn->signature_auth_len = secctx_sizes.cbMaxSignature;      conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer;  }  return RPC_S_OK;failed:  HeapFree(GetProcessHeap(), 0, out->pvBuffer);  out->pvBuffer = NULL;  return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */}/*********************************************************************** *           RPCRT4_AuthorizeBinding (internal) */static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn,                                            BYTE *challenge, ULONG count){  SecBuffer inp, out;  RpcPktHdr *resp_hdr;  RPC_STATUS status;  TRACE("challenge %s, %d bytes\n", challenge, count);  inp.BufferType = SECBUFFER_TOKEN;  inp.pvBuffer = challenge;  inp.cbBuffer = count;  status = RPCRT4_ClientAuthorize(conn, &inp, &out);  if (status) return status;  resp_hdr = RPCRT4_BuildAuthHeader(NDR_LOCAL_DATA_REPRESENTATION);  if (!resp_hdr)    return E_OUTOFMEMORY;  status = RPCRT4_SendAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer);  HeapFree(GetProcessHeap(), 0, out.pvBuffer);  RPCRT4_FreeHeader(resp_hdr);  return status;}/*********************************************************************** *           RPCRT4_Send (internal) *  * Transmit a packet over connection in acceptable fragments. */RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,                       void *Buffer, unsigned int BufferLength){  RPC_STATUS r;  SecBuffer out;  if (!Connection->AuthInfo || SecIsValidHandle(&Connection->ctx))  {    return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0);  }  /* tack on a negotiate packet */  RPCRT4_ClientAuthorize(Connection, NULL, &out);  r = RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer);  HeapFree(GetProcessHeap(), 0, out.pvBuffer);  return r;}/*********************************************************************** *           RPCRT4_Receive (internal) *  * Receive a packet from connection and merge the fragments. */RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,                          PRPC_MESSAGE pMsg){  RPC_STATUS status;  DWORD hdr_length;  LONG dwRead;  unsigned short first_flag;  unsigned long data_length;  unsigned long buffer_length;  unsigned long auth_length;  unsigned char *auth_data = NULL;  RpcPktCommonHdr common_hdr;  *Header = NULL;  TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);  /* read packet common header */  dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr));  if (dwRead != sizeof(common_hdr)) {    WARN("Short read of header, %d bytes\n", dwRead);    status = RPC_S_PROTOCOL_ERROR;    goto fail;  }  /* verify if the header really makes sense */  if (common_hdr.rpc_ver != RPC_VER_MAJOR ||      common_hdr.rpc_ver_minor != RPC_VER_MINOR) {    WARN("unhandled packet version\n");    status = RPC_S_PROTOCOL_ERROR;    goto fail;  }  hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr);  if (hdr_length == 0) {    WARN("header length == 0\n");    status = RPC_S_PROTOCOL_ERROR;    goto fail;  }  *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length);  memcpy(*Header, &common_hdr, sizeof(common_hdr));  /* read the rest of packet header */  dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr));  if (dwRead != hdr_length - sizeof(common_hdr)) {    WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length);    status = RPC_S_PROTOCOL_ERROR;    goto fail;  }  /* read packet body */  switch (common_hdr.ptype) {  case PKT_RESPONSE:    pMsg->BufferLength = (*Header)->response.alloc_hint;    break;  case PKT_REQUEST:    pMsg->BufferLength = (*Header)->request.alloc_hint;    break;  default:    pMsg->BufferLength = common_hdr.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&common_hdr);  }  TRACE("buffer length = %u\n", pMsg->BufferLength);  status = I_RpcGetBuffer(pMsg);  if (status != RPC_S_OK) goto fail;  first_flag = RPC_FLG_FIRST;  auth_length = common_hdr.auth_len;  if (auth_length) {    auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr));    if (!auth_data) {      status = RPC_S_PROTOCOL_ERROR;      goto fail;    }  }  buffer_length = 0;  while (TRUE)  {    unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common);    /* verify header fields */    if (((*Header)->common.frag_len < hdr_length) ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -