Coverage Report

Created: 2025-11-11 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dropbear/src/compat.c
Line
Count
Source
1
/*
2
 * Dropbear - a SSH2 server
3
 * 
4
 * Copyright (c) 2002,2003 Matt Johnston
5
 * All rights reserved.
6
 * 
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 * 
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 * 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 *
25
 * strlcat() is copyright as follows:
26
 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
27
 * All rights reserved.
28
 *
29
 * Redistribution and use in source and binary forms, with or without
30
 * modification, are permitted provided that the following conditions
31
 * are met:
32
 * 1. Redistributions of source code must retain the above copyright
33
 *    notice, this list of conditions and the following disclaimer.
34
 * 2. Redistributions in binary form must reproduce the above copyright
35
 *    notice, this list of conditions and the following disclaimer in the
36
 *    documentation and/or other materials provided with the distribution.
37
 * 3. The name of the author may not be used to endorse or promote products
38
 *    derived from this software without specific prior written permission.
39
 *
40
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
41
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
42
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
43
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
45
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
46
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
47
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
49
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50
 *
51
 * daemon() and getusershell() is copyright as follows:
52
 *
53
 * Copyright (c) 1990, 1993
54
 *      The Regents of the University of California.  All rights reserved.
55
 *
56
 * Redistribution and use in source and binary forms, with or without
57
 * modification, are permitted provided that the following conditions
58
 * are met:
59
 * 1. Redistributions of source code must retain the above copyright
60
 *    notice, this list of conditions and the following disclaimer.
61
 * 2. Redistributions in binary form must reproduce the above copyright
62
 *    notice, this list of conditions and the following disclaimer in the
63
 *    documentation and/or other materials provided with the distribution.
64
 * 3. Neither the name of the University nor the names of its contributors
65
 *    may be used to endorse or promote products derived from this software
66
 *    without specific prior written permission.
67
 *
68
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
69
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
71
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
72
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
74
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
75
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
76
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
77
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
78
* SUCH DAMAGE.
79
*
80
* Modifications for Dropbear to getusershell() are by Paul Marinceu
81
*/
82
83
#include "includes.h"
84
85
#ifndef HAVE_GETUSERSHELL
86
static char **curshell, **shells, *strings;
87
static char **initshells();
88
#endif
89
90
#ifndef HAVE_STRLCPY
91
/* Implemented by matt as specified in freebsd 4.7 manpage.
92
 * We don't require great speed, is simply for use with sshpty code */
93
0
size_t strlcpy(char *dst, const char *src, size_t size) {
94
95
0
  size_t i;
96
97
  /* this is undefined, though size==0 -> return 0 */
98
0
  if (size < 1) {
99
0
    return 0;
100
0
  }
101
102
0
  for (i = 0; i < size-1; i++) {
103
0
    if (src[i] == '\0') {
104
0
      break;
105
0
    } else {
106
0
      dst[i] = src[i];
107
0
    }
108
0
  }
109
110
0
  dst[i] = '\0';
111
0
  return strlen(src);
112
113
0
}
114
#endif /* HAVE_STRLCPY */
115
116
#ifndef HAVE_STRLCAT
117
/* taken from openbsd-compat for OpenSSH 7.2p2 */
118
/* "$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $"
119
 *
120
 * Appends src to string dst of size siz (unlike strncat, siz is the
121
 * full size of dst, not space left).  At most siz-1 characters
122
 * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
123
 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
124
 * If retval >= siz, truncation occurred.
125
 */
126
size_t
127
strlcat(char *dst, const char *src, size_t siz)
128
0
{
129
0
  char *d = dst;
130
0
  const char *s = src;
131
0
  size_t n = siz;
132
0
  size_t dlen;
133
134
  /* Find the end of dst and adjust bytes left but don't go past end */
135
0
  while (n-- != 0 && *d != '\0')
136
0
    d++;
137
0
  dlen = d - dst;
138
0
  n = siz - dlen;
139
140
0
  if (n == 0)
141
0
    return(dlen + strlen(s));
142
0
  while (*s != '\0') {
143
0
    if (n != 1) {
144
0
      *d++ = *s;
145
0
      n--;
146
0
    }
147
0
    s++;
148
0
  }
149
0
  *d = '\0';
150
151
0
  return(dlen + (s - src)); /* count does not include NUL */
152
0
}
153
#endif /* HAVE_STRLCAT */
154
155
#ifndef HAVE_DAEMON
156
/* From NetBSD - daemonise a process */
157
158
int daemon(int nochdir, int noclose) {
159
160
  int fd;
161
162
  switch (fork()) {
163
    case -1:
164
      return (-1);
165
    case 0:
166
      break;
167
    default:
168
      _exit(0);
169
  }
170
171
  if (setsid() == -1)
172
    return -1;
173
174
  if (!nochdir)
175
    (void)chdir("/");
176
177
  if (!noclose && (fd = open(DROPBEAR_PATH_DEVNULL, O_RDWR, 0)) != -1) {
178
    (void)dup2(fd, STDIN_FILENO);
179
    (void)dup2(fd, STDOUT_FILENO);
180
    (void)dup2(fd, STDERR_FILENO);
181
    if (fd > STDERR_FILENO)
182
      (void)close(fd);
183
  }
184
  return 0;
185
}
186
#endif /* HAVE_DAEMON */
187
188
#ifndef HAVE_BASENAME
189
190
char *basename(const char *path) {
191
192
  char *foo = strrchr(path, '/');
193
  if (!foo)
194
  {
195
    return path;
196
  }
197
  return ++foo;
198
}
199
200
#endif /* HAVE_BASENAME */
201
202
#ifndef HAVE_GETUSERSHELL
203
204
/*
205
 * Get a list of shells from /etc/shells, if it exists.
206
 */
207
char * getusershell() {
208
  char *ret;
209
210
  if (curshell == NULL)
211
    curshell = initshells();
212
  ret = *curshell;
213
  if (ret != NULL)
214
    curshell++;
215
  return (ret);
216
}
217
218
void endusershell() {
219
220
  if (shells != NULL)
221
    free(shells);
222
  shells = NULL;
223
  if (strings != NULL)
224
    free(strings);
225
  strings = NULL;
226
  curshell = NULL;
227
}
228
229
void setusershell() {
230
  curshell = initshells();
231
}
232
233
static char **initshells() {
234
  static const char *okshells[] = { COMPAT_USER_SHELLS, NULL };
235
  register char **sp, *cp;
236
  register FILE *fp;
237
  struct stat statb;
238
  int flen;
239
240
  if (shells != NULL)
241
    free(shells);
242
  shells = NULL;
243
  if (strings != NULL)
244
    free(strings);
245
  strings = NULL;
246
  if ((fp = fopen("/etc/shells", "rc")) == NULL)
247
    return (char **) okshells;
248
  if (fstat(fileno(fp), &statb) == -1) {
249
    (void)fclose(fp);
250
    return (char **) okshells;
251
  }
252
  if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) {
253
    (void)fclose(fp);
254
    return (char **) okshells;
255
  }
256
  shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
257
  if (shells == NULL) {
258
    (void)fclose(fp);
259
    free(strings);
260
    strings = NULL;
261
    return (char **) okshells;
262
  }
263
  sp = shells;
264
  cp = strings;
265
  flen = statb.st_size;
266
  while (fgets(cp, flen - (cp - strings), fp) != NULL) {
267
    while (*cp != '#' && *cp != '/' && *cp != '\0')
268
      cp++;
269
    if (*cp == '#' || *cp == '\0')
270
      continue;
271
    *sp++ = cp;
272
    while (!isspace(*cp) && *cp != '#' && *cp != '\0')
273
      cp++;
274
    *cp++ = '\0';
275
  }
276
  *sp = NULL;
277
  (void)fclose(fp);
278
  return (shells);
279
}
280
281
#endif /* HAVE_GETUSERSHELL */
282
283
/* libcrux uses glibc's htole64 etc */
284
#if !(defined(HAVE_HTOLE64) || defined(HAVE_DECL_HTOLE64))
285
286
uint64_t htole64(uint64_t inp) {
287
  union {
288
    uint64_t v;
289
    uint8_t bytes[8];
290
  } out;
291
  STORE64L(inp, out.bytes);
292
  return out.v;
293
}
294
295
uint64_t le64toh(uint64_t inp) {
296
  return htole64(inp);
297
}
298
299
uint32_t htole32(uint32_t inp) {
300
  union {
301
    uint32_t v;
302
    uint8_t bytes[4];
303
  } out;
304
  STORE32L(inp, out.bytes);
305
  return out.v;
306
}
307
308
uint32_t le32toh(uint32_t inp) {
309
  return htole32(inp);
310
}
311
312
#endif /* HAVE_HTOLE64 */