002
2022-04-24
op
* Copyright (c) 2021, 2022 Omar Polo <op@omarpolo.com>
004
2021-04-25
op
* Permission to use, copy, modify, and distribute this software for any
005
2021-04-25
op
* purpose with or without fee is hereby granted, provided that the above
006
2021-04-25
op
* copyright notice and this permission notice appear in all copies.
008
2021-04-25
op
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
009
2021-04-25
op
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
010
2021-04-25
op
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
011
2021-04-25
op
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
012
2021-04-25
op
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
013
2021-04-25
op
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
014
2021-04-25
op
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
017
2022-01-11
op
#include "compat.h"
019
2022-04-24
op
#include <limits.h>
020
2021-04-25
op
#include <stdlib.h>
021
2021-04-25
op
#include <string.h>
022
2022-04-24
op
#include <unistd.h>
024
2022-04-24
op
#include "fs.h"
025
2022-01-11
op
#include "telescope.h"
026
2022-01-11
op
#include "utils.h"
029
2021-04-25
op
tofu_init(struct ohash *h, unsigned int sz, ptrdiff_t ko)
031
2021-04-25
op
struct ohash_info info = {
032
2021-04-25
op
.key_offset = ko,
033
2021-04-25
op
.calloc = hash_calloc,
034
2021-04-25
op
.free = hash_free,
035
2021-04-25
op
.alloc = hash_alloc,
038
2021-04-25
op
ohash_init(h, sz, &info);
041
2021-04-25
op
struct tofu_entry *
042
2021-04-25
op
tofu_lookup(struct ohash *h, const char *domain, const char *port)
044
2021-04-25
op
char buf[GEMINI_URL_LEN];
045
2021-04-25
op
unsigned int slot;
047
2021-04-25
op
strlcpy(buf, domain, sizeof(buf));
048
2021-04-25
op
if (port != NULL && *port != '\0' && strcmp(port, "1965")) {
049
2021-04-25
op
strlcat(buf, ":", sizeof(buf));
050
2021-04-25
op
strlcat(buf, port, sizeof(buf));
053
2021-04-25
op
slot = ohash_qlookup(h, buf);
054
2021-04-25
op
return ohash_find(h, slot);
058
2021-04-25
op
tofu_add(struct ohash *h, struct tofu_entry *e)
060
2021-04-25
op
unsigned int slot;
062
2021-04-25
op
slot = ohash_qlookup(h, e->domain);
063
2021-04-25
op
ohash_insert(h, slot, e);
067
2022-04-24
op
tofu_save(struct ohash *h, struct tofu_entry *e)
069
2022-04-24
op
FILE *fp;
071
2022-04-24
op
tofu_add(h, e);
073
2022-04-24
op
if ((fp = fopen(known_hosts_file, "a")) == NULL)
074
2022-04-24
op
return -1;
075
2022-04-24
op
fprintf(fp, "%s %s %d\n", e->domain, e->hash, e->verified);
076
2022-04-24
op
fclose(fp);
077
2022-04-24
op
return 0;
081
2021-04-25
op
tofu_update(struct ohash *h, struct tofu_entry *e)
083
2021-04-25
op
struct tofu_entry *t;
085
2021-04-25
op
if ((t = tofu_lookup(h, e->domain, NULL)) == NULL)
086
2021-04-25
op
tofu_add(h, e);
088
2021-04-25
op
strlcpy(t->hash, e->hash, sizeof(t->hash));
089
2021-04-25
op
t->verified = e->verified;
095
2022-04-24
op
tofu_update_persist(struct ohash *h, struct tofu_entry *e)
097
2022-04-24
op
FILE *tmp, *fp;
098
2022-04-24
op
char sfn[PATH_MAX], *line = NULL;
099
2022-04-24
op
size_t l, linesize = 0;
100
2022-04-24
op
ssize_t linelen;
101
2022-04-24
op
int fd, err;
103
2022-04-24
op
tofu_update(h, e);
105
2022-04-24
op
strlcpy(sfn, known_hosts_tmp, sizeof(sfn));
106
2022-04-24
op
if ((fd = mkstemp(sfn)) == -1 ||
107
2022-04-24
op
(tmp = fdopen(fd, "w")) == NULL) {
108
2022-04-24
op
if (fd != -1) {
109
2022-04-24
op
unlink(sfn);
110
2022-04-24
op
close(fd);
112
2022-04-24
op
return -1;
115
2022-04-24
op
if ((fp = fopen(known_hosts_file, "r")) == NULL) {
116
2022-04-24
op
unlink(sfn);
117
2022-04-24
op
fclose(tmp);
118
2022-04-24
op
return -1;
121
2022-04-24
op
l = strlen(e->domain);
122
2022-04-24
op
while ((linelen = getline(&line, &linesize, fp)) != -1) {
123
2022-04-24
op
if (!strncmp(line, e->domain, l))
124
2022-04-24
op
continue;
125
2022-04-24
op
if (linesize > 0 && line[linesize-1] == '\n')
126
2022-04-24
op
line[linesize-1] = '\0';
127
2022-04-24
op
fprintf(tmp, "%s\n", line);
129
2022-04-24
op
fprintf(tmp, "%s %s %d\n", e->domain, e->hash, e->verified);
131
2022-04-24
op
free(line);
132
2022-04-24
op
err = ferror(tmp);
133
2022-04-24
op
fclose(tmp);
134
2022-04-24
op
fclose(fp);
136
2022-04-24
op
if (err) {
137
2022-04-24
op
unlink(sfn);
138
2022-04-24
op
return -1;
141
2022-04-24
op
if (rename(sfn, known_hosts_file))
142
2022-04-24
op
return -1;
143
2022-04-24
op
return 0;
147
2021-07-06
op
tofu_temp_trust(struct ohash *h, const char *host, const char *port,
148
2021-07-06
op
const char *hash)
150
2021-07-06
op
struct tofu_entry *e;
152
2021-07-06
op
if ((e = calloc(1, sizeof(*e))) == NULL)
155
2021-08-26
op
strlcpy(e->domain, host, sizeof(e->domain));
156
2021-07-06
op
if (*port != '\0' && strcmp(port, "1965")) {
157
2021-07-06
op
strlcat(e->domain, ":", sizeof(e->domain));
158
2021-07-06
op
strlcat(e->domain, port, sizeof(e->domain));
160
2021-07-06
op
strlcpy(e->hash, hash, sizeof(e->hash));
161
2021-07-06
op
e->verified = -1;
163
2021-07-06
op
tofu_update(h, e);