-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjson.c
More file actions
153 lines (120 loc) · 3.93 KB
/
Copy pathjson.c
File metadata and controls
153 lines (120 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "json.h"
#include <string.h>
void khm_json_escape(FILE *out, const char *s) {
if (!s) return;
for (const unsigned char *p = (const unsigned char *)s; *p; p++) {
switch (*p) {
case '"': fputs("\\\"", out); break;
case '\\': fputs("\\\\", out); break;
case '\n': fputs("\\n", out); break;
case '\r': fputs("\\r", out); break;
case '\t': fputs("\\t", out); break;
default:
if (*p < 0x20) {
fprintf(out, "\\u%04x", *p);
} else {
fputc(*p, out);
}
}
}
}
static void json_str(FILE *out, const char *s) {
if (!s) { fputs("null", out); return; }
fputc('"', out);
khm_json_escape(out, s);
fputc('"', out);
}
static const char *status_str(khm_status_t s) {
switch (s) {
case KHM_STATUS_OK: return "ok";
case KHM_STATUS_CHANGED: return "changed";
case KHM_STATUS_NEW: return "new";
case KHM_STATUS_NEW_ALGORITHM: return "new_algorithm";
case KHM_STATUS_UNREACHABLE: return "unreachable";
case KHM_STATUS_NONE:
default: return "none";
}
}
void khm_json_write_entry(FILE *out, const khm_entry_t *e, const char *fingerprint) {
fputc('{', out);
fputs("\"hostnames\":", out);
if (e->hashed) {
/* Hostname is not recoverable — mirror list.c's "<hashed>" display
* by not pretending we know it. */
fputs("[]", out);
} else {
fputc('[', out);
for (int i = 0; i < e->hostname_count; i++) {
if (i > 0) fputc(',', out);
json_str(out, e->hostnames[i]);
}
fputc(']', out);
}
fprintf(out, ",\"hashed\":%s", e->hashed ? "true" : "false");
fprintf(out, ",\"port\":%d", e->port ? e->port : 22);
fputs(",\"algorithm\":", out);
json_str(out, e->keytype_str);
if (fingerprint) {
fputs(",\"fingerprint\":", out);
json_str(out, fingerprint);
}
fputc('}', out);
}
void khm_json_write_result(FILE *out, const khm_result_t *r) {
fputc('{', out);
fputs("\"host\":", out);
json_str(out, r->host);
fprintf(out, ",\"port\":%d", r->port ? r->port : 22);
fputs(",\"status\":", out);
json_str(out, status_str(r->status));
fputs(",\"algorithm\":", out);
json_str(out, r->algorithm);
fputs(",\"fetched_fingerprint\":", out);
json_str(out, r->fetched_fp);
fputs(",\"known_fingerprint\":", out);
json_str(out, r->known_fp);
fputs(",\"record\":", out);
if (r->record_index > 0)
fprintf(out, "%ld", r->record_index);
else
fputs("null", out);
fputs(",\"known_algorithms\":", out);
json_str(out, r->known_algorithms);
fputc('}', out);
}
static const char *fp_check_status_str(khm_fp_check_status_t s) {
switch (s) {
case KHM_FP_CHECK_MATCH: return "match";
case KHM_FP_CHECK_MISMATCH: return "mismatch";
case KHM_FP_CHECK_ERROR:
default: return "error";
}
}
void khm_json_write_fp_check(FILE *out, const khm_fp_check_result_t *r) {
fputc('{', out);
fputs("\"host\":", out);
json_str(out, r->host);
fprintf(out, ",\"port\":%d", r->port ? r->port : 22);
fputs(",\"expected_fingerprint\":", out);
json_str(out, r->expected_fp);
fputs(",\"observed_fingerprint\":", out);
json_str(out, r->observed_fp);
fputs(",\"algorithm\":", out);
json_str(out, r->algorithm);
fputs(",\"result\":", out);
json_str(out, fp_check_status_str(r->status));
fputs(",\"error\":", out);
json_str(out, r->error);
fputc('}', out);
}
void khm_json_array_begin(FILE *out) {
fputc('[', out);
}
void khm_json_array_next(FILE *out, int *first) {
if (!*first) fputc(',', out);
*first = 0;
}
void khm_json_array_end(FILE *out) {
fputc(']', out);
fputc('\n', out);
}