## Gopher over TLS and spreading the revolution

Seamless encryption in the gopherspace!

    .-,          [+]         _l=l_
   (("))        (("))i       (("))
  __/ \/       __/_\/       __/.\/
   /___\        /___\         |:|
   _| \_        _| \_        _| \_

Ivan J. <[email protected]>

## Gopher over TLS - Why

* We're in 2021
* Privacy & security ️️(tm)
* Fight police terror and surveillance
* Tor isn't always convenient
* Opens a path to secure services on Gopher

## Gopher over TLS - What

* Community-adopted protocol
* No changes to the existing gopher protocol
   * Instead simply encapsulated with TLS
   * Optional(!) differentiation with URI (gopher|gophers)

* No need to change specification, protocol, nor port!


## Gopher over TLS - Server abstract

            record        handshake    client
            header         header      version
   recv: [16 03 01 00 a5, 01 00 00 a1, 03 03, .......]
#pause
          |
          V
   (bytes[0] == 0x16)


## Gopher over TLS - Server abstract

            record        handshake    client
            header         header      version
   recv: [16 03 01 00 a5, 01 00 00 a1, 03 03, .......]
          |
          V             (true) initialize tls context and serve
   (bytes[0] == 0x16) ----<
#pause
                        (false) serve over plain text (or refuse)

## Gopher over TLS - How

* Example:

   $ printf "/brcon\r\n" | nc parazyd.org 70
   $ printf "/brcon\r\n" | gnutls-cli parazyd.org:70


## Gopher over TLS

* We have a plan. Let's implement it!

## Five steps to domination

1. Gain understanding of core infrastructure
#pause
2. Write patch for core infrastructure
#pause
3. Get it upstream
#pause
4. Advocate this to other software using "core infrastructure"
#pause
5. Get it everywhere

## Example 1. - curl

* Arguably the most used software for data transfer with
 various protocols
* Influential
* Written in C

## Example 1. - curl

Git commit: a1f06f32b8603427535fc21183a84ce92a9b96f7
configure.ac  |  3 +++
lib/gopher.c  | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/gopher.h  |  3 +++
lib/url.c     |  3 +++
lib/version.c |  3 +++
5 files changed, 62 insertions(+)

## Example 1. - curl

* Reuse the existing Gopher protocol implementation
* Add a "gophers://" handler which is existing gopher code, plus TLS
* Explain the protocol is useful and adopted
#pause

* Merged in November 2020
* First mainstream software to include Gopher over TLS support

## Example 2. - ffmpeg

* The most widely used media tools and library
* Influential
* Written in C

## Example 2. - ffmpeg

Git commit: 51367267c8a9f1a840f5e810f8c788e6e03712a5
Changelog                 |  1 +
configure                 |  1 +
doc/general_contents.texi |  1 +
doc/protocols.texi        |  6 ++++++
libavformat/Makefile      |  1 +
libavformat/gopher.c      | 30 ++++++++++++++++++++++++++----
libavformat/protocols.c   |  1 +
libavformat/version.h     |  2 +-
8 files changed, 38 insertions(+), 5 deletions(-)

## Example 2. - ~~curl~~ ffmpeg

* Reuse the existing Gopher protocol implementation
* Add a "gophers://" handler which is existing gopher code, plus TLS
* Explain the protocol is useful and adopted (and merged by curl)
#pause

* Merged in February 2021

## Post-domination, pt.1

* Now at state where a core tool has support for Gopher over TLS
#pause

Let's see what happens with a project that uses curl:


## feh

* Solid, minimal image viewer
* Uses libcurl to fetch pictures from the Internet
* No gopher support at all!
* Written in C

## feh - the patch

Git commit: 7cb8ce10e542f27b176b6ecfb1a1ff114d9fef2d
diff --git a/src/utils.c b/src/utils.c
index 087e7f62..eb128a23 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -146,6 +146,8 @@ char *estrjoin(const char *separator, ...)
char path_is_url(char *path) {
   if ((!strncmp(path, "http://", 7))
           || (!strncmp(path, "https://", 8))
+           || (!strncmp(path, "gopher://", 9))
+           || (!strncmp(path, "gophers://", 10))
           || (!strncmp(path, "ftp://", 6))
           || (!strncmp(path, "file://", 7)))
       return 1;

## Post-domination, pt.2

* Now at state where multiple core tools have support for
 Gopher over TLS
#pause
* And a downstream project using a core tool supports
 Gopher over TLS
#pause

Let's see what happens with a project that uses ffmpeg:

## mpv

* Widely-used media player
* Works on commandline, and in GUIs
* Probably using it to listen to brcon audio stream
* Supports Gopher, but not Gopher over TLS
* Written in C

## mpv - the patch

Git commit: 6a903a9a087e9639eb3323a7e5adeb49871011af
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 1c7fd35ae2a..27a948d5e5c 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -413,7 +413,7 @@ const stream_info_t stream_info_ffmpeg = {
  .protocols = (const char *const[]){
     "rtmp", "rtsp", "rtsps", "http", "https", "mms", "mmst", "mmsh", "mmshttp",
     "rtp", "httpproxy", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srt",
-     "srtp", "gopher", "data",
+     "srtp", "gopher", "gophers", "data",
     NULL },
  .can_write = true,
  .stream_origin = STREAM_ORIGIN_NET,

## Post-domination, pt.3

* Now at a state where multiple core tools, widely-used software,
 and enthusiast projects have support for Gopher over TLS!

## Taking the role of dominatrix

* Find mainstream software and libraries that could benefit from
 Gopher over TLS
#pause
   * Difficulty level 4/10
   * Satisfaction level 10/10
#pause

* Find downstream projects using core tools that already have
 Gopher over TLS support and add this support to project-of-choice
#pause
   * Difficulty level 1/10
   * Satisfaction level 10/10

## Outro

   #job

Thanks for listening!