*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.37 2005/12/08 18:34:11 reyk Exp $");
+
+#include <sys/ioctl.h>
+#include <netinet/tcp.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#ifdef SSH_TUN_OPENBSD
+#include <net/if.h>
+#endif
#include "misc.h"
#include "log.h"
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
+#define QUOTE "\""
/* return next token in configuration line */
char *
old = *s;
- *s = strpbrk(*s, WHITESPACE "=");
+ *s = strpbrk(*s, WHITESPACE QUOTE "=");
if (*s == NULL)
return (old);
+ if (*s[0] == '\"') {
+ memmove(*s, *s + 1, strlen(*s)); /* move nul too */
+ /* Find matching quote */
+ if ((*s = strpbrk(*s, QUOTE)) == NULL) {
+ return (NULL); /* no matching quote */
+ } else {
+ *s[0] = '\0';
+ return (old);
+ }
+ }
+
/* Allow only one '=' to be skipped */
if (*s[0] == '=')
wspace = 1;
*s[0] = '\0';
+ /* Skip any extra whitespace after first token */
*s += strspn(*s + 1, WHITESPACE) + 1;
if (*s[0] == '=' && !wspace)
*s += strspn(*s + 1, WHITESPACE) + 1;
struct passwd *
pwcopy(struct passwd *pw)
{
- struct passwd *copy = xmalloc(sizeof(*copy));
+ struct passwd *copy = xcalloc(1, sizeof(*copy));
- memset(copy, 0, sizeof(*copy));
copy->pw_name = xstrdup(pw->pw_name);
copy->pw_passwd = xstrdup(pw->pw_passwd);
copy->pw_gecos = xstrdup(pw->pw_gecos);
switch (*endp++) {
case '\0':
endp--;
+ break;
case 's':
case 'S':
break;
addargs(arglist *args, char *fmt, ...)
{
va_list ap;
- char buf[1024];
+ char *cp;
u_int nalloc;
+ int r;
va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
+ r = vasprintf(&cp, fmt, ap);
va_end(ap);
+ if (r == -1)
+ fatal("addargs: argument too long");
nalloc = args->nalloc;
if (args->list == NULL) {
} else if (args->num+2 >= nalloc)
nalloc *= 2;
- args->list = xrealloc(args->list, nalloc * sizeof(char *));
+ args->list = xrealloc(args->list, nalloc, sizeof(char *));
args->nalloc = nalloc;
- args->list[args->num++] = xstrdup(buf);
+ args->list[args->num++] = cp;
args->list[args->num] = NULL;
}
+void
+replacearg(arglist *args, u_int which, char *fmt, ...)
+{
+ va_list ap;
+ char *cp;
+ int r;
+
+ va_start(ap, fmt);
+ r = vasprintf(&cp, fmt, ap);
+ va_end(ap);
+ if (r == -1)
+ fatal("replacearg: argument too long");
+
+ if (which >= args->num)
+ fatal("replacearg: tried to replace invalid arg %d >= %d",
+ which, args->num);
+ xfree(args->list[which]);
+ args->list[which] = cp;
+}
+
+void
+freeargs(arglist *args)
+{
+ u_int i;
+
+ if (args->list != NULL) {
+ for (i = 0; i < args->num; i++)
+ xfree(args->list[i]);
+ xfree(args->list);
+ args->nalloc = args->num = 0;
+ args->list = NULL;
+ }
+}
+
/*
* Expands tildes in the file name. Returns data allocated by xmalloc.
* Warning: this calls getpw*.
{
#if defined(CUSTOM_SYS_TUN_OPEN)
return (sys_tun_open(tun, mode));
-#elif defined(SSH_TUN_BSD)
+#elif defined(SSH_TUN_OPENBSD)
struct ifreq ifr;
char name[100];
int fd = -1, sock;
break;
}
} else {
- debug("%s: invalid tunnel %u\n", __func__, tun);
+ debug("%s: invalid tunnel %u", __func__, tun);
return (-1);
}
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
goto failed;
- if (mode == SSH_TUNMODE_ETHERNET) {
+
+ /* Set interface mode */
+ ifr.ifr_flags &= ~IFF_UP;
+ if (mode == SSH_TUNMODE_ETHERNET)
ifr.ifr_flags |= IFF_LINK0;
- if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
- goto failed;
- }
+ else
+ ifr.ifr_flags &= ~IFF_LINK0;
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
+ goto failed;
+
+ /* Bring interface up */
ifr.ifr_flags |= IFF_UP;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
goto failed;
void
sanitise_stdfd(void)
{
- int nullfd;
+ int nullfd, dupfd;
- if ((nullfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
exit(1);
}
- while (nullfd < 2) {
- if (dup2(nullfd, nullfd + 1) == -1) {
+ while (++dupfd <= 2) {
+ /* Only clobber closed fds */
+ if (fcntl(dupfd, F_GETFL, 0) >= 0)
+ continue;
+ if (dup2(nullfd, dupfd) == -1) {
fprintf(stderr, "dup2: %s", strerror(errno));
exit(1);
}
- nullfd++;
}
if (nullfd > 2)
close(nullfd);
u_int i, hl;
hl = l * 2 + 1;
- r = xmalloc(hl);
- *r = '\0';
+ r = xcalloc(1, hl);
for (i = 0; i < l; i++) {
snprintf(b, sizeof(b), "%02x", d[i]);
strlcat(r, b, hl);