From: Nikos Mavrogiannopoulos Date: Wed, 23 Jan 2013 22:24:59 +0000 (+0100) Subject: Added gnutls_sbuf_getdelim() and getline(). X-Git-Tag: gnutls_3_1_7~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d70e6fddecaa31267521ff05a659e5dee30f3c1;p=thirdparty%2Fgnutls.git Added gnutls_sbuf_getdelim() and getline(). --- diff --git a/NEWS b/NEWS index 15ad84a9bd..6b1820b80c 100644 --- a/NEWS +++ b/NEWS @@ -30,7 +30,10 @@ gnutls_record_get_random_padding_status: Added gnutls_sbuf_deinit: Added gnutls_sbuf_init: Added gnutls_sbuf_flush: Added -gnutls_sbuf_queue: Added +gnutls_sbuf_write: Added +gnutls_sbuf_getdelim: Added +gnutls_sbuf_read: Added +gnutls_sbuf_handshake: Added gnutls_x509_crt_set_dn: Added gnutls_x509_crt_set_issuer_dn: Added gnutls_x509_crq_set_dn: Added diff --git a/lib/Makefile.am b/lib/Makefile.am index 816b3c5271..70d23f3a73 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -78,7 +78,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \ gnutls_rsa_export.c gnutls_helper.c gnutls_supplemental.c \ random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c \ gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \ - crypto-backend.c verify-tofu.c pin.c tpm.c sbuf.c + crypto-backend.c verify-tofu.c pin.c tpm.c sbuf.c sbuf_getline.c if ENABLE_PKCS11 COBJECTS += pkcs11.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c diff --git a/lib/includes/gnutls/sbuf.h b/lib/includes/gnutls/sbuf.h index 2f755cf55b..cb9100d0eb 100644 --- a/lib/includes/gnutls/sbuf.h +++ b/lib/includes/gnutls/sbuf.h @@ -40,6 +40,11 @@ ssize_t gnutls_sbuf_flush (gnutls_sbuf_t sb); int gnutls_sbuf_handshake(gnutls_sbuf_t sb); ssize_t gnutls_sbuf_read(gnutls_sbuf_t sb, void* data, size_t data_size); +ssize_t +gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter); + +#define gnutls_sbuf_getline(sbuf, ptr, n) gnutls_sbuf_getdelim(sbuf, ptr, n, '\n') + #define GNUTLS_SBUF_QUEUE_FLUSHES 1 int gnutls_sbuf_init (gnutls_sbuf_t * sb, gnutls_session_t session, unsigned int flags); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 8df827aff2..ab8a6ce7d2 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -880,7 +880,7 @@ GNUTLS_3_1_0 { gnutls_sbuf_deinit; gnutls_sbuf_init; gnutls_sbuf_flush; - gnutls_sbuf_queue; + gnutls_sbuf_read; gnutls_x509_crt_set_dn; gnutls_x509_crq_set_dn; gnutls_x509_crt_set_issuer_dn; @@ -889,6 +889,8 @@ GNUTLS_3_1_0 { gnutls_range_send_message; gnutls_record_set_max_empty_records; gnutls_record_send_range; + gnutls_sbuf_getdelim; + gnutls_sbuf_write; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/lib/sbuf.c b/lib/sbuf.c index 8871cee854..62bbd10768 100644 --- a/lib/sbuf.c +++ b/lib/sbuf.c @@ -5,7 +5,7 @@ * * This file is part of GnuTLS. * - * The libdane library is free software; you can redistribute it + * The gnutls library is free software; you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. @@ -23,14 +23,9 @@ #include #include #include -#include #include -struct gnutls_sbuf_st { - gnutls_session_t session; - gnutls_buffer_st buf; - unsigned int flags; -}; +#include /** * gnutls_init: diff --git a/lib/sbuf.h b/lib/sbuf.h new file mode 100644 index 0000000000..70e8939791 --- /dev/null +++ b/lib/sbuf.h @@ -0,0 +1,12 @@ +#ifndef SBUF_H +# define SBUF_H + +#include + +struct gnutls_sbuf_st { + gnutls_session_t session; + gnutls_buffer_st buf; + unsigned int flags; +}; + +#endif diff --git a/lib/sbuf_getline.c b/lib/sbuf_getline.c new file mode 100644 index 0000000000..932d9dc96b --- /dev/null +++ b/lib/sbuf_getline.c @@ -0,0 +1,127 @@ +/* getdelim.c --- Implementation of replacement getdelim function. + * Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2012 Free Software + * Foundation, Inc. + * + * This file is part of GnuTLS. + * + * The gnutls library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + */ + +/* Ported from glibc by Simon Josefsson. */ + +#include +#include +#include +#include + +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +/** + * gnutls_sbuf_get_delim: + * @sb: is a #gnutls_sbuf_t structure. + * @lineptr: a pointer. + * @n: The size of @lineptr. + * @delimiter: The delimiter to stop reading at. + * + * Read up to (and including) a @delimiter from &sb into *LINEPTR (and + * NUL-terminate it). @lineptr is a pointer returned from gnutls_malloc() + * (or %NULL), pointing to @n characters of space. It is realloc'ed as + * necessary. + * + * Only fatal errors are returned by this function. + * + * Returns the number of characters read (not including + * the null terminator), or a negative error code on error. + * + * Since: 3.1.7 + **/ +ssize_t +gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter) +{ + ssize_t result; + size_t cur_len = 0; + + if (lineptr == NULL || n == NULL || sbuf == NULL) + { + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + } + + if (*lineptr == NULL || *n == 0) + { + char *new_lineptr; + *n = 120; + new_lineptr = (char *) gnutls_realloc (*lineptr, *n); + if (new_lineptr == NULL) + { + result = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto fail; + } + *lineptr = new_lineptr; + } + + for (;;) + { + char c; + + result = gnutls_sbuf_read(sbuf, &c, 1); + if (result < 0) + { + gnutls_assert(); + break; + } + + /* Make enough space for len+1 (for final NUL) bytes. */ + if (cur_len + 1 >= *n) + { + size_t needed_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed = 2 * *n + 1; /* Be generous. */ + char *new_lineptr; + + if (needed_max < needed) + needed = needed_max; + if (cur_len + 1 >= needed) + { + result = gnutls_assert_val(GNUTLS_E_LARGE_PACKET); + goto fail; + } + + new_lineptr = (char *) gnutls_realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto fail; + } + + *lineptr = new_lineptr; + *n = needed; + } + + (*lineptr)[cur_len] = c; + cur_len++; + + if (c == delimiter) + break; + } + (*lineptr)[cur_len] = '\0'; + + if (cur_len != 0) + result = cur_len; + +fail: + + return result; +} diff --git a/tests/mini-sbuf.c b/tests/mini-sbuf.c index 5981c14a76..5804a0d54f 100644 --- a/tests/mini-sbuf.c +++ b/tests/mini-sbuf.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "eagain-common.h" #include "utils.h" @@ -47,6 +48,9 @@ tls_log_func (int level, const char *str) static unsigned char server_buf[MAX_BUF]; static unsigned char client_buf[MAX_BUF]; +#define LINE1 "hello there people\n" +#define LINE2 "how are you doing today, all well?\n" + void doit (void) { @@ -64,6 +68,8 @@ doit (void) /* Need to enable anonymous KX specifically. */ int ret; ssize_t left, spos, cpos; + char *abuf = NULL; + size_t abuf_size = 0; /* General init. */ gnutls_global_init (); @@ -112,20 +118,23 @@ doit (void) { if (left > SEND_SIZE) { - ret = gnutls_sbuf_queue(ssbuf, server_buf+spos, SEND_SIZE); - left -= SEND_SIZE; - spos += SEND_SIZE; + ret = gnutls_sbuf_write(ssbuf, server_buf+spos, SEND_SIZE); } else { - gnutls_sbuf_queue(ssbuf, server_buf+spos, left); + ret = gnutls_sbuf_write(ssbuf, server_buf+spos, left); + } + + if (ret >= 0) + { + left -= ret; + spos += ret; ret = gnutls_sbuf_flush(ssbuf); - left = 0; } - + if (ret < 0) { - fail("Error sending\n"); + fail("Error sending %s\n", gnutls_strerror(ret)); abort(); } @@ -137,7 +146,7 @@ doit (void) if (ret < 0) { - fail("Error sending\n"); + fail("Error receiving %s\n", gnutls_strerror(ret)); abort(); } } @@ -148,6 +157,35 @@ doit (void) fail("Data do not match!\n"); abort(); } + + gnutls_record_send(client, LINE1, sizeof(LINE1)-1); + gnutls_record_send(client, LINE2, sizeof(LINE2)-1); + + ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size); + if (ret < 0) + { + fail("sbuf_getline error %s!\n", gnutls_strerror(ret)); + abort(); + } + + if (strcmp(abuf, LINE1) != 0) + { + fail("LINE1 Data do not match!\n"); + abort(); + } + + ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size); + if (ret < 0) + { + fail("sbuf_getline error %s!\n", gnutls_strerror(ret)); + abort(); + } + + if (strcmp(abuf, LINE2) != 0) + { + fail("LINE2 Data do not match!\n"); + abort(); + } gnutls_bye (client, GNUTLS_SHUT_RDWR); gnutls_bye (server, GNUTLS_SHUT_RDWR);