summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c159
1 files changed, 147 insertions, 12 deletions
diff --git a/misc.c b/misc.c
index 29e928886..625a34368 100644
--- a/misc.c
+++ b/misc.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: misc.c,v 1.65 2006/11/23 01:35:11 ray Exp $ */
1/* 2/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 * Copyright (c) 2005 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -24,15 +25,35 @@
24 */ 25 */
25 26
26#include "includes.h" 27#include "includes.h"
27RCSID("$OpenBSD: misc.c,v 1.42 2006/01/31 10:19:02 djm Exp $");
28 28
29#include <sys/types.h>
30#include <sys/ioctl.h>
31#include <sys/socket.h>
32#include <sys/param.h>
33
34#include <stdarg.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39
40#include <netinet/in.h>
41#include <netinet/tcp.h>
42
43#include <errno.h>
44#include <fcntl.h>
45#ifdef HAVE_PATHS_H
46# include <paths.h>
47#include <pwd.h>
48#endif
29#ifdef SSH_TUN_OPENBSD 49#ifdef SSH_TUN_OPENBSD
30#include <net/if.h> 50#include <net/if.h>
31#endif 51#endif
32 52
53#include "xmalloc.h"
33#include "misc.h" 54#include "misc.h"
34#include "log.h" 55#include "log.h"
35#include "xmalloc.h" 56#include "ssh.h"
36 57
37/* remove newline at end of string */ 58/* remove newline at end of string */
38char * 59char *
@@ -123,6 +144,7 @@ set_nodelay(int fd)
123 144
124/* Characters considered whitespace in strsep calls. */ 145/* Characters considered whitespace in strsep calls. */
125#define WHITESPACE " \t\r\n" 146#define WHITESPACE " \t\r\n"
147#define QUOTE "\""
126 148
127/* return next token in configuration line */ 149/* return next token in configuration line */
128char * 150char *
@@ -136,15 +158,27 @@ strdelim(char **s)
136 158
137 old = *s; 159 old = *s;
138 160
139 *s = strpbrk(*s, WHITESPACE "="); 161 *s = strpbrk(*s, WHITESPACE QUOTE "=");
140 if (*s == NULL) 162 if (*s == NULL)
141 return (old); 163 return (old);
142 164
165 if (*s[0] == '\"') {
166 memmove(*s, *s + 1, strlen(*s)); /* move nul too */
167 /* Find matching quote */
168 if ((*s = strpbrk(*s, QUOTE)) == NULL) {
169 return (NULL); /* no matching quote */
170 } else {
171 *s[0] = '\0';
172 return (old);
173 }
174 }
175
143 /* Allow only one '=' to be skipped */ 176 /* Allow only one '=' to be skipped */
144 if (*s[0] == '=') 177 if (*s[0] == '=')
145 wspace = 1; 178 wspace = 1;
146 *s[0] = '\0'; 179 *s[0] = '\0';
147 180
181 /* Skip any extra whitespace after first token */
148 *s += strspn(*s + 1, WHITESPACE) + 1; 182 *s += strspn(*s + 1, WHITESPACE) + 1;
149 if (*s[0] == '=' && !wspace) 183 if (*s[0] == '=' && !wspace)
150 *s += strspn(*s + 1, WHITESPACE) + 1; 184 *s += strspn(*s + 1, WHITESPACE) + 1;
@@ -155,9 +189,8 @@ strdelim(char **s)
155struct passwd * 189struct passwd *
156pwcopy(struct passwd *pw) 190pwcopy(struct passwd *pw)
157{ 191{
158 struct passwd *copy = xmalloc(sizeof(*copy)); 192 struct passwd *copy = xcalloc(1, sizeof(*copy));
159 193
160 memset(copy, 0, sizeof(*copy));
161 copy->pw_name = xstrdup(pw->pw_name); 194 copy->pw_name = xstrdup(pw->pw_name);
162 copy->pw_passwd = xstrdup(pw->pw_passwd); 195 copy->pw_passwd = xstrdup(pw->pw_passwd);
163 copy->pw_gecos = xstrdup(pw->pw_gecos); 196 copy->pw_gecos = xstrdup(pw->pw_gecos);
@@ -280,6 +313,7 @@ convtime(const char *s)
280 switch (*endp++) { 313 switch (*endp++) {
281 case '\0': 314 case '\0':
282 endp--; 315 endp--;
316 break;
283 case 's': 317 case 's':
284 case 'S': 318 case 'S':
285 break; 319 break;
@@ -312,6 +346,23 @@ convtime(const char *s)
312} 346}
313 347
314/* 348/*
349 * Returns a standardized host+port identifier string.
350 * Caller must free returned string.
351 */
352char *
353put_host_port(const char *host, u_short port)
354{
355 char *hoststr;
356
357 if (port == 0 || port == SSH_DEFAULT_PORT)
358 return(xstrdup(host));
359 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
360 fatal("put_host_port: asprintf: %s", strerror(errno));
361 debug3("put_host_port: %s", hoststr);
362 return hoststr;
363}
364
365/*
315 * Search for next delimiter between hostnames/addresses and ports. 366 * Search for next delimiter between hostnames/addresses and ports.
316 * Argument may be modified (for termination). 367 * Argument may be modified (for termination).
317 * Returns *cp if parsing succeeds. 368 * Returns *cp if parsing succeeds.
@@ -408,7 +459,7 @@ addargs(arglist *args, char *fmt, ...)
408 } else if (args->num+2 >= nalloc) 459 } else if (args->num+2 >= nalloc)
409 nalloc *= 2; 460 nalloc *= 2;
410 461
411 args->list = xrealloc(args->list, nalloc * sizeof(char *)); 462 args->list = xrealloc(args->list, nalloc, sizeof(char *));
412 args->nalloc = nalloc; 463 args->nalloc = nalloc;
413 args->list[args->num++] = cp; 464 args->list[args->num++] = cp;
414 args->list[args->num] = NULL; 465 args->list[args->num] = NULL;
@@ -565,6 +616,8 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
565 u_long *lineno) 616 u_long *lineno)
566{ 617{
567 while (fgets(buf, bufsz, f) != NULL) { 618 while (fgets(buf, bufsz, f) != NULL) {
619 if (buf[0] == '\0')
620 continue;
568 (*lineno)++; 621 (*lineno)++;
569 if (buf[strlen(buf) - 1] == '\n' || feof(f)) { 622 if (buf[strlen(buf) - 1] == '\n' || feof(f)) {
570 return 0; 623 return 0;
@@ -673,18 +726,100 @@ sanitise_stdfd(void)
673} 726}
674 727
675char * 728char *
676tohex(const u_char *d, u_int l) 729tohex(const void *vp, size_t l)
677{ 730{
731 const u_char *p = (const u_char *)vp;
678 char b[3], *r; 732 char b[3], *r;
679 u_int i, hl; 733 size_t i, hl;
734
735 if (l > 65536)
736 return xstrdup("tohex: length > 65536");
680 737
681 hl = l * 2 + 1; 738 hl = l * 2 + 1;
682 r = xmalloc(hl); 739 r = xcalloc(1, hl);
683 *r = '\0';
684 for (i = 0; i < l; i++) { 740 for (i = 0; i < l; i++) {
685 snprintf(b, sizeof(b), "%02x", d[i]); 741 snprintf(b, sizeof(b), "%02x", p[i]);
686 strlcat(r, b, hl); 742 strlcat(r, b, hl);
687 } 743 }
688 return (r); 744 return (r);
689} 745}
690 746
747u_int64_t
748get_u64(const void *vp)
749{
750 const u_char *p = (const u_char *)vp;
751 u_int64_t v;
752
753 v = (u_int64_t)p[0] << 56;
754 v |= (u_int64_t)p[1] << 48;
755 v |= (u_int64_t)p[2] << 40;
756 v |= (u_int64_t)p[3] << 32;
757 v |= (u_int64_t)p[4] << 24;
758 v |= (u_int64_t)p[5] << 16;
759 v |= (u_int64_t)p[6] << 8;
760 v |= (u_int64_t)p[7];
761
762 return (v);
763}
764
765u_int32_t
766get_u32(const void *vp)
767{
768 const u_char *p = (const u_char *)vp;
769 u_int32_t v;
770
771 v = (u_int32_t)p[0] << 24;
772 v |= (u_int32_t)p[1] << 16;
773 v |= (u_int32_t)p[2] << 8;
774 v |= (u_int32_t)p[3];
775
776 return (v);
777}
778
779u_int16_t
780get_u16(const void *vp)
781{
782 const u_char *p = (const u_char *)vp;
783 u_int16_t v;
784
785 v = (u_int16_t)p[0] << 8;
786 v |= (u_int16_t)p[1];
787
788 return (v);
789}
790
791void
792put_u64(void *vp, u_int64_t v)
793{
794 u_char *p = (u_char *)vp;
795
796 p[0] = (u_char)(v >> 56) & 0xff;
797 p[1] = (u_char)(v >> 48) & 0xff;
798 p[2] = (u_char)(v >> 40) & 0xff;
799 p[3] = (u_char)(v >> 32) & 0xff;
800 p[4] = (u_char)(v >> 24) & 0xff;
801 p[5] = (u_char)(v >> 16) & 0xff;
802 p[6] = (u_char)(v >> 8) & 0xff;
803 p[7] = (u_char)v & 0xff;
804}
805
806void
807put_u32(void *vp, u_int32_t v)
808{
809 u_char *p = (u_char *)vp;
810
811 p[0] = (u_char)(v >> 24) & 0xff;
812 p[1] = (u_char)(v >> 16) & 0xff;
813 p[2] = (u_char)(v >> 8) & 0xff;
814 p[3] = (u_char)v & 0xff;
815}
816
817
818void
819put_u16(void *vp, u_int16_t v)
820{
821 u_char *p = (u_char *)vp;
822
823 p[0] = (u_char)(v >> 8) & 0xff;
824 p[1] = (u_char)v & 0xff;
825}