Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
8.1 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. osfpcket.cxx
  5. Abstract:
  6. This file provides helper routines for dealing with packets for the
  7. OSF Connection Oriented RPC protocol.
  8. Author:
  9. Michael Montague (mikemon) 23-Jul-1990
  10. Revision History:
  11. 30-Apr-1991 o-decjt
  12. Initialized the drep[4] fields to reflect integer, character,
  13. and floating point format.
  14. --*/
  15. #include <precomp.hxx>
  16. #include <osfpcket.hxx>
  17. void
  18. ConstructPacket (
  19. IN OUT rpcconn_common PAPI * Packet,
  20. IN unsigned char PacketType,
  21. IN unsigned int PacketLength
  22. )
  23. /*++
  24. Routine Description:
  25. This routine fills in the common fields of a packet, except for the
  26. call_id.
  27. Arguments:
  28. Packet - Supplies the packet for which we want to fill in the common
  29. fields; returns the filled in packet.
  30. PacketType - Supplies the type of the packet; this is one of the values
  31. in the rpc_ptype_t enumeration.
  32. PacketLength - Supplies the total length of the packet in bytes.
  33. --*/
  34. {
  35. Packet->rpc_vers = OSF_RPC_V20_VERS;
  36. Packet->rpc_vers_minor = OSF_RPC_V20_VERS_MINOR;
  37. Packet->PTYPE = PacketType;
  38. Packet->pfc_flags = 0;
  39. Packet->drep[0] = NDR_LOCAL_CHAR_DREP | NDR_LOCAL_INT_DREP;
  40. Packet->drep[1] = NDR_LOCAL_FP_DREP;
  41. Packet->drep[2] = 0;
  42. Packet->drep[3] = 0;
  43. Packet->frag_length = (unsigned short) PacketLength;
  44. Packet->auth_length = 0;
  45. }
  46. unsigned int PacketSizes[] =
  47. {
  48. sizeof(rpcconn_request), // rpc_request = 0
  49. 0, // = 1
  50. sizeof(rpcconn_response), // rpc_response = 2
  51. FaultSizeWithoutEEInfo, // rpc_fault = 3. This may not use the whole rpcconn_fault
  52. // since we may not send EEInfo.
  53. 0,// = 4
  54. 0,// = 5
  55. 0,// = 6
  56. 0,// = 7
  57. 0,// = 8
  58. 0,// = 9
  59. 0,// = 10
  60. sizeof(rpcconn_bind), // rpc_bind = 11,
  61. sizeof(rpcconn_bind_ack), // rpc_bind_ack = 12,
  62. MinimumBindNakLength, // rpc_bind_nak = 13. Similar to rpc_fault.
  63. sizeof(rpcconn_alter_context), // rpc_alter_context = 14,
  64. sizeof(rpcconn_alter_context_resp), // rpc_alter_context_resp = 15,
  65. sizeof(rpcconn_auth3), // rpc_auth_3 = 16,
  66. sizeof(rpcconn_common), // rpc_shutdown = 17. We do not really process these much.
  67. sizeof(rpcconn_common), // rpc_cancel = 18,
  68. sizeof(rpcconn_common) // rpc_orphaned = 19
  69. };
  70. // in many places we treat the size of the request and response interchangeably
  71. // Make sure this is valid on all platforms
  72. C_ASSERT(sizeof(rpcconn_response) == sizeof(rpcconn_request));
  73. unsigned int
  74. MinPacketLength (
  75. IN rpcconn_common PAPI *Packet
  76. )
  77. {
  78. unsigned int Size;
  79. if (Packet->PTYPE > rpc_orphaned)
  80. {
  81. return 0;
  82. }
  83. Size = PacketSizes[Packet->PTYPE];
  84. if (Size == 0)
  85. {
  86. return 0;
  87. }
  88. if (Packet->pfc_flags & PFC_OBJECT_UUID)
  89. {
  90. Size += sizeof(UUID);
  91. }
  92. if (Packet->auth_length)
  93. {
  94. Size += Packet->auth_length+sizeof(sec_trailer);
  95. if (Size > Packet->frag_length)
  96. {
  97. return 0;
  98. }
  99. sec_trailer * SecurityTrailer = (sec_trailer *) (((unsigned char *) Packet)
  100. + Packet->frag_length - Packet->auth_length - sizeof(sec_trailer));
  101. Size += SecurityTrailer->auth_pad_length;
  102. }
  103. return Size;
  104. }
  105. RPC_STATUS
  106. ValidatePacket (
  107. IN rpcconn_common PAPI * Packet,
  108. IN unsigned int PacketLength
  109. )
  110. /*++
  111. Routine Description:
  112. This is the routine used to validate a packet and perform data
  113. conversion, if necessary of the common part of a packet. In addition,
  114. to data converting the common part of a packet, we data convert the
  115. rest of the headers of rpc_request, rpc_response, and rpc_fault packets.
  116. Arguments:
  117. Packet - Supplies the packet to validate and data convert (if
  118. necessary).
  119. PacketLength - Supplies the length of the packet as reported by the
  120. transport.
  121. Return Value:
  122. RPC_S_OK - The packet has been successfully validated and the data
  123. converted (if necessary).
  124. RPC_S_PROTOCOL_ERROR - The supplied packet does not contain an rpc
  125. protocol version which we recognize.
  126. --*/
  127. {
  128. if ( DataConvertEndian(Packet->drep) != 0 )
  129. {
  130. // We need to data convert the packet.
  131. Packet->frag_length = RpcpByteSwapShort(Packet->frag_length);
  132. Packet->auth_length = RpcpByteSwapShort(Packet->auth_length);
  133. Packet->call_id = RpcpByteSwapLong(Packet->call_id);
  134. if ( (Packet->PTYPE == rpc_request)
  135. || (Packet->PTYPE == rpc_response)
  136. || (Packet->PTYPE == rpc_fault))
  137. {
  138. // We are going to touch fields beyond sizeof(rpcconn_common).
  139. // Make sure the memory is there. Since we are touching rpcconn_request's
  140. // fields it is enough to compare against it.
  141. if (PacketLength < sizeof(rpcconn_request))
  142. {
  143. CORRUPTION_ASSERT(PacketLength >= sizeof(rpcconn_request));
  144. return(RPC_S_PROTOCOL_ERROR);
  145. }
  146. ((rpcconn_request PAPI *) Packet)->alloc_hint =
  147. RpcpByteSwapLong(((rpcconn_request PAPI *) Packet)->alloc_hint);
  148. ((rpcconn_request PAPI *) Packet)->p_cont_id
  149. = RpcpByteSwapShort(((rpcconn_request PAPI *) Packet)->p_cont_id);
  150. if ( Packet->PTYPE == rpc_request )
  151. {
  152. ((rpcconn_request PAPI *) Packet)->opnum =
  153. RpcpByteSwapShort(((rpcconn_request PAPI *) Packet)->opnum);
  154. }
  155. }
  156. }
  157. else if ( (Packet->drep[0] & NDR_DREP_ENDIAN_MASK) != NDR_LOCAL_INT_DREP )
  158. {
  159. CORRUPTION_ASSERT(0);
  160. return(RPC_S_PROTOCOL_ERROR);
  161. }
  162. if (Packet->frag_length != (unsigned short) PacketLength)
  163. {
  164. CORRUPTION_ASSERT(0);
  165. return (RPC_S_PROTOCOL_ERROR);
  166. }
  167. unsigned int MinLength = MinPacketLength(Packet);
  168. if (MinLength == 0 || MinLength > PacketLength)
  169. {
  170. CORRUPTION_ASSERT(0);
  171. return (RPC_S_PROTOCOL_ERROR);
  172. }
  173. if ( (Packet->rpc_vers != OSF_RPC_V20_VERS)
  174. || (Packet->rpc_vers_minor > OSF_RPC_V20_VERS_MINOR))
  175. {
  176. // Some Unix boxes give these bogus versions to us at times
  177. // and we will skip asserting on chk builds.
  178. return(RPC_S_PROTOCOL_ERROR);
  179. }
  180. return(RPC_S_OK);
  181. }
  182. void
  183. ByteSwapSyntaxId (
  184. IN p_syntax_id_t PAPI * SyntaxId
  185. )
  186. /*++
  187. Routine Description:
  188. This routine is used to perform data conversion in a syntax identifier
  189. if necessary.
  190. Arguments:
  191. SyntaxId - Supplies the syntax identifier to be byte swapped.
  192. --*/
  193. {
  194. ByteSwapUuid((RPC_UUID *)&SyntaxId->if_uuid);
  195. SyntaxId->if_version = RpcpByteSwapLong(SyntaxId->if_version);
  196. }
  197. #if 0
  198. void
  199. ConvertStringEbcdicToAscii (
  200. IN unsigned char * String
  201. )
  202. /*++
  203. Routine Description:
  204. We will convert a zero terminated character string from EBCDIC to
  205. ASCII. The conversion will be done in place.
  206. Arguments:
  207. String - Supplies the string to be converted.
  208. --*/
  209. {
  210. UNUSED(String);
  211. ASSERT(!RPC_S_CANNOT_SUPPORT);
  212. }
  213. #endif
  214. void
  215. UnpickleEEInfoFromBuffer (
  216. IN PVOID Buffer,
  217. IN size_t SizeOfPickledData
  218. )
  219. {
  220. RPC_STATUS RpcStatus;
  221. ExtendedErrorInfo *EEInfo;
  222. ASSERT(IsBufferAligned(Buffer));
  223. ASSERT(RpcpGetEEInfo() == NULL);
  224. RpcStatus = UnpickleEEInfo((unsigned char *)Buffer,
  225. SizeOfPickledData,
  226. &EEInfo);
  227. if (RpcStatus == RPC_S_OK)
  228. {
  229. StripComputerNameIfRedundant(EEInfo);
  230. RpcpSetEEInfo(EEInfo);
  231. }
  232. }
  233. // the size of all these structs must be 4 byte aligned
  234. C_ASSERT(ConstPadN(sizeof(rpc_sec_vt_pcontext), 4) == 0);
  235. C_ASSERT(ConstPadN(sizeof(rpc_sec_vt_bitmask), 4) == 0);
  236. C_ASSERT(ConstPadN(sizeof(rpc_sec_vt_header2), 4) == 0);