Mercurial > dropbear
annotate fake-rfc2553.c @ 1306:34e6127ef02e
merge fixes from PuTTY import.c
toint() from misc.c
(revids are from hggit conversion)
changeset: 4620:60a336a6c85c
user: Simon Tatham <[email protected]>
date: Thu Feb 25 20:26:33 2016 +0000
files: import.c
description:
Fix potential segfaults in reading OpenSSH's ASN.1 key format.
The length coming back from ber_read_id_len might have overflowed, so
treat it as potentially negative. Also, while I'm here, accumulate it
inside ber_read_id_len as an unsigned, so as to avoid undefined
behaviour on integer overflow, and toint() it before return.
Thanks to Hanno Böck for spotting this, with the aid of AFL.
(cherry picked from commit 5b7833cd474a24ec098654dcba8cb9509f3bf2c1)
Conflicts:
import.c
(cherry-picker's note: resolving the conflict involved removing an
entire section of the original commit which fixed ECDSA code not
present on this branch)
changeset: 4619:9c6c638d98d8
user: Simon Tatham <[email protected]>
date: Sun Jul 14 10:45:54 2013 +0000
files: import.c ssh.c sshdss.c sshpubk.c sshrsa.c
description:
Tighten up a lot of casts from unsigned to int which are read by one
of the GET_32BIT macros and then used as length fields. Missing bounds
checks against zero have been added, and also I've introduced a helper
function toint() which casts from unsigned to int in such a way as to
avoid C undefined behaviour, since I'm not sure I trust compilers any
more to do the obviously sensible thing.
[originally from svn r9918]
changeset: 4618:3957829f24d3
user: Simon Tatham <[email protected]>
date: Mon Jul 08 22:36:04 2013 +0000
files: import.c sshdss.c sshrsa.c
description:
Add an assortment of extra safety checks.
[originally from svn r9896]
changeset: 4617:2cddee0bce12
user: Jacob Nevins <[email protected]>
date: Wed Dec 07 00:24:45 2005 +0000
files: import.c
description:
Institutional failure to memset() things pointed at rather than pointers.
Things should now be zeroed and memory not leaked. Spotted by Brant Thomsen.
[originally from svn r6476]
changeset: 4616:24ac78a9c71d
user: Simon Tatham <[email protected]>
date: Wed Feb 11 13:58:27 2004 +0000
files: import.c
description:
Jacob's last-minute testing found a couple of trivial bugs in
import.c, and my attempts to reproduce them in cmdgen found another
one there :-)
[originally from svn r3847]
changeset: 4615:088d39a73db0
user: Simon Tatham <[email protected]>
date: Thu Jan 22 18:52:49 2004 +0000
files: import.c
description:
Placate some gcc warnings.
[originally from svn r3761]
changeset: 4614:e4288bad4d93
parent: 1758:108b8924593d
user: Simon Tatham <[email protected]>
date: Fri Oct 03 21:21:23 2003 +0000
files: import.c
description:
My ASN.1 decoder returned wrong IDs for anything above 0x1E! Good
job it's never had to yet. Ahem.
[originally from svn r3479]
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 12 Jul 2016 23:00:01 +0800 |
parents | 9fd27bc37807 |
children |
rev | line source |
---|---|
589
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
1 /* Taken for Dropbear from OpenSSH 5.5p1 */ |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
2 |
64 | 3 /* |
4 * Copyright (C) 2000-2003 Damien Miller. All rights reserved. | |
5 * Copyright (C) 1999 WIDE Project. All rights reserved. | |
6 * | |
7 * Redistribution and use in source and binary forms, with or without | |
8 * modification, are permitted provided that the following conditions | |
9 * are met: | |
10 * 1. Redistributions of source code must retain the above copyright | |
11 * notice, this list of conditions and the following disclaimer. | |
12 * 2. Redistributions in binary form must reproduce the above copyright | |
13 * notice, this list of conditions and the following disclaimer in the | |
14 * documentation and/or other materials provided with the distribution. | |
15 * 3. Neither the name of the project nor the names of its contributors | |
16 * may be used to endorse or promote products derived from this software | |
17 * without specific prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | |
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 * SUCH DAMAGE. | |
30 */ | |
31 | |
32 /* | |
33 * Pseudo-implementation of RFC2553 name / address resolution functions | |
34 * | |
35 * But these functions are not implemented correctly. The minimum subset | |
36 * is implemented for ssh use only. For example, this routine assumes | |
37 * that ai_family is AF_INET. Don't use it for another purpose. | |
38 */ | |
39 | |
40 #include "includes.h" | |
41 | |
589
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
42 #include <stdlib.h> |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
43 #include <string.h> |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
44 |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
45 #include <netinet/in.h> |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
46 #include <arpa/inet.h> |
64 | 47 |
48 #ifndef HAVE_GETNAMEINFO | |
49 int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, | |
50 size_t hostlen, char *serv, size_t servlen, int flags) | |
51 { | |
52 struct sockaddr_in *sin = (struct sockaddr_in *)sa; | |
53 struct hostent *hp; | |
54 char tmpserv[16]; | |
55 | |
589
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
56 if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
57 return (EAI_FAMILY); |
64 | 58 if (serv != NULL) { |
59 snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); | |
60 if (strlcpy(serv, tmpserv, servlen) >= servlen) | |
61 return (EAI_MEMORY); | |
62 } | |
63 | |
64 if (host != NULL) { | |
65 if (flags & NI_NUMERICHOST) { | |
66 if (strlcpy(host, inet_ntoa(sin->sin_addr), | |
67 hostlen) >= hostlen) | |
68 return (EAI_MEMORY); | |
69 else | |
70 return (0); | |
71 } else { | |
72 hp = gethostbyaddr((char *)&sin->sin_addr, | |
73 sizeof(struct in_addr), AF_INET); | |
74 if (hp == NULL) | |
75 return (EAI_NODATA); | |
76 | |
77 if (strlcpy(host, hp->h_name, hostlen) >= hostlen) | |
78 return (EAI_MEMORY); | |
79 else | |
80 return (0); | |
81 } | |
82 } | |
83 return (0); | |
84 } | |
85 #endif /* !HAVE_GETNAMEINFO */ | |
86 | |
87 #ifndef HAVE_GAI_STRERROR | |
88 #ifdef HAVE_CONST_GAI_STRERROR_PROTO | |
89 const char * | |
90 #else | |
91 char * | |
92 #endif | |
93 gai_strerror(int err) | |
94 { | |
95 switch (err) { | |
96 case EAI_NODATA: | |
97 return ("no address associated with name"); | |
98 case EAI_MEMORY: | |
99 return ("memory allocation failure."); | |
100 case EAI_NONAME: | |
101 return ("nodename nor servname provided, or not known"); | |
589
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
102 case EAI_FAMILY: |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
103 return ("ai_family not supported"); |
64 | 104 default: |
105 return ("unknown/invalid error."); | |
106 } | |
107 } | |
108 #endif /* !HAVE_GAI_STRERROR */ | |
109 | |
110 #ifndef HAVE_FREEADDRINFO | |
111 void | |
112 freeaddrinfo(struct addrinfo *ai) | |
113 { | |
114 struct addrinfo *next; | |
115 | |
116 for(; ai != NULL;) { | |
117 next = ai->ai_next; | |
118 free(ai); | |
119 ai = next; | |
120 } | |
121 } | |
122 #endif /* !HAVE_FREEADDRINFO */ | |
123 | |
124 #ifndef HAVE_GETADDRINFO | |
125 static struct | |
126 addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) | |
127 { | |
128 struct addrinfo *ai; | |
129 | |
130 ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); | |
131 if (ai == NULL) | |
132 return (NULL); | |
133 | |
134 memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); | |
135 | |
136 ai->ai_addr = (struct sockaddr *)(ai + 1); | |
137 /* XXX -- ssh doesn't use sa_len */ | |
138 ai->ai_addrlen = sizeof(struct sockaddr_in); | |
139 ai->ai_addr->sa_family = ai->ai_family = AF_INET; | |
140 | |
141 ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; | |
142 ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; | |
143 | |
144 /* XXX: the following is not generally correct, but does what we want */ | |
145 if (hints->ai_socktype) | |
146 ai->ai_socktype = hints->ai_socktype; | |
147 else | |
148 ai->ai_socktype = SOCK_STREAM; | |
149 | |
150 if (hints->ai_protocol) | |
151 ai->ai_protocol = hints->ai_protocol; | |
152 | |
153 return (ai); | |
154 } | |
155 | |
156 int | |
157 getaddrinfo(const char *hostname, const char *servname, | |
158 const struct addrinfo *hints, struct addrinfo **res) | |
159 { | |
160 struct hostent *hp; | |
161 struct servent *sp; | |
162 struct in_addr in; | |
163 int i; | |
164 long int port; | |
165 u_long addr; | |
166 | |
167 port = 0; | |
589
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
168 if (hints && hints->ai_family != AF_UNSPEC && |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
169 hints->ai_family != AF_INET) |
9fd27bc37807
- Update fake-rfc2553.{c,h} from OpenSSH 5.5p1
Matt Johnston <matt@ucc.asn.au>
parents:
67
diff
changeset
|
170 return (EAI_FAMILY); |
64 | 171 if (servname != NULL) { |
172 char *cp; | |
173 | |
174 port = strtol(servname, &cp, 10); | |
175 if (port > 0 && port <= 65535 && *cp == '\0') | |
176 port = htons(port); | |
177 else if ((sp = getservbyname(servname, NULL)) != NULL) | |
178 port = sp->s_port; | |
179 else | |
180 port = 0; | |
181 } | |
182 | |
183 if (hints && hints->ai_flags & AI_PASSIVE) { | |
184 addr = htonl(0x00000000); | |
185 if (hostname && inet_aton(hostname, &in) != 0) | |
186 addr = in.s_addr; | |
187 *res = malloc_ai(port, addr, hints); | |
188 if (*res == NULL) | |
189 return (EAI_MEMORY); | |
190 return (0); | |
191 } | |
192 | |
193 if (!hostname) { | |
194 *res = malloc_ai(port, htonl(0x7f000001), hints); | |
195 if (*res == NULL) | |
196 return (EAI_MEMORY); | |
197 return (0); | |
198 } | |
199 | |
200 if (inet_aton(hostname, &in)) { | |
201 *res = malloc_ai(port, in.s_addr, hints); | |
202 if (*res == NULL) | |
203 return (EAI_MEMORY); | |
204 return (0); | |
205 } | |
206 | |
207 /* Don't try DNS if AI_NUMERICHOST is set */ | |
208 if (hints && hints->ai_flags & AI_NUMERICHOST) | |
209 return (EAI_NONAME); | |
210 | |
211 hp = gethostbyname(hostname); | |
212 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { | |
213 struct addrinfo *cur, *prev; | |
214 | |
215 cur = prev = *res = NULL; | |
216 for (i = 0; hp->h_addr_list[i]; i++) { | |
217 struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; | |
218 | |
219 cur = malloc_ai(port, in->s_addr, hints); | |
220 if (cur == NULL) { | |
221 if (*res != NULL) | |
222 freeaddrinfo(*res); | |
223 return (EAI_MEMORY); | |
224 } | |
225 if (prev) | |
226 prev->ai_next = cur; | |
227 else | |
228 *res = cur; | |
229 | |
230 prev = cur; | |
231 } | |
232 return (0); | |
233 } | |
234 | |
235 return (EAI_NODATA); | |
236 } | |
237 #endif /* !HAVE_GETADDRINFO */ |