Go to file
Omar Polo e872053b20 send all the params as per RFC3875 (CGI) and sync documentation 2023-08-18 12:40:10 +00:00
compat add missing include of config.h in vis.c 2023-08-07 17:57:24 +00:00
contrib rework the configure script 2023-06-13 16:36:10 +00:00
have address the strnvis(3) portability fiasco 2023-08-07 15:39:57 +00:00
regress use the legacy style in the tests for now 2023-08-03 22:37:05 +00:00
site update the site for 1.8.6 2022-12-02 15:21:20 +00:00
.cirrus.yml hopefully fix the macos ci 2023-06-23 22:40:58 +00:00
.dockerignore fix the dockerfile 2021-07-11 20:58:42 +00:00
.gitignore rename ge -> gemexp 2023-07-25 20:15:40 +00:00
ChangeLog update changelog 2023-08-08 18:08:37 +00:00
LICENSE copyright years 2022-07-04 09:48:39 +00:00
Makefile two more missing ge -> gemexp 2023-08-03 22:04:36 +00:00
README.md revamp helper section of the README and mention titan(1) 2023-07-25 20:24:44 +00:00
config.c unbreak config_test() when !use_privsep_crypto 2023-08-07 13:18:04 +00:00
configure fix INSTALL handling 2023-08-13 09:53:12 +00:00
configure.local.example add an example configure.local based on mandoc-portable' one 2022-07-04 13:44:53 +00:00
crypto.c fmt 2023-07-22 08:19:26 +00:00
dirs.c don't set d_reclen 2022-07-07 08:54:26 +00:00
fcgi.c send all the params as per RFC3875 (CGI) and sync documentation 2023-08-18 12:40:10 +00:00
ge.c use the subject' common name as the user field in log 2023-08-07 14:04:47 +00:00
gemexp.1 rename ge -> gemexp 2023-07-25 20:15:40 +00:00
gg.1 minor tweaks to gg(1) 2023-08-03 22:07:40 +00:00
gg.c revert previous 2023-07-23 14:13:23 +00:00
gmid.8 remove the LOGGING section; it's covered by gmid.conf(5) 2023-08-03 22:03:43 +00:00
gmid.c use the subject' common name as the user field in log 2023-08-07 14:04:47 +00:00
gmid.conf.5 send all the params as per RFC3875 (CGI) and sync documentation 2023-08-18 12:40:10 +00:00
gmid.h remove not so useful starts_with() 2023-08-11 10:38:34 +00:00
iri.c more is*() unsigned char cast 2022-11-29 23:03:55 +00:00
iri.h split out iri.h from gmid.h 2023-07-22 13:49:07 +00:00
log.c add missing include of gmid.h 2023-06-06 11:57:33 +00:00
log.h switch to the more usual log.c 2023-06-06 11:46:40 +00:00
logger.c add `log syslog facility' to use a different syslog(3) facility 2023-08-07 09:34:19 +00:00
mime.c copyright years++ 2023-06-24 10:07:17 +00:00
parse.y implement fastcgi strip number 2023-08-08 17:35:11 +00:00
proc.c rework check 2023-06-24 19:42:31 +00:00
proc.h reopen log files upon SIGUSR2 2023-07-24 09:00:19 +00:00
proxy.c don't call client_close() from fcgi/proxy bev handlers 2023-08-09 19:13:13 +00:00
puny.c remove not so useful starts_with() 2023-08-11 10:38:34 +00:00
sandbox.c add ability to log to files with log access <path> 2023-07-24 08:50:49 +00:00
server.c fix comment (ge -> gemexp) 2023-08-11 16:18:37 +00:00
titan.1 add a manpage for titan(1) 2023-07-24 09:59:02 +00:00
titan.c titan: clean up IRI/URI/URL mess; it's a IRI what we parse 2023-08-04 10:02:18 +00:00
utf8.c fmt 2021-10-18 10:05:55 +00:00
utils.c getcwd(NULL) is an extension; don't rely on it 2023-08-11 10:40:58 +00:00

README.md

gmid

Warning The master branch is WIP: it's what gmid 2.0 will be, with breaking changes et al. Please use the latest release from the 1.8 branch for a stable and documented experience, thank you.

gmid is a full-featured Gemini server written with security in mind. It can serve static files, has optional FastCGI and proxying support, and a rich configuration syntax.

A few helper programs are shipped as part of gmid:

  • gg is a simple command-line Gemini client.

  • gemexp is a stripped-down config-less version of gmid to quickly serve a directory from the command line.

  • titan is a command-line titan client.

Internationalisation (IRIs, UNICODE, punycode, all that stuff)

Even thought the current Gemini specification doesn't mention anything in this regard, I do think these are important things and so I tried to implement them in the most user-friendly way I could think of.

For starters, gmid has full support for IRI (RFC3987 — Internationalized Resource Identifiers). IRIs are a superset of URIs, so there aren't incompatibilities with URI-only clients.

There is full support also for punycode. In theory, the user doesn't even need to know that punycode is a thing. The hostname in the configuration file can (and must be) in the decoded form (e.g. naïve and not xn--nave-6pa), gmid will do the rest.

The only missing piece is UNICODE normalisation of the IRI path: gmid doesn't do that (yet).

Configuration

gmid has a rich configuration file, heavily inspired by OpenBSD' httpd(8), with every detail carefully documented in the manpage. Here's a minimal example of a config file:

server "example.com" {
	listen on * port 1965
	cert "/path/to/cert.pem"
	key  "/path/to/key.pem"
	root "/var/gemini/example.com"
}

and a slightly more complex one

cert_root = "/path/to/keys"

server "example.com" {
	listen on * port 1965

	alias "foobar.com"

	cert $cert_root "/example.com.crt"
	key  $cert_root "/example.com.pem"
	root "/var/gemini/example.com"

	# lang for text/gemini files
	lang "en"

	# only for locations that matches /files/*
	location "/files/*" {
		# generate directory listings
		auto index on
	}

	location "/repo/*" {
		# change the index file name
		index "README.gmi"
		lang "it"
	}
}

Building

gmid depends on libevent2, OpenSSL/LibreSSL and libtls (provided either by LibreSSL or libretls). At build time, yacc (or GNU bison) is also needed.

The build is as simple as

$ ./configure
$ make

If the configure scripts fails to pick up something, please open an issue or notify me via email.

To install execute:

# make install

Please keep in mind that the master branch, from time to time, may be accidentally broken on some platforms. gmid is developed primarily on OpenBSD/amd64 and commits on the master branch don't get always tested in other OSes. Before tagging a release however, a comprehensive testing on various platform is done to ensure that everything is working as intended.

Testing

Execute

$ make regress

to start the suite. Keep in mind that the regression tests needs to create a few file inside the regress directory and bind the 10965 port.

Contributing

Any form of contribution is welcome, not only patches or bug reports. If you have a sample configuration for some specific use-case, a script or anything that could be useful to others, consider adding it to the contrib directory.

Architecture/Security considerations

The internal architecture was revisited for the 2.0 release. For previous releases, please refer to previous revision of this file.

gmid has a privsep design, where the operations done by the daemon are splitted into multiple processes:

  • main: the main process is the only one that keeps the original privileges. It opens the TLS certificates on the behalf of the server and crypto processes and reloads the configuration upon SIGHUP.

  • logger: logs the requests.

  • server: listen on the binded ports and serves the request. This also include speaking FastCGI and proxying requests.

  • crypto: (used only on OpenBSD at the time of writing.) Holds the TLS private keys to avoid a compromised server process to disclose them.