Coverage Report

Created: 2026-09-07 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c
Line
Count
Source
1
#include "fixed-keys.h"
2
#include <assert.h>
3
4
#define main(ac, av) xxxmain(ac, av)
5
#include "../../../ssh-agent.c"
6
7
void test_one(const uint8_t* s, size_t slen);
8
9
static int
10
devnull_or_die(void)
11
0
{
12
0
  int fd;
13
14
0
  if ((fd = open("/dev/null", O_RDWR)) == -1) {
15
0
    error_f("open /dev/null: %s", strerror(errno));
16
0
    abort();
17
0
  }
18
0
  return fd;
19
0
}
20
21
static struct sshkey *
22
pubkey_or_die(const char *s)
23
0
{
24
0
  char *tmp, *cp;
25
0
  struct sshkey *pubkey;
26
0
  int r;
27
28
0
  tmp = cp = xstrdup(s);
29
0
  if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
30
0
    abort();
31
0
  if ((r = sshkey_read(pubkey, &cp)) != 0) {
32
0
    error_fr(r, "parse");
33
0
    abort();
34
0
  }
35
0
  free(tmp);
36
0
  return pubkey;
37
0
}
38
39
static struct sshkey *
40
privkey_or_die(const char *s)
41
0
{
42
0
  int r;
43
0
  struct sshbuf *b;
44
0
  struct sshkey *privkey;
45
46
0
  if ((b = sshbuf_from(s, strlen(s))) == NULL) {
47
0
    error_f("sshbuf_from failed");
48
0
    abort();
49
0
  }
50
0
  if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
51
0
    error_fr(r, "parse");
52
0
    abort();
53
0
  }
54
0
  sshbuf_free(b);
55
0
  return privkey;
56
0
}
57
58
static void
59
add_key(const char *privkey, const char *certpath)
60
0
{
61
0
  Identity *id;
62
0
  int r;
63
0
  struct sshkey *cert;
64
65
0
  id = xcalloc(1, sizeof(Identity));
66
0
  TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
67
0
  idtab->nentries++;
68
0
  id->key = privkey_or_die(privkey);
69
0
  id->comment = xstrdup("rhododaktulos Eos");
70
0
  if (sshkey_is_sk(id->key))
71
0
    id->sk_provider = xstrdup("internal");
72
73
  /* Now the cert too */
74
0
  id = xcalloc(1, sizeof(Identity));
75
0
  TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
76
0
  idtab->nentries++;
77
0
  id->key = privkey_or_die(privkey);
78
0
  cert = pubkey_or_die(certpath);
79
0
  if ((r = sshkey_to_certified(id->key)) != 0) {
80
0
    error_fr(r, "sshkey_to_certified");
81
0
    abort();
82
0
  }
83
0
  if ((r = sshkey_cert_copy(cert, id->key)) != 0) {
84
0
    error_fr(r, "sshkey_cert_copy");
85
0
    abort();
86
0
  }
87
0
  sshkey_free(cert);
88
0
  id->comment = xstrdup("outis");
89
0
  if (sshkey_is_sk(id->key))
90
0
    id->sk_provider = xstrdup("internal");
91
0
}
92
93
static void
94
cleanup_idtab(void)
95
0
{
96
0
  Identity *id;
97
98
0
  if (idtab == NULL) return;
99
0
  for (id = TAILQ_FIRST(&idtab->idlist); id;
100
0
      id = TAILQ_FIRST(&idtab->idlist)) {
101
0
    TAILQ_REMOVE(&idtab->idlist, id, next);
102
0
    free_identity(id);
103
0
  }
104
0
  free(idtab);
105
0
  idtab = NULL;
106
0
}
107
108
static void
109
reset_idtab(void)
110
0
{
111
0
  cleanup_idtab();
112
0
  idtab_init();
113
  // Load keys.
114
0
  add_key(PRIV_RSA, CERT_RSA);
115
0
  add_key(PRIV_ECDSA, CERT_ECDSA);
116
0
  add_key(PRIV_ED25519, CERT_ED25519);
117
0
  add_key(PRIV_ECDSA_SK, CERT_ECDSA_SK);
118
0
  add_key(PRIV_ED25519_SK, CERT_ED25519_SK);
119
0
}
120
121
static void
122
cleanup_sockettab(void)
123
0
{
124
0
  u_int i;
125
0
  for (i = 0; i < sockets_alloc; i++) {
126
0
    if (sockets[i].type != AUTH_UNUSED)
127
0
      close_socket(sockets + i);
128
0
  }
129
0
  free(sockets);
130
0
  sockets = NULL;
131
0
  sockets_alloc = 0;
132
0
}
133
134
static void
135
reset_sockettab(int devnull)
136
0
{
137
0
  int fd;
138
139
0
  cleanup_sockettab();
140
0
  if ((fd = dup(devnull)) == -1) {
141
0
    error_f("dup: %s", strerror(errno));
142
0
    abort();
143
0
  }
144
0
  new_socket(AUTH_CONNECTION, fd);
145
0
  assert(sockets[0].type == AUTH_CONNECTION);
146
0
  assert(sockets[0].fd == fd);
147
0
}
148
149
0
#define MAX_MESSAGES 256
150
void
151
test_one(const uint8_t* s, size_t slen)
152
0
{
153
0
  static int devnull = -1;
154
0
  size_t i, olen, nlen;
155
156
0
  if (devnull == -1) {
157
0
    log_init(__progname, SYSLOG_LEVEL_DEBUG3,
158
0
        SYSLOG_FACILITY_AUTH, 1);
159
0
    devnull = devnull_or_die();
160
0
    allowed_providers = xstrdup("");
161
0
    websafe_allowlist = xstrdup("*");
162
0
    setenv("DISPLAY", "", 1); /* ban askpass */
163
0
  }
164
165
0
  reset_idtab();
166
0
  reset_sockettab(devnull);
167
0
  (void)sshbuf_put(sockets[0].input, s, slen);
168
0
  for (i = 0; i < MAX_MESSAGES; i++) {
169
0
    olen = sshbuf_len(sockets[0].input);
170
0
    process_message(0);
171
0
    nlen = sshbuf_len(sockets[0].input);
172
0
    if (nlen == 0 || nlen == olen)
173
0
      break;
174
0
  }
175
0
  cleanup_idtab();
176
0
  cleanup_sockettab();
177
0
}