rpc.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. #ifndef _DEFAULT_SOURCE
  2. #define _DEFAULT_SOURCE
  3. #endif // _DEFAULT_SOURCE
  4. #ifndef CONFIG
  5. #define CONFIG "config.h"
  6. #endif // CONFIG
  7. #include CONFIG
  8. #ifndef USE_MSRPC
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdint.h>
  13. #include <ctype.h>
  14. #include <time.h>
  15. #if !defined(_WIN32)
  16. #include <sys/socket.h>
  17. #include <netdb.h>
  18. #endif
  19. #include "rpc.h"
  20. #include "output.h"
  21. #include "crypto.h"
  22. #include "endian.h"
  23. #include "helpers.h"
  24. #include "network.h"
  25. #include "shared_globals.h"
  26. /* Forwards */
  27. static int checkRpcHeader(const RPC_HEADER *const Header, const BYTE desiredPacketType, const PRINTFUNC p);
  28. /* Data definitions */
  29. // All GUIDs are defined as BYTE[16] here. No big-endian/little-endian byteswapping required.
  30. static const BYTE TransferSyntaxNDR32[] = {
  31. 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60
  32. };
  33. static const BYTE InterfaceUuid[] = {
  34. 0x75, 0x21, 0xc8, 0x51, 0x4e, 0x84, 0x50, 0x47, 0xB0, 0xD8, 0xEC, 0x25, 0x55, 0x55, 0xBC, 0x06
  35. };
  36. static const BYTE TransferSyntaxNDR64[] = {
  37. 0x33, 0x05, 0x71, 0x71, 0xba, 0xbe, 0x37, 0x49, 0x83, 0x19, 0xb5, 0xdb, 0xef, 0x9c, 0xcc, 0x36
  38. };
  39. static const BYTE BindTimeFeatureNegotiation[] = {
  40. 0x2c, 0x1c, 0xb7, 0x6c, 0x12, 0x98, 0x40, 0x45, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  41. };
  42. //
  43. // Dispatch RPC payload to kms.c
  44. //
  45. typedef int (*CreateResponse_t)(const void *const, void *const, const char* const);
  46. static const struct {
  47. unsigned int RequestSize;
  48. CreateResponse_t CreateResponse;
  49. } _Versions[] = {
  50. { sizeof(REQUEST_V4), (CreateResponse_t) CreateResponseV4 },
  51. { sizeof(REQUEST_V6), (CreateResponse_t) CreateResponseV6 },
  52. { sizeof(REQUEST_V6), (CreateResponse_t) CreateResponseV6 }
  53. };
  54. RPC_FLAGS RpcFlags;
  55. static int_fast8_t firstPacketSent;
  56. //
  57. // RPC request (server)
  58. //
  59. #if defined(_PEDANTIC) && !defined(NO_LOG)
  60. static void CheckRpcRequest(const RPC_REQUEST64 *const Request, const unsigned int len, WORD* NdrCtx, WORD* Ndr64Ctx, WORD Ctx)
  61. {
  62. uint_fast8_t kmsMajorVersion;
  63. uint32_t requestSize = Ctx != *Ndr64Ctx ? sizeof(RPC_REQUEST) : sizeof(RPC_REQUEST64);
  64. if (len < requestSize)
  65. {
  66. logger("Fatal: RPC request (including header) must be at least %i bytes but is only %i bytes.\n",
  67. (int)(sizeof(RPC_HEADER) + requestSize),
  68. (int)(len + sizeof(RPC_HEADER))
  69. );
  70. return;
  71. }
  72. if (len < requestSize + sizeof(DWORD))
  73. {
  74. logger("Fatal: KMS Request too small to contain version info (less than 4 bytes).\n");
  75. return;
  76. }
  77. if (Ctx != *Ndr64Ctx)
  78. kmsMajorVersion = (uint_fast8_t)LE16(((WORD*)Request->Ndr.Data)[1]);
  79. else
  80. kmsMajorVersion = (uint_fast8_t)LE16(((WORD*)Request->Ndr64.Data)[1]);
  81. if (kmsMajorVersion > 6)
  82. {
  83. logger("Fatal: KMSv%u is not supported.\n", (unsigned int)kmsMajorVersion);
  84. }
  85. else
  86. {
  87. if (len >_Versions[kmsMajorVersion].RequestSize + requestSize)
  88. logger("Warning: %u excess bytes in RPC request.\n",
  89. len - _Versions[kmsMajorVersion].RequestSize
  90. );
  91. }
  92. if (Ctx != *Ndr64Ctx && Ctx != *NdrCtx)
  93. logger("Warning: Context id should be %u (NDR32) or %u (NDR64) but is %u.\n",
  94. (unsigned int)*NdrCtx,
  95. (unsigned int)*Ndr64Ctx,
  96. Ctx
  97. );
  98. if (Request->Opnum)
  99. logger("Warning: OpNum should be 0 but is %u.\n",
  100. (unsigned int)LE16(Request->Opnum)
  101. );
  102. if (LE32(Request->AllocHint) != len - sizeof(RPC_REQUEST) + sizeof(Request->Ndr))
  103. logger("Warning: Allocation hint should be %u but is %u.\n",
  104. len + sizeof(Request->Ndr),
  105. LE32(Request->AllocHint)
  106. );
  107. if (Ctx != *Ndr64Ctx)
  108. {
  109. if (LE32(Request->Ndr.DataLength) != len - sizeof(RPC_REQUEST))
  110. logger("Warning: NDR32 data length field should be %u but is %u.\n",
  111. len - sizeof(RPC_REQUEST),
  112. LE32(Request->Ndr.DataLength)
  113. );
  114. if (LE32(Request->Ndr.DataSizeIs) != len - sizeof(RPC_REQUEST))
  115. logger("Warning: NDR32 data size field should be %u but is %u.\n",
  116. len - sizeof(RPC_REQUEST),
  117. LE32(Request->Ndr.DataSizeIs)
  118. );
  119. }
  120. else
  121. {
  122. if (LE64(Request->Ndr64.DataLength) != len - sizeof(RPC_REQUEST64))
  123. logger("Warning: NDR32 data length field should be %u but is %u.\n",
  124. len - sizeof(RPC_REQUEST) + sizeof(Request->Ndr),
  125. LE64(Request->Ndr64.DataLength)
  126. );
  127. if (LE64(Request->Ndr64.DataSizeIs) != len - sizeof(RPC_REQUEST64))
  128. logger("Warning: NDR32 data size field should be %u but is %u.\n",
  129. len - sizeof(RPC_REQUEST64),
  130. LE64(Request->Ndr64.DataSizeIs)
  131. );
  132. }
  133. }
  134. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  135. /*
  136. * check RPC request for (somewhat) correct size
  137. * allow any size that does not cause CreateResponse to fail badly
  138. */
  139. static unsigned int checkRpcRequestSize(const RPC_REQUEST64 *const Request, const unsigned int requestSize, WORD* NdrCtx, WORD* Ndr64Ctx)
  140. {
  141. WORD Ctx = LE16(Request->ContextId);
  142. # if defined(_PEDANTIC) && !defined(NO_LOG)
  143. CheckRpcRequest(Request, requestSize, NdrCtx, Ndr64Ctx, Ctx);
  144. # endif // defined(_PEDANTIC) && !defined(NO_LOG)
  145. // Anything that is smaller than a v4 request is illegal
  146. if (requestSize < sizeof(REQUEST_V4) + (Ctx != *Ndr64Ctx ? sizeof(RPC_REQUEST) : sizeof(RPC_REQUEST64))) return 0;
  147. // Get KMS major version
  148. uint16_t majorIndex, minor;
  149. DWORD version;
  150. if (Ctx != *Ndr64Ctx)
  151. {
  152. version = LE32(*(DWORD*)Request->Ndr.Data);
  153. }
  154. else
  155. {
  156. version = LE32(*(DWORD*)Request->Ndr64.Data);
  157. }
  158. majorIndex = (uint16_t)(version >> 16) - 4;
  159. minor = (uint16_t)(version & 0xffff);
  160. // Only KMS v4, v5 and v6 are supported
  161. if (majorIndex >= vlmcsd_countof(_Versions) || minor)
  162. {
  163. # ifndef NO_LOG
  164. logger("Fatal: KMSv%hu.%hu unsupported\n", (unsigned short)majorIndex + 4, (unsigned short)minor);
  165. # endif // NO_LOG
  166. return 0;
  167. }
  168. // Could check for equality but allow bigger requests to support buggy RPC clients (e.g. wine)
  169. // Buffer overrun is check by caller.
  170. return (requestSize >= _Versions[majorIndex].RequestSize);
  171. }
  172. /*
  173. * Handles the actual KMS request from the client.
  174. * Calls KMS functions (CreateResponseV4 or CreateResponseV6) in kms.c
  175. * Returns size of the KMS response packet or 0 on failure.
  176. *
  177. * The RPC packet size (excluding header) is actually in Response->AllocHint
  178. */
  179. static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const Response, const DWORD RpcAssocGroup_unused, const SOCKET sock_unused, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE isValid, const char* const ipstr)
  180. {
  181. int ResponseSize; // <0 = Errorcode (HRESULT)
  182. WORD Ctx = LE16(Request->ContextId);
  183. BYTE* requestData;
  184. BYTE* responseData;
  185. BYTE* pRpcReturnCode;
  186. int len;
  187. if (Ctx != *Ndr64Ctx)
  188. {
  189. requestData = (BYTE*)&Request->Ndr.Data;
  190. responseData = (BYTE*)&Response->Ndr.Data;
  191. }
  192. else
  193. {
  194. requestData = (BYTE*)&Request->Ndr64.Data;
  195. responseData = (BYTE*)&Response->Ndr64.Data;
  196. }
  197. ResponseSize = 0x8007000D; // Invalid Data
  198. if (isValid)
  199. {
  200. uint16_t majorIndex = LE16(((WORD*)requestData)[1]) - 4;
  201. if (!(ResponseSize = _Versions[majorIndex].CreateResponse(requestData, responseData, ipstr))) ResponseSize = 0x8007000D;
  202. }
  203. if (Ctx != *Ndr64Ctx)
  204. {
  205. if (ResponseSize < 0)
  206. {
  207. Response->Ndr.DataSizeMax = Response->Ndr.DataLength = 0;
  208. len = sizeof(Response->Ndr) - sizeof(Response->Ndr.DataSizeIs);
  209. }
  210. else
  211. {
  212. Response->Ndr.DataSizeMax = LE32(0x00020000);
  213. Response->Ndr.DataLength = Response->Ndr.DataSizeIs = LE32(ResponseSize);
  214. len = ResponseSize + sizeof(Response->Ndr);
  215. }
  216. }
  217. else
  218. {
  219. if (ResponseSize < 0)
  220. {
  221. Response->Ndr64.DataSizeMax = Response->Ndr64.DataLength = 0;
  222. len = sizeof(Response->Ndr64) - sizeof(Response->Ndr64.DataSizeIs);
  223. }
  224. else
  225. {
  226. Response->Ndr64.DataSizeMax = LE64(0x00020000ULL);
  227. Response->Ndr64.DataLength = Response->Ndr64.DataSizeIs = LE64((uint64_t)ResponseSize);
  228. len = ResponseSize + sizeof(Response->Ndr64);
  229. }
  230. }
  231. pRpcReturnCode = ((BYTE*)&Response->Ndr) + len;
  232. UA32(pRpcReturnCode) = ResponseSize < 0 ? LE32(ResponseSize) : 0;
  233. len += sizeof(DWORD);
  234. // Pad zeros to 32-bit align (seems not neccassary but Windows RPC does it this way)
  235. int pad = ((~len & 3) + 1) & 3;
  236. memset(pRpcReturnCode + sizeof(DWORD), 0, pad);
  237. len += pad;
  238. Response->AllocHint = LE32(len);
  239. Response->ContextId = Request->ContextId;
  240. *((WORD*)&Response->CancelCount) = 0; // CancelCount + Pad1
  241. return len + 8;
  242. }
  243. #if defined(_PEDANTIC) && !defined(NO_LOG)
  244. static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const unsigned int len)
  245. {
  246. uint_fast8_t i, HasTransferSyntaxNDR32 = FALSE;
  247. char guidBuffer1[GUID_STRING_LENGTH + 1], guidBuffer2[GUID_STRING_LENGTH + 1];
  248. uint32_t CapCtxItems = (len - sizeof(*Request) + sizeof(Request->CtxItems)) / sizeof(Request->CtxItems);
  249. DWORD NumCtxItems = LE32(Request->NumCtxItems);
  250. if (NumCtxItems < CapCtxItems) // Can't be too small because already handled by RpcBindSize
  251. logger("Warning: Excess bytes in RPC bind request.\n");
  252. for (i = 0; i < NumCtxItems; i++)
  253. {
  254. if (!IsEqualGUID(&Request->CtxItems[i].InterfaceUUID, InterfaceUuid))
  255. {
  256. uuid2StringLE((GUID*)&Request->CtxItems[i].InterfaceUUID, guidBuffer1);
  257. uuid2StringLE((GUID*)InterfaceUuid, guidBuffer2);
  258. logger("Warning: Interface UUID is %s but should be %s in Ctx item %u.\n", guidBuffer1, guidBuffer2, (unsigned int)i);
  259. }
  260. if (Request->CtxItems[i].NumTransItems != LE16(1))
  261. logger("Fatal: %u NDR32 transfer items detected in Ctx item %u, but only one is supported.\n",
  262. (unsigned int)LE16(Request->CtxItems[i].NumTransItems), (unsigned int)i
  263. );
  264. if (Request->CtxItems[i].InterfaceVerMajor != LE16(1) || Request->CtxItems[i].InterfaceVerMinor != 0)
  265. logger("Warning: NDR32 Interface version is %u.%u but should be 1.0.\n",
  266. (unsigned int)LE16(Request->CtxItems[i].InterfaceVerMajor),
  267. (unsigned int)LE16(Request->CtxItems[i].InterfaceVerMinor)
  268. );
  269. if (Request->CtxItems[i].ContextId != LE16((WORD)i))
  270. logger("Warning: context id of Ctx item %u is %u.\n", (unsigned int)i, (unsigned int)Request->CtxItems[i].ContextId);
  271. if ( IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  272. {
  273. HasTransferSyntaxNDR32 = TRUE;
  274. if (Request->CtxItems[i].SyntaxVersion != LE32(2))
  275. logger("NDR32 transfer syntax version is %u but should be 2.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  276. }
  277. else if ( IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  278. {
  279. if (Request->CtxItems[i].SyntaxVersion != LE32(1))
  280. logger("NDR64 transfer syntax version is %u but should be 1.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  281. }
  282. else if (!memcmp(BindTimeFeatureNegotiation, (BYTE*)(&Request->CtxItems[i].TransferSyntax), 8))
  283. {
  284. if (Request->CtxItems[i].SyntaxVersion != LE32(1))
  285. logger("BTFN syntax version is %u but should be 1.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  286. }
  287. }
  288. if (!HasTransferSyntaxNDR32)
  289. logger("Warning: RPC bind request has no NDR32 CtxItem.\n");
  290. }
  291. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  292. /*
  293. * Check, if we receive enough bytes to return a valid RPC bind response
  294. */
  295. static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, const unsigned int RequestSize, WORD* NdrCtx, WORD* Ndr64Ctx)
  296. {
  297. if ( RequestSize < sizeof(RPC_BIND_REQUEST) ) return FALSE;
  298. unsigned int _NumCtxItems = LE32(Request->NumCtxItems);
  299. if ( RequestSize < sizeof(RPC_BIND_REQUEST) - sizeof(Request->CtxItems[0]) + _NumCtxItems * sizeof(Request->CtxItems[0]) ) return FALSE;
  300. #if defined(_PEDANTIC) && !defined(NO_LOG)
  301. CheckRpcBindRequest(Request, RequestSize);
  302. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  303. return TRUE;
  304. }
  305. /*
  306. * Accepts a bind or alter context request from the client and composes the bind response.
  307. * Needs the socket because the tcp port number is part of the response.
  308. * len is not used here.
  309. *
  310. * Returns TRUE on success.
  311. */
  312. static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Response, const DWORD RpcAssocGroup, const SOCKET sock, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr_unused)
  313. {
  314. unsigned int i, _st = FALSE;
  315. DWORD numCtxItems = LE32(Request->NumCtxItems);
  316. int_fast8_t IsNDR64possible = FALSE;
  317. uint_fast8_t portNumberSize;
  318. socklen_t socklen;
  319. struct sockaddr_storage addr;
  320. // M$ RPC does not do this. Pad bytes contain apparently random data
  321. // memset(Response->SecondaryAddress, 0, sizeof(Response->SecondaryAddress));
  322. socklen = sizeof addr;
  323. if (
  324. packetType == RPC_PT_ALTERCONTEXT_REQ ||
  325. getsockname(sock, (struct sockaddr*)&addr, &socklen) ||
  326. getnameinfo((struct sockaddr*)&addr, socklen, NULL, 0, (char*)Response->SecondaryAddress, sizeof(Response->SecondaryAddress), NI_NUMERICSERV))
  327. {
  328. portNumberSize = 0;
  329. Response->SecondaryAddressLength = 0;
  330. }
  331. else
  332. {
  333. portNumberSize = (uint_fast8_t)strlen((char*)Response->SecondaryAddress) + 1;
  334. Response->SecondaryAddressLength = LE16(portNumberSize);
  335. }
  336. Response->MaxXmitFrag = Request->MaxXmitFrag;
  337. Response->MaxRecvFrag = Request->MaxRecvFrag;
  338. Response->AssocGroup = LE32(RpcAssocGroup);
  339. // This is really ugly (but efficient) code to support padding after the secondary address field
  340. if (portNumberSize < 3)
  341. {
  342. Response = (RPC_BIND_RESPONSE*)((BYTE*)Response - 4);
  343. }
  344. Response->NumResults = Request->NumCtxItems;
  345. if (UseRpcNDR64)
  346. {
  347. for (i = 0; i < numCtxItems; i++)
  348. {
  349. if ( IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  350. {
  351. /*if (packetType == RPC_PT_BIND_REQ)*/
  352. *NdrCtx = LE16(Request->CtxItems[i].ContextId);
  353. }
  354. if ( IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  355. {
  356. IsNDR64possible = TRUE;
  357. /*if (packetType == RPC_PT_BIND_REQ)*/
  358. *Ndr64Ctx = LE16(Request->CtxItems[i].ContextId);
  359. }
  360. }
  361. }
  362. for (i = 0; i < numCtxItems; i++)
  363. {
  364. memset(&Response->Results[i].TransferSyntax, 0, sizeof(GUID));
  365. if ( !IsNDR64possible && IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  366. {
  367. Response->Results[i].SyntaxVersion = LE32(2);
  368. Response->Results[i].AckResult =
  369. Response->Results[i].AckReason = RPC_BIND_ACCEPT;
  370. memcpy(&Response->Results[i].TransferSyntax, TransferSyntaxNDR32, sizeof(GUID));
  371. _st = TRUE;
  372. }
  373. else if ( IsNDR64possible && IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  374. {
  375. Response->Results[i].SyntaxVersion = LE32(1);
  376. Response->Results[i].AckResult =
  377. Response->Results[i].AckReason = RPC_BIND_ACCEPT;
  378. memcpy(&Response->Results[i].TransferSyntax, TransferSyntaxNDR64, sizeof(GUID));
  379. _st = TRUE;
  380. }
  381. else if ( UseRpcBTFN && !memcmp(BindTimeFeatureNegotiation, (BYTE*)(&Request->CtxItems[i].TransferSyntax), 8) )
  382. {
  383. Response->Results[i].SyntaxVersion = 0;
  384. Response->Results[i].AckResult = RPC_BIND_ACK;
  385. // Features requested are actually encoded in the GUID
  386. Response->Results[i].AckReason =
  387. ((WORD*)(&Request->CtxItems[i].TransferSyntax))[4] &
  388. (RPC_BTFN_SEC_CONTEXT_MULTIPLEX | RPC_BTFN_KEEP_ORPHAN);
  389. }
  390. else
  391. {
  392. Response->Results[i].SyntaxVersion = 0;
  393. Response->Results[i].AckResult =
  394. Response->Results[i].AckReason = RPC_BIND_NACK; // Unsupported
  395. }
  396. }
  397. if ( !_st ) return 0;
  398. return sizeof(RPC_BIND_RESPONSE) + numCtxItems * sizeof(((RPC_BIND_RESPONSE *)0)->Results[0]) - (portNumberSize < 3 ? 4 : 0);
  399. }
  400. //
  401. // Main RPC handling routine
  402. //
  403. typedef unsigned int (*GetResponseSize_t)(const void *const request, const unsigned int requestSize, WORD* NdrCtx, WORD* Ndr64Ctx);
  404. typedef int (*GetResponse_t)(const void* const request, void* response, const DWORD rpcAssocGroup, const SOCKET socket, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr);
  405. static const struct {
  406. BYTE ResponsePacketType;
  407. GetResponseSize_t CheckRequestSize;
  408. GetResponse_t GetResponse;
  409. }
  410. _Actions[] = {
  411. { RPC_PT_BIND_ACK, (GetResponseSize_t)checkRpcBindSize, (GetResponse_t) rpcBind },
  412. { RPC_PT_RESPONSE, (GetResponseSize_t)checkRpcRequestSize, (GetResponse_t) rpcRequest },
  413. { RPC_PT_ALTERCONTEXT_ACK, (GetResponseSize_t)checkRpcBindSize, (GetResponse_t) rpcBind },
  414. };
  415. /*
  416. * This is the main RPC server loop. Returns after KMS request has been serviced
  417. * or a timeout has occured.
  418. */
  419. void rpcServer(const SOCKET sock, const DWORD RpcAssocGroup, const char* const ipstr)
  420. {
  421. RPC_HEADER rpcRequestHeader;
  422. WORD NdrCtx = INVALID_NDR_CTX, Ndr64Ctx = INVALID_NDR_CTX;
  423. randomNumberInit();
  424. while (_recv(sock, &rpcRequestHeader, sizeof(rpcRequestHeader)))
  425. {
  426. //int_fast8_t _st;
  427. unsigned int request_len, response_len;
  428. uint_fast8_t _a;
  429. #if defined(_PEDANTIC) && !defined(NO_LOG)
  430. checkRpcHeader(&rpcRequestHeader, rpcRequestHeader.PacketType, &logger);
  431. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  432. switch (rpcRequestHeader.PacketType)
  433. {
  434. case RPC_PT_BIND_REQ: _a = 0; break;
  435. case RPC_PT_REQUEST: _a = 1; break;
  436. case RPC_PT_ALTERCONTEXT_REQ: _a = 2; break;
  437. default: return;
  438. }
  439. request_len = LE16(rpcRequestHeader.FragLength) - sizeof(rpcRequestHeader);
  440. BYTE requestBuffer[MAX_REQUEST_SIZE + sizeof(RPC_RESPONSE64)];
  441. BYTE responseBuffer[MAX_RESPONSE_SIZE + sizeof(RPC_HEADER) + sizeof(RPC_RESPONSE64)];
  442. RPC_HEADER *rpcResponseHeader = (RPC_HEADER *)responseBuffer;
  443. RPC_RESPONSE* rpcResponse = (RPC_RESPONSE*)(responseBuffer + sizeof(rpcRequestHeader));
  444. // The request is larger than the buffer size
  445. if (request_len > MAX_REQUEST_SIZE + sizeof(RPC_REQUEST64)) return;
  446. // Unable to receive the complete request
  447. if (!_recv(sock, requestBuffer, request_len)) return;
  448. // Request is invalid
  449. BYTE isValid = (BYTE)_Actions[_a].CheckRequestSize(requestBuffer, request_len, &NdrCtx, &Ndr64Ctx);
  450. if (rpcRequestHeader.PacketType != RPC_PT_REQUEST && !isValid) return;
  451. // Unable to create a valid response from request
  452. if (!(response_len = _Actions[_a].GetResponse(requestBuffer, rpcResponse, RpcAssocGroup, sock, &NdrCtx, &Ndr64Ctx, rpcRequestHeader.PacketType != RPC_PT_REQUEST ? rpcRequestHeader.PacketType : isValid, ipstr))) return;
  453. response_len += sizeof(RPC_HEADER);
  454. memcpy(rpcResponseHeader, &rpcRequestHeader, sizeof(RPC_HEADER));
  455. rpcResponseHeader->FragLength = LE16((WORD)response_len);
  456. rpcResponseHeader->PacketType = _Actions[_a].ResponsePacketType;
  457. if (rpcResponseHeader->PacketType == RPC_PT_ALTERCONTEXT_ACK)
  458. rpcResponseHeader->PacketFlags = RPC_PF_FIRST | RPC_PF_LAST;
  459. if (!_send(sock, responseBuffer, response_len)) return;
  460. if (DisconnectImmediately && rpcResponseHeader->PacketType == RPC_PT_RESPONSE)
  461. shutdown(sock, VLMCSD_SHUT_RDWR);
  462. }
  463. }
  464. /* RPC client functions */
  465. static DWORD CallId = 2; // M$ starts with CallId 2. So we do the same.
  466. /*
  467. * Checks RPC header. Returns 0 on success.
  468. * This is mainly for debugging a non Microsoft KMS server that uses its own RPC code.
  469. */
  470. static int checkRpcHeader(const RPC_HEADER *const Header, const BYTE desiredPacketType, const PRINTFUNC p)
  471. {
  472. int status = 0;
  473. if (Header->PacketType != desiredPacketType)
  474. {
  475. p("Fatal: Received wrong RPC packet type. Expected %u but got %u\n",
  476. (uint32_t)desiredPacketType,
  477. Header->PacketType
  478. );
  479. status = RPC_S_PROTOCOL_ERROR;
  480. }
  481. if (Header->DataRepresentation != BE32(0x10000000))
  482. {
  483. p("Fatal: RPC response does not conform to Microsoft's limited support of DCE RPC\n");
  484. status = RPC_S_PROTOCOL_ERROR;
  485. }
  486. if (Header->AuthLength != 0)
  487. {
  488. p("Fatal: RPC response requests authentication\n");
  489. status = RPC_S_UNKNOWN_AUTHN_TYPE;
  490. }
  491. // vlmcsd does not support fragmented packets (not yet neccassary)
  492. if ( (Header->PacketFlags & (RPC_PF_FIRST | RPC_PF_LAST)) != (RPC_PF_FIRST | RPC_PF_LAST) )
  493. {
  494. p("Fatal: RPC packet flags RPC_PF_FIRST and RPC_PF_LAST are not both set.\n");
  495. status = RPC_S_CANNOT_SUPPORT;
  496. }
  497. if (Header->PacketFlags & RPC_PF_CANCEL_PENDING) p("Warning: %s should not be set\n", "RPC_PF_CANCEL_PENDING");
  498. if (Header->PacketFlags & RPC_PF_RESERVED) p("Warning: %s should not be set\n", "RPC_PF_RESERVED");
  499. if (Header->PacketFlags & RPC_PF_NOT_EXEC) p("Warning: %s should not be set\n", "RPC_PF_NOT_EXEC");
  500. if (Header->PacketFlags & RPC_PF_MAYBE) p("Warning: %s should not be set\n", "RPC_PF_MAYBE");
  501. if (Header->PacketFlags & RPC_PF_OBJECT) p("Warning: %s should not be set\n", "RPC_PF_OBJECT");
  502. if (Header->VersionMajor != 5 || Header->VersionMinor != 0)
  503. {
  504. p("Fatal: Expected RPC version 5.0 and got %u.%u\n", Header->VersionMajor, Header->VersionMinor);
  505. status = RPC_S_INVALID_VERS_OPTION;
  506. }
  507. return status;
  508. }
  509. /*
  510. * Checks an RPC response header. Does basic header checks by calling checkRpcHeader()
  511. * and then does additional checks if response header complies with the respective request header.
  512. * PRINTFUNC p can be anything that has the same prototype as printf.
  513. * Returns 0 on success.
  514. */
  515. static int checkRpcResponseHeader(const RPC_HEADER *const ResponseHeader, const RPC_HEADER *const RequestHeader, const BYTE desiredPacketType, const PRINTFUNC p)
  516. {
  517. static int_fast8_t WineBugDetected = FALSE;
  518. int status = checkRpcHeader(ResponseHeader, desiredPacketType, p);
  519. if (desiredPacketType == RPC_PT_BIND_ACK)
  520. {
  521. if ((ResponseHeader->PacketFlags & RPC_PF_MULTIPLEX) != (RequestHeader->PacketFlags & RPC_PF_MULTIPLEX))
  522. {
  523. p("Warning: RPC_PF_MULTIPLEX of RPC request and response should match\n");
  524. }
  525. }
  526. else
  527. {
  528. if (ResponseHeader->PacketFlags & RPC_PF_MULTIPLEX)
  529. {
  530. p("Warning: %s should not be set\n", "RPC_PF_MULTIPLEX");
  531. }
  532. }
  533. if (!status && ResponseHeader->CallId == LE32(1))
  534. {
  535. if (!WineBugDetected)
  536. {
  537. p("Warning: Buggy RPC of Wine detected. Call Id of Response is always 1\n");
  538. WineBugDetected = TRUE;
  539. }
  540. }
  541. else if (ResponseHeader->CallId != RequestHeader->CallId)
  542. {
  543. p("Fatal: Sent Call Id %u but received answer for Call Id %u\n",
  544. (uint32_t)LE32(RequestHeader->CallId),
  545. (uint32_t)LE32(ResponseHeader->CallId)
  546. );
  547. status = RPC_S_PROTOCOL_ERROR;
  548. }
  549. return status;
  550. }
  551. /*
  552. * Initializes an RPC request header as needed for KMS, i.e. packet always fits in one fragment.
  553. * size cannot be greater than fragment length negotiated during RPC bind.
  554. */
  555. static void createRpcRequestHeader(RPC_HEADER* RequestHeader, BYTE packetType, WORD size)
  556. {
  557. RequestHeader->PacketType = packetType;
  558. RequestHeader->PacketFlags = RPC_PF_FIRST | RPC_PF_LAST;
  559. RequestHeader->VersionMajor = 5;
  560. RequestHeader->VersionMinor = 0;
  561. RequestHeader->AuthLength = 0;
  562. RequestHeader->DataRepresentation = BE32(0x10000000); // Little endian, ASCII charset, IEEE floating point
  563. RequestHeader->CallId = LE32(CallId);
  564. RequestHeader->FragLength = LE16(size);
  565. }
  566. /*
  567. * Sends a KMS request via RPC and receives a response.
  568. * Parameters are raw (encrypted) reqeuests / responses.
  569. * Returns 0 on success.
  570. */
  571. RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t *const responseSize)
  572. {
  573. #define MAX_EXCESS_BYTES 16
  574. RPC_HEADER *RequestHeader, ResponseHeader;
  575. RPC_REQUEST64 *RpcRequest;
  576. RPC_RESPONSE64 _Response;
  577. int status = 0;
  578. int_fast8_t useNdr64 = UseRpcNDR64 && firstPacketSent;
  579. size_t size = sizeof(RPC_HEADER) + (useNdr64 ? sizeof(RPC_REQUEST64) : sizeof(RPC_REQUEST)) + requestSize;
  580. size_t responseSize2;
  581. *KmsResponse = NULL;
  582. BYTE *_Request = (BYTE*)vlmcsd_malloc(size);
  583. RequestHeader = (RPC_HEADER*)_Request;
  584. RpcRequest = (RPC_REQUEST64*)(_Request + sizeof(RPC_HEADER));
  585. createRpcRequestHeader(RequestHeader, RPC_PT_REQUEST, (WORD)size);
  586. // Increment CallId for next Request
  587. CallId++;
  588. RpcRequest->Opnum = 0;
  589. if (useNdr64)
  590. {
  591. RpcRequest->ContextId = LE16(1); // We negotiate NDR64 always as context 1
  592. RpcRequest->AllocHint = LE32((DWORD)(requestSize + sizeof(RpcRequest->Ndr64)));
  593. RpcRequest->Ndr64.DataLength = LE64((uint64_t)requestSize);
  594. RpcRequest->Ndr64.DataSizeIs = LE64((uint64_t)requestSize);
  595. memcpy(RpcRequest->Ndr64.Data, KmsRequest, requestSize);
  596. }
  597. else
  598. {
  599. RpcRequest->ContextId = 0; // We negotiate NDR32 always as context 0
  600. RpcRequest->AllocHint = LE32((DWORD)(requestSize + sizeof(RpcRequest->Ndr)));
  601. RpcRequest->Ndr.DataLength = LE32((DWORD)requestSize);
  602. RpcRequest->Ndr.DataSizeIs = LE32((DWORD)requestSize);
  603. memcpy(RpcRequest->Ndr.Data, KmsRequest, requestSize);
  604. }
  605. for(;;)
  606. {
  607. int bytesread;
  608. if (!_send(sock, _Request, (int)size))
  609. {
  610. printerrorf("\nFatal: Could not send RPC request\n");
  611. status = RPC_S_COMM_FAILURE;
  612. break;
  613. }
  614. if (!_recv(sock, &ResponseHeader, sizeof(RPC_HEADER)))
  615. {
  616. printerrorf("\nFatal: No RPC response received from server\n");
  617. status = RPC_S_COMM_FAILURE;
  618. break;
  619. }
  620. if ((status = checkRpcResponseHeader(&ResponseHeader, RequestHeader, RPC_PT_RESPONSE, &printerrorf))) break;
  621. size = useNdr64 ? sizeof(RPC_RESPONSE64) : sizeof(RPC_RESPONSE);
  622. if (size > LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader))
  623. size = LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader);
  624. if (!_recv(sock, &_Response, (int)size))
  625. {
  626. printerrorf("\nFatal: RPC response is incomplete\n");
  627. status = RPC_S_COMM_FAILURE;
  628. break;
  629. }
  630. if (_Response.CancelCount != 0)
  631. {
  632. printerrorf("\nFatal: RPC response cancel count is not 0\n");
  633. status = RPC_S_CALL_CANCELLED;
  634. }
  635. if (_Response.ContextId != (useNdr64 ? LE16(1) : 0))
  636. {
  637. printerrorf("\nFatal: RPC response context id %u is not bound\n", (unsigned int)LE16(_Response.ContextId));
  638. status = RPC_X_SS_CONTEXT_DAMAGED;
  639. }
  640. int_fast8_t sizesMatch;
  641. if (useNdr64)
  642. {
  643. *responseSize = (size_t)LE64(_Response.Ndr64.DataLength);
  644. responseSize2 = (size_t)LE64(_Response.Ndr64.DataSizeIs);
  645. if (/*!*responseSize ||*/ !_Response.Ndr64.DataSizeMax)
  646. {
  647. status = (int)LE32(_Response.Ndr64.status);
  648. break;
  649. }
  650. sizesMatch = (size_t)LE64(_Response.Ndr64.DataLength) == responseSize2;
  651. }
  652. else
  653. {
  654. *responseSize = (size_t)LE32(_Response.Ndr.DataLength);
  655. responseSize2 = (size_t)LE32(_Response.Ndr.DataSizeIs);
  656. if (/*!*responseSize ||*/ !_Response.Ndr.DataSizeMax)
  657. {
  658. status = (int)LE32(_Response.Ndr.status);
  659. break;
  660. }
  661. sizesMatch = (size_t)LE32(_Response.Ndr.DataLength) == responseSize2;
  662. }
  663. if (!sizesMatch)
  664. {
  665. printerrorf("\nFatal: NDR data length (%u) does not match NDR data size (%u)\n",
  666. (uint32_t)*responseSize,
  667. (uint32_t)LE32(_Response.Ndr.DataSizeIs)
  668. );
  669. status = RPC_S_PROTOCOL_ERROR;
  670. }
  671. *KmsResponse = (BYTE*)vlmcsd_malloc(*responseSize + MAX_EXCESS_BYTES);
  672. // If RPC stub is too short, assume missing bytes are zero (same ill behavior as MS RPC)
  673. memset(*KmsResponse, 0, *responseSize + MAX_EXCESS_BYTES);
  674. // Read up to 16 bytes more than bytes expected to detect faulty KMS emulators
  675. if ((bytesread = recv(sock, (char*)*KmsResponse, (int)(*responseSize) + MAX_EXCESS_BYTES, 0)) < (int)*responseSize)
  676. {
  677. printerrorf("\nFatal: No or incomplete KMS response received. Required %u bytes but only got %i\n",
  678. (uint32_t)*responseSize,
  679. (int32_t)(bytesread < 0 ? 0 : bytesread)
  680. );
  681. status = RPC_S_PROTOCOL_ERROR;
  682. break;
  683. }
  684. DWORD *pReturnCode;
  685. size_t len = *responseSize + (useNdr64 ? sizeof(_Response.Ndr64) : sizeof(_Response.Ndr)) + sizeof(*pReturnCode);
  686. size_t pad = ((~len & 3) + 1) & 3;
  687. if (len + pad != LE32(_Response.AllocHint))
  688. {
  689. printerrorf("\nWarning: RPC stub size is %u, should be %u (probably incorrect padding)\n", (uint32_t)LE32(_Response.AllocHint), (uint32_t)(len + pad));
  690. }
  691. else
  692. {
  693. size_t i;
  694. for (i = 0; i < pad; i++)
  695. {
  696. if (*(*KmsResponse + *responseSize + sizeof(*pReturnCode) + i))
  697. {
  698. printerrorf("\nWarning: RPC stub data not padded to zeros according to Microsoft standard\n");
  699. break;
  700. }
  701. }
  702. }
  703. pReturnCode = (DWORD*)(*KmsResponse + *responseSize + pad);
  704. status = LE32(UA32(pReturnCode));
  705. break;
  706. }
  707. free(_Request);
  708. firstPacketSent = TRUE;
  709. return status;
  710. #undef MAX_EXCESS_BYTES
  711. }
  712. static int_fast8_t IsNullGuid(BYTE* guidPtr)
  713. {
  714. int_fast8_t i;
  715. for (i = 0; i < 16; i++)
  716. {
  717. if (guidPtr[i]) return FALSE;
  718. }
  719. return TRUE;
  720. }
  721. /*
  722. * Perform RPC client bind. Accepts a connected client socket.
  723. * Returns 0 on success. RPC binding is required before any payload can be
  724. * exchanged. It negotiates about protocol details.
  725. */
  726. RpcStatus rpcBindOrAlterClientContext(const RpcCtx sock, BYTE packetType, const int_fast8_t verbose)
  727. {
  728. RPC_HEADER *RequestHeader, ResponseHeader;
  729. RPC_BIND_REQUEST *bindRequest;
  730. RPC_BIND_RESPONSE *bindResponse;
  731. int status;
  732. WORD ctxItems = 1 + (packetType == RPC_PT_BIND_REQ ? UseRpcNDR64 + UseRpcBTFN : 0);
  733. size_t rpcBindSize = (sizeof(RPC_HEADER) + sizeof(RPC_BIND_REQUEST) + (ctxItems - 1) * sizeof(bindRequest->CtxItems[0]));
  734. WORD ctxIndex = 0;
  735. WORD i;
  736. WORD CtxBTFN = (WORD)~0, CtxNDR64 = (WORD)~0;
  737. BYTE* _Request = (BYTE*)alloca(rpcBindSize);
  738. RequestHeader = (RPC_HEADER*)_Request;
  739. bindRequest = (RPC_BIND_REQUEST* )(_Request + sizeof(RPC_HEADER));
  740. createRpcRequestHeader(RequestHeader, packetType, (WORD)rpcBindSize);
  741. RequestHeader->PacketFlags |= UseMultiplexedRpc ? RPC_PF_MULTIPLEX : 0;
  742. bindRequest->AssocGroup = 0;
  743. bindRequest->MaxRecvFrag = bindRequest->MaxXmitFrag = LE16(5840);
  744. bindRequest->NumCtxItems = LE32(ctxItems);
  745. // data that is identical in all Ctx items
  746. for (i = 0; i < ctxItems; i++)
  747. {
  748. bindRequest->CtxItems[i].ContextId = LE16(i);
  749. bindRequest->CtxItems[i].InterfaceVerMajor = LE16(1);
  750. bindRequest->CtxItems[i].InterfaceVerMinor = 0;
  751. bindRequest->CtxItems[i].NumTransItems = LE16(1);
  752. bindRequest->CtxItems[i].SyntaxVersion = i ? LE32(1) : LE32(2);
  753. memcpy(&bindRequest->CtxItems[i].InterfaceUUID, InterfaceUuid, sizeof(GUID));
  754. }
  755. memcpy(&bindRequest->CtxItems[0].TransferSyntax, TransferSyntaxNDR32, sizeof(GUID));
  756. if (UseRpcNDR64 && packetType == RPC_PT_BIND_REQ)
  757. {
  758. memcpy(&bindRequest->CtxItems[++ctxIndex].TransferSyntax, TransferSyntaxNDR64, sizeof(GUID));
  759. CtxNDR64 = ctxIndex;
  760. }
  761. if (UseRpcBTFN && packetType == RPC_PT_BIND_REQ)
  762. {
  763. memcpy(&bindRequest->CtxItems[++ctxIndex].TransferSyntax, BindTimeFeatureNegotiation, sizeof(GUID));
  764. CtxBTFN = ctxIndex;
  765. }
  766. if (!_send(sock, _Request, (int)rpcBindSize))
  767. {
  768. printerrorf("\nFatal: Sending RPC bind request failed\n");
  769. return RPC_S_COMM_FAILURE;
  770. }
  771. if (!_recv(sock, &ResponseHeader, sizeof(RPC_HEADER)))
  772. {
  773. printerrorf("\nFatal: Did not receive a response from server\n");
  774. return RPC_S_COMM_FAILURE;
  775. }
  776. if ((status = checkRpcResponseHeader
  777. (
  778. &ResponseHeader,
  779. RequestHeader,
  780. packetType == RPC_PT_BIND_REQ ? RPC_PT_BIND_ACK : RPC_PT_ALTERCONTEXT_ACK,
  781. &printerrorf
  782. )))
  783. {
  784. return status;
  785. }
  786. bindResponse = (RPC_BIND_RESPONSE*)vlmcsd_malloc(LE16(ResponseHeader.FragLength) - sizeof(RPC_HEADER));
  787. BYTE* bindResponseBytePtr = (BYTE*)bindResponse;
  788. if (!_recv(sock, bindResponse, LE16(ResponseHeader.FragLength) - sizeof(RPC_HEADER)))
  789. {
  790. printerrorf("\nFatal: Incomplete RPC bind acknowledgement received\n");
  791. free(bindResponseBytePtr);
  792. return RPC_S_COMM_FAILURE;
  793. }
  794. else
  795. {
  796. /*
  797. * checking, whether a bind or alter context response is as expected.
  798. * This check is very strict and checks whether a KMS emulator behaves exactly the same way
  799. * as Microsoft's RPC does.
  800. */
  801. status = 0;
  802. if (bindResponse->SecondaryAddressLength < LE16(3))
  803. bindResponse = (RPC_BIND_RESPONSE*)(bindResponseBytePtr - 4);
  804. if (bindResponse->NumResults != bindRequest->NumCtxItems)
  805. {
  806. printerrorf("\nFatal: Expected %u CTX items but got %u\n",
  807. (uint32_t)LE32(bindRequest->NumCtxItems),
  808. (uint32_t)LE32(bindResponse->NumResults)
  809. );
  810. status = RPC_S_PROTOCOL_ERROR;
  811. }
  812. for (i = 0; i < ctxItems; i++)
  813. {
  814. const char* transferSyntaxName =
  815. i == CtxBTFN ? "BTFN" : i == CtxNDR64 ? "NDR64" : "NDR32";
  816. if (bindResponse->Results[i].AckResult == RPC_BIND_NACK) // transfer syntax was declined
  817. {
  818. if (!IsNullGuid((BYTE*)&bindResponse->Results[i].TransferSyntax))
  819. {
  820. printerrorf(
  821. "\nWarning: Rejected transfer syntax %s did not return NULL Guid\n",
  822. transferSyntaxName
  823. );
  824. }
  825. if (bindResponse->Results[i].SyntaxVersion)
  826. {
  827. printerrorf(
  828. "\nWarning: Rejected transfer syntax %s did not return syntax version 0 but %u\n",
  829. transferSyntaxName,
  830. LE32(bindResponse->Results[i].SyntaxVersion)
  831. );
  832. }
  833. if (bindResponse->Results[i].AckReason == RPC_ABSTRACTSYNTAX_UNSUPPORTED)
  834. {
  835. printerrorf(
  836. "\nWarning: Transfer syntax %s does not support KMS activation\n",
  837. transferSyntaxName
  838. );
  839. }
  840. else if (bindResponse->Results[i].AckReason != RPC_SYNTAX_UNSUPPORTED)
  841. {
  842. printerrorf(
  843. "\nWarning: Rejected transfer syntax %s did not return ack reason RPC_SYNTAX_UNSUPPORTED\n",
  844. transferSyntaxName
  845. );
  846. }
  847. continue;
  848. }
  849. if (i == CtxBTFN) // BTFN
  850. {
  851. if (bindResponse->Results[i].AckResult != RPC_BIND_ACK)
  852. {
  853. printerrorf("\nWarning: BTFN did not respond with RPC_BIND_ACK or RPC_BIND_NACK\n");
  854. }
  855. if (bindResponse->Results[i].AckReason != LE16(3))
  856. {
  857. printerrorf("\nWarning: BTFN did not return expected feature mask 0x3 but 0x%X\n", (unsigned int)LE16(bindResponse->Results[i].AckReason));
  858. }
  859. if (verbose) printf("... BTFN ");
  860. RpcFlags.HasBTFN = TRUE;
  861. continue;
  862. }
  863. // NDR32 or NDR64 Ctx
  864. if (bindResponse->Results[i].AckResult != RPC_BIND_ACCEPT)
  865. {
  866. printerrorf(
  867. "\nFatal: transfer syntax %s returned an invalid status, neither RPC_BIND_ACCEPT nor RPC_BIND_NACK\n",
  868. transferSyntaxName
  869. );
  870. status = RPC_S_PROTOCOL_ERROR;
  871. }
  872. if (!IsEqualGUID(&bindResponse->Results[i].TransferSyntax, &bindRequest->CtxItems[i].TransferSyntax))
  873. {
  874. printerrorf(
  875. "\nFatal: Transfer syntax of RPC bind request and response does not match\n"
  876. );
  877. status = RPC_S_UNSUPPORTED_TRANS_SYN;
  878. }
  879. if (bindResponse->Results[i].SyntaxVersion != bindRequest->CtxItems[i].SyntaxVersion)
  880. {
  881. printerrorf("\nFatal: Expected transfer syntax version %u for %s but got %u\n",
  882. (uint32_t)LE32(bindRequest->CtxItems[0].SyntaxVersion),
  883. transferSyntaxName,
  884. (uint32_t)LE32(bindResponse->Results[0].SyntaxVersion)
  885. );
  886. status = RPC_S_UNSUPPORTED_TRANS_SYN;
  887. }
  888. // The ack reason field is actually undefined here but Microsoft sets this to 0
  889. if (bindResponse->Results[i].AckReason != 0)
  890. {
  891. printerrorf(
  892. "\nWarning: Ack reason should be 0 but is %u\n",
  893. LE16(bindResponse->Results[i].AckReason)
  894. );
  895. }
  896. if (!status)
  897. {
  898. if (i == CtxNDR64)
  899. {
  900. RpcFlags.HasNDR64 = TRUE;
  901. if (verbose) printf("... NDR64 ");
  902. }
  903. if (!i)
  904. {
  905. RpcFlags.HasNDR32 = TRUE;
  906. if (verbose) printf("... NDR32 ");
  907. }
  908. }
  909. }
  910. }
  911. free(bindResponseBytePtr);
  912. if (!RpcFlags.HasNDR64 && !RpcFlags.HasNDR32)
  913. {
  914. printerrorf("\nFatal: Could neither negotiate NDR32 nor NDR64 with the RPC server\n");
  915. status = RPC_S_NO_PROTSEQS;
  916. }
  917. return status;
  918. }
  919. RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose)
  920. {
  921. firstPacketSent = FALSE;
  922. RpcFlags.mask = 0;
  923. RpcStatus status =
  924. rpcBindOrAlterClientContext(sock, RPC_PT_BIND_REQ, verbose);
  925. if (status) return status;
  926. if (!RpcFlags.HasNDR32)
  927. status = rpcBindOrAlterClientContext(sock, RPC_PT_ALTERCONTEXT_REQ, verbose);
  928. return status;
  929. }
  930. #endif // USE_MSRPC