From 7a9b09feaa07f79522f7affccbca4236da2443e5 Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Fri, 9 Jul 2021 00:31:21 +0200 Subject: BIO_s_connect(): Enable BIO_gets() Fixes #16028 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/16030) --- crypto/bio/bss_conn.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'crypto/bio/bss_conn.c') diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index d146c97b82..8bc53548ca 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -42,6 +42,7 @@ typedef struct bio_connect_st { static int conn_write(BIO *h, const char *buf, int num); static int conn_read(BIO *h, char *buf, int size); static int conn_puts(BIO *h, const char *str); +static int conn_gets(BIO *h, char *buf, int size); static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int conn_new(BIO *h); static int conn_free(BIO *data); @@ -68,7 +69,7 @@ static const BIO_METHOD methods_connectp = { bread_conv, conn_read, conn_puts, - NULL, /* conn_gets, */ + conn_gets, conn_ctrl, conn_new, conn_free, @@ -595,6 +596,56 @@ static int conn_puts(BIO *bp, const char *str) return ret; } +int conn_gets(BIO *bio, char *buf, int size) +{ + BIO_CONNECT *data; + char *ptr = buf; + int ret = 0; + + if (buf == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (size <= 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + *buf = '\0'; + + if (bio == NULL || bio->ptr == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) + return ret; + } + + clear_socket_error(); + while (size-- > 1) { +# ifndef OPENSSL_NO_KTLS + if (BIO_get_ktls_recv(bio)) + ret = ktls_read_record(bio->num, ptr, 1); + else +# endif + ret = readsocket(bio->num, ptr, 1); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(bio); + else if (ret == 0) + bio->flags |= BIO_FLAGS_IN_EOF; + break; + } + if (*ptr++ == '\n') + break; + } + *ptr = '\0'; + return ret > 0 || (bio->flags & BIO_FLAGS_IN_EOF) != 0 ? ptr - buf : ret; +} + BIO *BIO_new_connect(const char *str) { BIO *ret; -- cgit v1.2.3