Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
gopher: Implement secure gopher protocol.
This commit introduces a "gophers" handler inside the gopher protocol if
USE_SSL is defined. This protocol is no different than the usual gopher
prococol, with the added TLS encapsulation upon connecting. The protocol
has been adopted in the gopher community, and many people have enabled
TLS in their gopher daemons like geomyidae(8), and clients, like clic(1)
and hurl(1).

I have not implemented test units for this protocol because my knowledge
of Perl is sub-par. However, for someone more knowledgeable it might be
fairly trivial, because the same test that tests the plain gopher
protocol can be used for "gophers" just by adding a TLS listener.

Signed-off-by: parazyd <parazyd@dyne.org>

Closes #6208
  • Loading branch information
parazyd authored and bagder committed Dec 15, 2020
1 parent be8c94d commit a1f06f3
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 0 deletions.
3 changes: 3 additions & 0 deletions configure.ac
Expand Up @@ -5111,6 +5111,9 @@ if test "x$CURL_DISABLE_TFTP" != "x1"; then
fi
if test "x$CURL_DISABLE_GOPHER" != "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER"
if test "x$SSL_ENABLED" = "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHERS"
fi
fi
if test "x$CURL_DISABLE_MQTT" != "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT"
Expand Down
50 changes: 50 additions & 0 deletions lib/gopher.c
Expand Up @@ -33,6 +33,7 @@
#include "gopher.h"
#include "select.h"
#include "strdup.h"
#include "vtls/vtls.h"
#include "url.h"
#include "escape.h"
#include "warnless.h"
Expand All @@ -46,6 +47,10 @@
*/

static CURLcode gopher_do(struct connectdata *conn, bool *done);
#ifdef USE_SSL
static CURLcode gopher_connect(struct connectdata *conn, bool *done);
static CURLcode gopher_connecting(struct connectdata *conn, bool *done);
#endif

/*
* Gopher protocol handler.
Expand Down Expand Up @@ -75,6 +80,46 @@ const struct Curl_handler Curl_handler_gopher = {
PROTOPT_NONE /* flags */
};

#ifdef USE_SSL
const struct Curl_handler Curl_handler_gophers = {
"GOPHERS", /* scheme */
ZERO_NULL, /* setup_connection */
gopher_do, /* do_it */
ZERO_NULL, /* done */
ZERO_NULL, /* do_more */
gopher_connect, /* connect_it */
gopher_connecting, /* connecting */
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
PORT_GOPHER, /* defport */
CURLPROTO_GOPHER, /* protocol */
CURLPROTO_GOPHER, /* family */
PROTOPT_SSL /* flags */
};

static CURLcode gopher_connect(struct connectdata *conn, bool *done)
{
(void)conn;
(void)done;
return CURLE_OK;
}

static CURLcode gopher_connecting(struct connectdata *conn, bool *done)
{
CURLcode result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(result)
connclose(conn, "Failed TLS connection");
*done = TRUE;
return result;
}
#endif

static CURLcode gopher_do(struct connectdata *conn, bool *done)
{
CURLcode result = CURLE_OK;
Expand Down Expand Up @@ -127,6 +172,11 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
k = curlx_uztosz(len);

for(;;) {
/* Break out of the loop if the selector is empty because OpenSSL and/or
LibreSSL fail with errno 0 if this is the case. */
if(strlen(sel) < 1)
break;

result = Curl_write(conn, sockfd, sel, k, &amount);
if(!result) { /* Which may not have written it all! */
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
Expand Down
3 changes: 3 additions & 0 deletions lib/gopher.h
Expand Up @@ -24,6 +24,9 @@

#ifndef CURL_DISABLE_GOPHER
extern const struct Curl_handler Curl_handler_gopher;
#ifdef USE_SSL
extern const struct Curl_handler Curl_handler_gophers;
#endif
#endif

#endif /* HEADER_CURL_GOPHER_H */
3 changes: 3 additions & 0 deletions lib/url.c
Expand Up @@ -251,6 +251,9 @@ static const struct Curl_handler * const protocols[] = {

#ifndef CURL_DISABLE_GOPHER
&Curl_handler_gopher,
#ifdef USE_SSL
&Curl_handler_gophers,
#endif
#endif

#ifdef USE_LIBRTMP
Expand Down
3 changes: 3 additions & 0 deletions lib/version.c
Expand Up @@ -274,6 +274,9 @@ static const char * const protocols[] = {
#ifndef CURL_DISABLE_GOPHER
"gopher",
#endif
#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)
"gophers",
#endif
#ifndef CURL_DISABLE_HTTP
"http",
#endif
Expand Down

0 comments on commit a1f06f3

Please sign in to comment.