Download raw body.
gotwebd ssh host key fingerprints
Stefan Sperling <stsp@stsp.name> wrote:
> Add options to gotwebd.conf which set SSH host key fingeprints to
> be displayed beneath the clone URL.
>
> In gotwebd.conf the clone URL is arbitrary, which means the admin needs to
> be able to specify key fingerprints per clone-URL, rather than per server.
> So, for now, ssh fingerprints must be set per repository. If this causes
> too much copy-pasting we can introduce equivalent server-scope options later.
>
> gotsysd will be able to make assumptions about how the server is set
> up and generate appropriate gotwebd.conf stanzas automatically.
> A patch for gotsysd will follow.
>
> ok?
okay op@
> M gotwebd/gotweb.c | 21+ 0-
> M gotwebd/gotwebd.conf.5 | 12+ 0-
> M gotwebd/gotwebd.h | 8+ 0-
> M gotwebd/pages.tmpl | 12+ 0-
> M gotwebd/parse.y | 70+ 0-
>
> 5 files changed, 123 insertions(+), 0 deletions(-)
>
> commit - 8e075c1ec8542ad827b525234bea2eba76a011ad
> commit + 896f2e7025bdfa07698b31229ccfdd7de5984ba4
> blob - f4dc9ee62c67b484e6013abf9d57672569a9f3b9
> blob + 2dcdf486c002a5a2a948db88611b6912fc1de984
> --- gotwebd/gotweb.c
> +++ gotwebd/gotweb.c
> @@ -1124,11 +1124,15 @@ gotweb_free_repo_commit(struct repo_commit *rc)
> static void
> gotweb_free_repo_dir(struct repo_dir *repo_dir)
> {
> + size_t i;
> +
> if (repo_dir != NULL) {
> free(repo_dir->name);
> free(repo_dir->owner);
> free(repo_dir->description);
> free(repo_dir->url);
> + for (i = 0; i < nitems(repo_dir->sshfp); i++)
> + free(repo_dir->sshfp[i]);
> free(repo_dir->path);
> }
> free(repo_dir);
> @@ -1708,6 +1712,23 @@ gotweb_load_got_path(struct repo_dir **rp, const char
> error = gotweb_get_clone_url(&repo_dir->url, srv,
> repo_dir->path, dirfd(dt));
> }
> +
> + if (srv->show_repo_cloneurl && repo) {
> + size_t i;
> +
> + for (i = 0; i < nitems(repo->clone_url_hostkey); i++) {
> + if (repo->clone_url_hostkey[i][0] == '\0')
> + continue;
> +
> + repo_dir->sshfp[i] = strdup(repo->clone_url_hostkey[i]);
> + if (repo_dir->sshfp[i] == NULL) {
> + error = got_error_from_errno("strdup");
> + goto err;
> + }
> + }
> +
> + }
> +
> err:
> free(dir_test);
> if (dt != NULL && closedir(dt) == EOF && error == NULL)
> blob - dd2a181f36cae86843ad2bd1da24552cfd704f34
> blob + 213c5b4be700f2eab0b7e9c32341ac7d848a4123
> --- gotwebd/gotwebd.conf.5
> +++ gotwebd/gotwebd.conf.5
> @@ -497,6 +497,18 @@ then URLs stored in the repository's
> .Pa cloneurl
> file will be shown instead.
> This file may contain multiple URLs, one per line.
> +.It Ic ssh_hostkey_ecdsa Ar string
> +Set the server's SSH ECDSA host key fingerprint to be displayed beneath
> +the clone URL.
> +Should be set when the clone URL uses the SSH protocol.
> +.It Ic ssh_hostkey_ed25519 Ar string
> +Set the server's SSH ED25519 host key fingerprint to be displayed beneath
> +the clone URL.
> +Should be set when the clone URL uses the SSH protocol.
> +.It Ic ssh_hostkey_rsa Ar string
> +Set the server's SSH RSA host key fingerprint to be displayed beneath
> +the clone URL.
> +Should be set when the clone URL uses the SSH protocol.
> .It Ic description Ar string
> Sets the repository description shown on the repository listing page.
> The
> blob - af216fb97464e9ca56a9e377fdd5fc49502ebd0f
> blob + 69c2896f72735357062dc4f09af598567a4aa339
> --- gotwebd/gotwebd.h
> +++ gotwebd/gotwebd.h
> @@ -54,7 +54,13 @@
> #define GOTWEBD_MAXPORT 6
> #define GOTWEBD_NUMPROC 3
> #define GOTWEBD_SOCK_FILENO 3
> +#define GOTWEBD_MAX_SSHFP 64
>
> +#define GOTWEBD_SSHFP_ECDSA 0
> +#define GOTWEBD_SSHFP_ED25519 1
> +#define GOTWEBD_SSHFP_RSA 2
> +#define GOTWEBD_NUM_SSHFP 3
> +
> #define PROC_MAX_INSTANCES 32
>
> /* GOTWEB DEFAULTS */
> @@ -206,6 +212,7 @@ struct repo_dir {
> char *owner;
> char *description;
> char *url;
> + char *sshfp[GOTWEBD_NUM_SSHFP];
> time_t age;
> char *path;
> };
> @@ -398,6 +405,7 @@ struct gotwebd_repo {
> char name[NAME_MAX];
> char description[GOTWEBD_MAXDESCRSZ];
> char clone_url[GOTWEBD_MAXCLONEURLSZ];
> + char clone_url_hostkey[GOTWEBD_NUM_SSHFP][GOTWEBD_MAX_SSHFP];
>
> enum gotwebd_auth_config auth_config;
> struct gotwebd_access_rule_list access_rules;
> blob - cebcb17ddb34bf214026aa7e215c0e0f358e0824
> blob + e146964ba1ffd06404dc161bd891095107b8ecc8
> --- gotwebd/pages.tmpl
> +++ gotwebd/pages.tmpl
> @@ -1133,7 +1133,19 @@ nextsep(char *s, char **t)
> {{ if srv->show_repo_cloneurl }}
> <dt>Clone URL:</dt>
> <dd><pre class="clone-url">{{ t->repo_dir->url }}</pre></dd>
> + {{ if t->repo_dir->sshfp[GOTWEBD_SSHFP_ECDSA] }}
> + <dt>ECDSA:</dt>
> + <dd><pre class="clone-url">{{ t->repo_dir->sshfp[GOTWEBD_SSHFP_ECDSA] }}</pre></dd>
> {{ end }}
> + {{ if t->repo_dir->sshfp[GOTWEBD_SSHFP_ED25519] }}
> + <dt>ED25519:</dt>
> + <dd><pre class="clone-url">{{ t->repo_dir->sshfp[GOTWEBD_SSHFP_ED25519] }}</pre></dd>
> + {{ end }}
> + {{ if t->repo_dir->sshfp[GOTWEBD_SSHFP_RSA] }}
> + <dt>RSA:</dt>
> + <dd><pre class="clone-url">{{ t->repo_dir->sshfp[GOTWEBD_SSHFP_RSA] }}</pre></dd>
> + {{ end }}
> + {{ end }}
> </dl>
> <div class="summary-briefs">
> {{ render gotweb_render_briefs(tp) }}
> blob - 03821d0d02b8707a48377d243fee6f91c949727b
> blob + 06d0fa8ac5221e0906bb1adb03a35e49c67c6f35
> --- gotwebd/parse.y
> +++ gotwebd/parse.y
> @@ -157,6 +157,7 @@ mediatype_ok(const char *s)
> %token ENABLE DISABLE INSECURE REPOSITORY REPOSITORIES PERMIT DENY HIDE
> %token WEBSITE PATH BRANCH REPOS_URL_PATH DESCRIPTION
> %token TYPES INCLUDE GOTWEBD_CONTROL
> +%token SSH_HOSTKEY_ECDSA SSH_HOSTKEY_ED25519 SSH_HOSTKEY_RSA
>
> %token <v.string> STRING
> %token <v.number> NUMBER
> @@ -978,6 +979,72 @@ repoopts1 : DISABLE AUTHENTICATION {
> YYERROR;
> }
> }
> + | SSH_HOSTKEY_ECDSA STRING {
> + int i = GOTWEBD_SSHFP_ECDSA;
> +
> + if (*$2 == '\0') {
> + yyerror("ssh host key fingerprint cannot be "
> + "an empty string");
> + free($2);
> + YYERROR;
> + }
> +
> + if (strlcpy(new_repo->clone_url_hostkey[i], $2,
> + sizeof(new_repo->clone_url_hostkey[i])) >=
> + sizeof(new_repo->clone_url_hostkey[i])) {
> + yyerror("ssh host key fingerprint too long, "
> + "exceeds " "%zd bytes: %s",
> + sizeof(new_repo->clone_url_hostkey[i]), $2);
> + free($2);
> + YYERROR;
> + }
> +
> + free($2);
> + }
> + | SSH_HOSTKEY_ED25519 STRING {
> + int i = GOTWEBD_SSHFP_ED25519;
> +
> + if (*$2 == '\0') {
> + yyerror("ssh host key fingerprint cannot be "
> + "an empty string");
> + free($2);
> + YYERROR;
> + }
> +
> + if (strlcpy(new_repo->clone_url_hostkey[i], $2,
> + sizeof(new_repo->clone_url_hostkey[i])) >=
> + sizeof(new_repo->clone_url_hostkey[i])) {
> + yyerror("ssh host key fingerprint too long, "
> + "exceeds " "%zd bytes: %s",
> + sizeof(new_repo->clone_url_hostkey[i]), $2);
> + free($2);
> + YYERROR;
> + }
> +
> + free($2);
> + }
> + | SSH_HOSTKEY_RSA STRING {
> + int i = GOTWEBD_SSHFP_RSA;
> +
> + if (*$2 == '\0') {
> + yyerror("ssh host key fingerprint cannot be "
> + "an empty string");
> + free($2);
> + YYERROR;
> + }
> +
> + if (strlcpy(new_repo->clone_url_hostkey[i], $2,
> + sizeof(new_repo->clone_url_hostkey[i])) >=
> + sizeof(new_repo->clone_url_hostkey[i])) {
> + yyerror("ssh host key fingerprint too long, "
> + "exceeds " "%zd bytes: %s",
> + sizeof(new_repo->clone_url_hostkey[i]), $2);
> + free($2);
> + YYERROR;
> + }
> +
> + free($2);
> + }
> ;
>
> types : TYPES '{' optnl mediaopts_l '}'
> @@ -1129,6 +1196,9 @@ lookup(char *s)
> { "site_name", SITE_NAME },
> { "site_owner", SITE_OWNER },
> { "socket", SOCKET },
> + { "ssh_hostkey_ecdsa", SSH_HOSTKEY_ECDSA},
> + { "ssh_hostkey_ed25519", SSH_HOSTKEY_ED25519},
> + { "ssh_hostkey_rsa", SSH_HOSTKEY_RSA},
> { "summary_commits_display", SUMMARY_COMMITS_DISPLAY },
> { "summary_tags_display", SUMMARY_TAGS_DISPLAY },
> { "types", TYPES },
gotwebd ssh host key fingerprints