diff --git a/http.c b/http.c index afb2c446..6b451196 100644 --- a/http.c +++ b/http.c @@ -132,6 +132,68 @@ void buf_append_bytes(struct oc_text_buf *buf, const void *bytes, int len) buf->data[buf->pos] = 0; } +int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8) +{ + int len = 0; + unsigned char c; + unsigned long utfchar; + int min; + int nr_extra; + + /* Ick. Now I'm implementing my own UTF8 handling too. Perhaps it's + time to bite the bullet and start requiring something like glib? */ + while (*utf8) { + c = *(utf8++); + if (c < 128) { + utfchar = c; + nr_extra = 0; + min = 0; + } else if ((c & 0xe0) == 0xc0) { + utfchar = c & 0x1f; + nr_extra = 1; + min = 0x80; + } else if ((c & 0xf0) == 0xe0) { + utfchar = c & 0x0f; + nr_extra = 2; + min = 0x800; + } else if ((c & 0xf8) == 0xf0) { + utfchar = c & 0x07; + nr_extra = 3; + min = 0x10000; + } else { + return -EINVAL; + } + + while (nr_extra--) { + c = *(utf8++); + if ((c & 0xc0) != 0x80) + return -EINVAL; + utfchar <<= 6; + utfchar |= (c & 0x3f); + } + if (utfchar > 0x10ffff || utfchar < min) + return -EINVAL; + + if (utfchar >= 0x10000) { + utfchar -= 0x10000; + if (buf_ensure_space(buf, 4)) + return -ENOMEM; + buf->data[buf->pos++] = (utfchar >> 10) & 0xff; + buf->data[buf->pos++] = 0xd8 | ((utfchar >> 18) & 3); + buf->data[buf->pos++] = utfchar & 0xff; + buf->data[buf->pos++] = 0xdc | ((utfchar >> 8) & 3); + len += 4; + } else { + if (buf_ensure_space(buf, 2)) + return -ENOMEM; + buf->data[buf->pos++] = utfchar & 0xff; + buf->data[buf->pos++] = utfchar >> 8; + len += 2; + } + } + return len; +} + int buf_error(struct oc_text_buf *buf) { return buf ? buf->error : -ENOMEM; diff --git a/ntlm.c b/ntlm.c index 95a7ee2e..0886001e 100644 --- a/ntlm.c +++ b/ntlm.c @@ -736,68 +736,6 @@ static void setup_schedule (const unsigned char *key_56, DES_KS ks) deskey (ks, key, 0); } -static int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8) -{ - int len = 0; - unsigned char c; - unsigned long utfchar; - int min; - int nr_extra; - - /* Ick. Now I'm implementing my own UTF8 handling too. Perhaps it's - time to bite the bullet and start requiring something like glib? */ - while (*utf8) { - c = *(utf8++); - if (c < 128) { - utfchar = c; - nr_extra = 0; - min = 0; - } else if ((c & 0xe0) == 0xc0) { - utfchar = c & 0x1f; - nr_extra = 1; - min = 0x80; - } else if ((c & 0xf0) == 0xe0) { - utfchar = c & 0x0f; - nr_extra = 2; - min = 0x800; - } else if ((c & 0xf8) == 0xf0) { - utfchar = c & 0x07; - nr_extra = 3; - min = 0x10000; - } else { - return -EINVAL; - } - - while (nr_extra--) { - c = *(utf8++); - if ((c & 0xc0) != 0x80) - return -EINVAL; - utfchar <<= 6; - utfchar |= (c & 0x3f); - } - if (utfchar > 0x10ffff || utfchar < min) - return -EINVAL; - - if (utfchar >= 0x10000) { - utfchar -= 0x10000; - if (buf_ensure_space(buf, 4)) - return -ENOMEM; - buf->data[buf->pos++] = (utfchar >> 10) & 0xff; - buf->data[buf->pos++] = 0xd8 | ((utfchar >> 18) & 3); - buf->data[buf->pos++] = utfchar & 0xff; - buf->data[buf->pos++] = 0xdc | ((utfchar >> 8) & 3); - len += 4; - } else { - if (buf_ensure_space(buf, 2)) - return -ENOMEM; - buf->data[buf->pos++] = utfchar & 0xff; - buf->data[buf->pos++] = utfchar >> 8; - len += 2; - } - } - return len; -} - #define LM_PASSWORD_MAGIC "\x4B\x47\x53\x21\x40\x23\x24\x25" \ "\x4B\x47\x53\x21\x40\x23\x24\x25" \ "\x00\x00\x00\x00\x00" diff --git a/openconnect-internal.h b/openconnect-internal.h index 819dbd89..5029db3c 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -612,6 +612,7 @@ void __attribute__ ((format (printf, 2, 3))) buf_append(struct oc_text_buf *buf, const char *fmt, ...); void buf_append_bytes(struct oc_text_buf *buf, const void *bytes, int len); void buf_append_base64(struct oc_text_buf *buf, const void *bytes, int len); +int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8); void *openconnect_base64_decode(int *len, const char *in); void buf_truncate(struct oc_text_buf *buf); void buf_append_urlencoded(struct oc_text_buf *buf, char *str);