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.

144 lines
3.5 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // VSASink.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file defines the class VSASink.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 01/24/1998 Original version.
  16. // 08/11/1998 Packing functions moved to iasutil.
  17. // 08/13/1998 IASTL integration.
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. #include <radcommon.h>
  21. #include <iasutil.h>
  22. #include <iastlutl.h>
  23. #include <sdoias.h>
  24. #include <radutil.h>
  25. #include <vsasink.h>
  26. ///////////////////////////////////////////////////////////////////////////////
  27. //
  28. // METHOD
  29. //
  30. // VSASink::VSASink
  31. //
  32. // DESCRIPTION
  33. //
  34. // Constructor.
  35. //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. VSASink::VSASink(IAttributesRaw* request) throw ()
  38. : raw(request),
  39. bufferLength(0),
  40. currentVendor(NO_VENDOR)
  41. { }
  42. ///////////////////////////////////////////////////////////////////////////////
  43. //
  44. // METHOD
  45. //
  46. // VSASink::operator<<
  47. //
  48. // DESCRIPTION
  49. //
  50. // Inserts a SubVSA into the sink.
  51. //
  52. ///////////////////////////////////////////////////////////////////////////////
  53. VSASink& VSASink::operator<<(const SubVSA& vsa)
  54. {
  55. _ASSERT(vsa.vendorID != NO_VENDOR);
  56. // Get the size of the sub VSA on the wire.
  57. ULONG vsaLength = RadiusUtil::getEncodedSize(*vsa.attr) + 2;
  58. if (vsaLength > MAX_SUBVSA_LENGTH) { _com_issue_error(E_INVALIDARG); }
  59. // If we're out of room or the vendors and flags don't match, then ...
  60. if (bufferLength + vsaLength > sizeof(buffer) ||
  61. currentVendor != vsa.vendorID ||
  62. currentFlags != vsa.attr->dwFlags)
  63. {
  64. // ... we have to flush the buffer and start a new attribute.
  65. flush();
  66. // Write the vendor ID at the head of the attribute.
  67. IASInsertDWORD(buffer, vsa.vendorID);
  68. bufferLength = 4;
  69. // Save the new vendor and flags.
  70. currentVendor = vsa.vendorID;
  71. currentFlags = vsa.attr->dwFlags;
  72. }
  73. // Find the next available byte.
  74. PBYTE next = buffer + bufferLength;
  75. // Pack the vendor type.
  76. *next++ = vsa.vendorType;
  77. // Pack the vendor length.
  78. *next++ = (BYTE)vsaLength;
  79. // Encode the value.
  80. RadiusUtil::encode(next, *vsa.attr);
  81. // Update the buffer length.
  82. bufferLength += vsaLength;
  83. return *this;
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////
  86. //
  87. // METHOD
  88. //
  89. // VSASink::flush
  90. //
  91. // DESCRIPTION
  92. //
  93. // Flush the sink. This should be called after all SubVSA's have been
  94. // inserted to ensure that everything has been inserted into the request.
  95. //
  96. ///////////////////////////////////////////////////////////////////////////////
  97. void VSASink::flush() throw (_com_error)
  98. {
  99. // Is there anything in the buffer?
  100. if (bufferLength > 0)
  101. {
  102. //////////
  103. // Allocate an attribute for the VSA.
  104. //////////
  105. IASTL::IASAttribute attr(true);
  106. //////////
  107. // Initialize the fields.
  108. //////////
  109. attr->dwId = RADIUS_ATTRIBUTE_VENDOR_SPECIFIC;
  110. attr->dwFlags = currentFlags;
  111. attr.setOctetString(bufferLength, buffer);
  112. //////////
  113. // Load the attribute into the request and reset the buffer.
  114. //////////
  115. attr.store(raw);
  116. currentVendor = NO_VENDOR;
  117. bufferLength = 0;
  118. }
  119. }