Skip to content

Commit a1f06f3

Browse files
parazydbagder
authored andcommitted
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
1 parent be8c94d commit a1f06f3

5 files changed

Lines changed: 62 additions & 0 deletions

File tree

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5111,6 +5111,9 @@ if test "x$CURL_DISABLE_TFTP" != "x1"; then
51115111
fi
51125112
if test "x$CURL_DISABLE_GOPHER" != "x1"; then
51135113
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER"
5114+
if test "x$SSL_ENABLED" = "x1"; then
5115+
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHERS"
5116+
fi
51145117
fi
51155118
if test "x$CURL_DISABLE_MQTT" != "x1"; then
51165119
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT"

lib/gopher.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "gopher.h"
3434
#include "select.h"
3535
#include "strdup.h"
36+
#include "vtls/vtls.h"
3637
#include "url.h"
3738
#include "escape.h"
3839
#include "warnless.h"
@@ -46,6 +47,10 @@
4647
*/
4748

4849
static CURLcode gopher_do(struct connectdata *conn, bool *done);
50+
#ifdef USE_SSL
51+
static CURLcode gopher_connect(struct connectdata *conn, bool *done);
52+
static CURLcode gopher_connecting(struct connectdata *conn, bool *done);
53+
#endif
4954

5055
/*
5156
* Gopher protocol handler.
@@ -75,6 +80,46 @@ const struct Curl_handler Curl_handler_gopher = {
7580
PROTOPT_NONE /* flags */
7681
};
7782

83+
#ifdef USE_SSL
84+
const struct Curl_handler Curl_handler_gophers = {
85+
"GOPHERS", /* scheme */
86+
ZERO_NULL, /* setup_connection */
87+
gopher_do, /* do_it */
88+
ZERO_NULL, /* done */
89+
ZERO_NULL, /* do_more */
90+
gopher_connect, /* connect_it */
91+
gopher_connecting, /* connecting */
92+
ZERO_NULL, /* doing */
93+
ZERO_NULL, /* proto_getsock */
94+
ZERO_NULL, /* doing_getsock */
95+
ZERO_NULL, /* domore_getsock */
96+
ZERO_NULL, /* perform_getsock */
97+
ZERO_NULL, /* disconnect */
98+
ZERO_NULL, /* readwrite */
99+
ZERO_NULL, /* connection_check */
100+
PORT_GOPHER, /* defport */
101+
CURLPROTO_GOPHER, /* protocol */
102+
CURLPROTO_GOPHER, /* family */
103+
PROTOPT_SSL /* flags */
104+
};
105+
106+
static CURLcode gopher_connect(struct connectdata *conn, bool *done)
107+
{
108+
(void)conn;
109+
(void)done;
110+
return CURLE_OK;
111+
}
112+
113+
static CURLcode gopher_connecting(struct connectdata *conn, bool *done)
114+
{
115+
CURLcode result = Curl_ssl_connect(conn, FIRSTSOCKET);
116+
if(result)
117+
connclose(conn, "Failed TLS connection");
118+
*done = TRUE;
119+
return result;
120+
}
121+
#endif
122+
78123
static CURLcode gopher_do(struct connectdata *conn, bool *done)
79124
{
80125
CURLcode result = CURLE_OK;
@@ -127,6 +172,11 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
127172
k = curlx_uztosz(len);
128173

129174
for(;;) {
175+
/* Break out of the loop if the selector is empty because OpenSSL and/or
176+
LibreSSL fail with errno 0 if this is the case. */
177+
if(strlen(sel) < 1)
178+
break;
179+
130180
result = Curl_write(conn, sockfd, sel, k, &amount);
131181
if(!result) { /* Which may not have written it all! */
132182
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);

lib/gopher.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
#ifndef CURL_DISABLE_GOPHER
2626
extern const struct Curl_handler Curl_handler_gopher;
27+
#ifdef USE_SSL
28+
extern const struct Curl_handler Curl_handler_gophers;
29+
#endif
2730
#endif
2831

2932
#endif /* HEADER_CURL_GOPHER_H */

lib/url.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ static const struct Curl_handler * const protocols[] = {
251251

252252
#ifndef CURL_DISABLE_GOPHER
253253
&Curl_handler_gopher,
254+
#ifdef USE_SSL
255+
&Curl_handler_gophers,
256+
#endif
254257
#endif
255258

256259
#ifdef USE_LIBRTMP

lib/version.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ static const char * const protocols[] = {
274274
#ifndef CURL_DISABLE_GOPHER
275275
"gopher",
276276
#endif
277+
#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)
278+
"gophers",
279+
#endif
277280
#ifndef CURL_DISABLE_HTTP
278281
"http",
279282
#endif

0 commit comments

Comments
 (0)