#include "replace.h"
-#include "libcli/util/ntstatus.h"
#include "util_str_hex.h"
+#include "lib/util/data_blob.h"
+#include "librpc/gen_ndr/misc.h"
-NTSTATUS read_hex_bytes(const char *s, uint hexchars, uint64_t *dest)
+static bool hex_uint16(const char *in, uint16_t *out)
{
- uint64_t x = 0;
- uint i;
- char c;
-
- if ((hexchars & 1) || hexchars > 16) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- for (i = 0; i < hexchars; i++) {
- x <<= 4;
- c = s[i];
- if (c >= '0' && c <= '9') {
- x += c - '0';
- }
- else if (c >= 'a' && c <= 'f') {
- x += c - 'a' + 10;
- }
- else if (c >= 'A' && c <= 'F') {
- x += c - 'A' + 10;
- }
- else {
- /* BAD character (including '\0') */
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- *dest = x;
- return NT_STATUS_OK;
+ uint8_t hi=0, lo=0;
+ bool ok = hex_byte(in, &hi) && hex_byte(in+2, &lo);
+ *out = (((uint16_t)hi)<<8) + lo;
+ return ok;
}
+bool hex_uint32(const char *in, uint32_t *out)
+{
+ uint16_t hi=0, lo=0;
+ bool ok = hex_uint16(in, &hi) && hex_uint16(in+4, &lo);
+ *out = (((uint32_t)hi)<<16) + lo;
+ return ok;
+}
-NTSTATUS parse_guid_string(const char *s,
- uint32_t *time_low,
- uint32_t *time_mid,
- uint32_t *time_hi_and_version,
- uint32_t clock_seq[2],
- uint32_t node[6])
+bool parse_guid_string(const char *s, struct GUID *guid)
{
- uint64_t tmp;
- NTSTATUS status;
+ bool ok;
int i;
/* "e12b56b6-0a95-11d1-adbb-00c04fd8d5cd"
| | | | |
| \_______________ time_mid
\_____________________ time_low
*/
- status = read_hex_bytes(s, 8, &tmp);
- if (!NT_STATUS_IS_OK(status) || s[8] != '-') {
- return NT_STATUS_INVALID_PARAMETER;
+
+ ok = hex_uint32(s, &guid->time_low);
+ if (!ok || (s[8] != '-')) {
+ return false;
}
- *time_low = tmp;
s += 9;
- status = read_hex_bytes(s, 4, &tmp);
- if (!NT_STATUS_IS_OK(status) || s[4] != '-') {
- return NT_STATUS_INVALID_PARAMETER;
+ ok = hex_uint16(s, &guid->time_mid);
+ if (!ok || (s[4] != '-')) {
+ return false;
}
- *time_mid = tmp;
s += 5;
- status = read_hex_bytes(s, 4, &tmp);
- if (!NT_STATUS_IS_OK(status) || s[4] != '-') {
- return NT_STATUS_INVALID_PARAMETER;
+ ok = hex_uint16(s, &guid->time_hi_and_version);
+ if (!ok || (s[4] != '-')) {
+ return false;
}
- *time_hi_and_version = tmp;
s += 5;
- for (i = 0; i < 2; i++) {
- status = read_hex_bytes(s, 2, &tmp);
- if (!NT_STATUS_IS_OK(status)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- clock_seq[i] = tmp;
- s += 2;
- }
- if (s[0] != '-') {
- return NT_STATUS_INVALID_PARAMETER;
+ ok = hex_byte(s, &guid->clock_seq[0]) &&
+ hex_byte(s+2, &guid->clock_seq[1]);
+ if (!ok || (s[4] != '-')) {
+ return false;
}
-
- s++;
+ s += 5;
for (i = 0; i < 6; i++) {
- status = read_hex_bytes(s, 2, &tmp);
- if (!NT_STATUS_IS_OK(status)) {
- return NT_STATUS_INVALID_PARAMETER;
+ ok = hex_byte(s, &guid->node[i]);
+ if (!ok) {
+ return false;
}
- node[i] = tmp;
s += 2;
}
- return NT_STATUS_OK;
+ return true;
}
-#include "../libcli/util/ntstatus.h"
+#include "replace.h"
-NTSTATUS read_hex_bytes(const char *s, uint hexchars, uint64_t *dest);
-
-NTSTATUS parse_guid_string(const char *s,
- uint32_t *time_low,
- uint32_t *time_mid,
- uint32_t *time_hi_and_version,
- uint32_t clock_seq[2],
- uint32_t node[6]);
+bool hex_uint32(const char *in, uint32_t *out);
+struct GUID;
+bool parse_guid_string(const char *s, struct GUID *guid);
_PUBLIC_ bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id)
{
- size_t i;
- uint32_t time_low;
- uint32_t time_mid, time_hi_and_version;
- uint32_t clock_seq[2];
- uint32_t node[6];
- uint64_t if_version;
- NTSTATUS status;
+ bool ok;
- status = parse_guid_string(s,
- &time_low,
- &time_mid,
- &time_hi_and_version,
- clock_seq,
- node);
-
- if (!NT_STATUS_IS_OK(status)) {
+ ok = parse_guid_string(s, &id->uuid);
+ if (!ok) {
return false;
}
return false;
}
- status = read_hex_bytes(s + 39, 8, &if_version);
-
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
-
- id->uuid.time_low = time_low;
- id->uuid.time_mid = time_mid;
- id->uuid.time_hi_and_version = time_hi_and_version;
- id->uuid.clock_seq[0] = clock_seq[0];
- id->uuid.clock_seq[1] = clock_seq[1];
- for (i=0; i<6; i++) {
- id->uuid.node[i] = node[i];
- }
- id->if_version = (uint32_t)if_version;
-
- return true;
+ ok = hex_uint32(s+39, &id->if_version);
+ return ok;
}
*/
_PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
{
- NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
- uint32_t time_low = 0;
- uint32_t time_mid = 0;
- uint32_t time_hi_and_version = 0;
- uint32_t clock_seq[2] = {0};
- uint32_t node[6] = {0};
- uint8_t buf16[16] = {0};
-
- DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16));
- int i;
+ bool ok;
if (s->data == NULL) {
return NT_STATUS_INVALID_PARAMETER;
}
- switch(s->length) {
- case 36:
- {
- status = parse_guid_string((char *)s->data,
- &time_low,
- &time_mid,
- &time_hi_and_version,
- clock_seq,
- node);
- break;
+ if (s->length == 36) {
+ ok = parse_guid_string((char *)s->data, guid);
+ return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
}
- case 38:
- {
+
+ if (s->length == 38) {
if (s->data[0] != '{' || s->data[37] != '}') {
- break;
+ return NT_STATUS_INVALID_PARAMETER;
}
-
- status = parse_guid_string((char *)s->data + 1,
- &time_low,
- &time_mid,
- &time_hi_and_version,
- clock_seq,
- node);
- break;
+ ok = parse_guid_string((char *)s->data + 1, guid);
+ return ok ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER;
}
- case 32:
- {
+
+ if (s->length == 32) {
+ uint8_t buf16[16] = {0};
+ DATA_BLOB blob16 = { .data = buf16, .length = sizeof(buf16) };
size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
(const char *)s->data, s->length);
if (rlen != blob16.length) {
return NT_STATUS_INVALID_PARAMETER;
}
- s = &blob16;
- return GUID_from_ndr_blob(s, guid);
- }
- case 16:
- return GUID_from_ndr_blob(s, guid);
- default:
- status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ return GUID_from_ndr_blob(&blob16, guid);
}
- guid->time_low = time_low;
- guid->time_mid = time_mid;
- guid->time_hi_and_version = time_hi_and_version;
- guid->clock_seq[0] = clock_seq[0];
- guid->clock_seq[1] = clock_seq[1];
- for (i=0;i<6;i++) {
- guid->node[i] = node[i];
+ if (s->length == 16) {
+ return GUID_from_ndr_blob(s, guid);
}
- return NT_STATUS_OK;
+ return NT_STATUS_INVALID_PARAMETER;
}
/**