summaryrefslogtreecommitdiff
path: root/sshbuf-getput-basic.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 13:33:15 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 14:27:30 +0100
commitf0b009aea83e9ff3a50be30f51012099a5143c16 (patch)
tree3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /sshbuf-getput-basic.c
parent47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff)
parent762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (diff)
Merge 6.7p1.
* New upstream release (http://www.openssh.com/txt/release-6.7): - sshd(8): The default set of ciphers and MACs has been altered to remove unsafe algorithms. In particular, CBC ciphers and arcfour* are disabled by default. The full set of algorithms remains available if configured explicitly via the Ciphers and MACs sshd_config options. - ssh(1), sshd(8): Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket (closes: #236718). - ssh(1), ssh-keygen(1): Add support for SSHFP DNS records for ED25519 key types. - sftp(1): Allow resumption of interrupted uploads. - ssh(1): When rekeying, skip file/DNS lookups of the hostkey if it is the same as the one sent during initial key exchange. - sshd(8): Allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family. - sshd(8): Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option. - ssh(1): Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a hash of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding miserly pathname limits for Unix domain sockets in multiplexing control paths. - sshd(8): Make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages. - Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It considers time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly (closes: #734553). - Use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}. * Restore TCP wrappers support, removed upstream in 6.7. It is true that dropping this reduces preauth attack surface in sshd. On the other hand, this support seems to be quite widely used, and abruptly dropping it (from the perspective of users who don't read openssh-unix-dev) could easily cause more serious problems in practice. It's not entirely clear what the right long-term answer for Debian is, but it at least probably doesn't involve dropping this feature shortly before a freeze. * Replace patch to disable OpenSSL version check with an updated version of Kurt Roeckx's patch from #732940 to just avoid checking the status field.
Diffstat (limited to 'sshbuf-getput-basic.c')
-rw-r--r--sshbuf-getput-basic.c421
1 files changed, 421 insertions, 0 deletions
diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c
new file mode 100644
index 000000000..b7d0758c2
--- /dev/null
+++ b/sshbuf-getput-basic.c
@@ -0,0 +1,421 @@
1/* $OpenBSD: sshbuf-getput-basic.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#define SSHBUF_INTERNAL
19#include "includes.h"
20
21#include <sys/types.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25
26#include "ssherr.h"
27#include "sshbuf.h"
28
29int
30sshbuf_get(struct sshbuf *buf, void *v, size_t len)
31{
32 const u_char *p = sshbuf_ptr(buf);
33 int r;
34
35 if ((r = sshbuf_consume(buf, len)) < 0)
36 return r;
37 if (v != NULL)
38 memcpy(v, p, len);
39 return 0;
40}
41
42int
43sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp)
44{
45 const u_char *p = sshbuf_ptr(buf);
46 int r;
47
48 if ((r = sshbuf_consume(buf, 8)) < 0)
49 return r;
50 if (valp != NULL)
51 *valp = PEEK_U64(p);
52 return 0;
53}
54
55int
56sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp)
57{
58 const u_char *p = sshbuf_ptr(buf);
59 int r;
60
61 if ((r = sshbuf_consume(buf, 4)) < 0)
62 return r;
63 if (valp != NULL)
64 *valp = PEEK_U32(p);
65 return 0;
66}
67
68int
69sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp)
70{
71 const u_char *p = sshbuf_ptr(buf);
72 int r;
73
74 if ((r = sshbuf_consume(buf, 2)) < 0)
75 return r;
76 if (valp != NULL)
77 *valp = PEEK_U16(p);
78 return 0;
79}
80
81int
82sshbuf_get_u8(struct sshbuf *buf, u_char *valp)
83{
84 const u_char *p = sshbuf_ptr(buf);
85 int r;
86
87 if ((r = sshbuf_consume(buf, 1)) < 0)
88 return r;
89 if (valp != NULL)
90 *valp = (u_int8_t)*p;
91 return 0;
92}
93
94int
95sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
96{
97 const u_char *val;
98 size_t len;
99 int r;
100
101 if (valp != NULL)
102 *valp = NULL;
103 if (lenp != NULL)
104 *lenp = 0;
105 if ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0)
106 return r;
107 if (valp != NULL) {
108 if ((*valp = malloc(len + 1)) == NULL) {
109 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL"));
110 return SSH_ERR_ALLOC_FAIL;
111 }
112 memcpy(*valp, val, len);
113 (*valp)[len] = '\0';
114 }
115 if (lenp != NULL)
116 *lenp = len;
117 return 0;
118}
119
120int
121sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp)
122{
123 size_t len;
124 const u_char *p;
125 int r;
126
127 if (valp != NULL)
128 *valp = NULL;
129 if (lenp != NULL)
130 *lenp = 0;
131 if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0)
132 return r;
133 if (valp != 0)
134 *valp = p;
135 if (lenp != NULL)
136 *lenp = len;
137 if (sshbuf_consume(buf, len + 4) != 0) {
138 /* Shouldn't happen */
139 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
140 SSHBUF_ABORT();
141 return SSH_ERR_INTERNAL_ERROR;
142 }
143 return 0;
144}
145
146int
147sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
148 size_t *lenp)
149{
150 u_int32_t len;
151 const u_char *p = sshbuf_ptr(buf);
152
153 if (valp != NULL)
154 *valp = NULL;
155 if (lenp != NULL)
156 *lenp = 0;
157 if (sshbuf_len(buf) < 4) {
158 SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE"));
159 return SSH_ERR_MESSAGE_INCOMPLETE;
160 }
161 len = PEEK_U32(p);
162 if (len > SSHBUF_SIZE_MAX - 4) {
163 SSHBUF_DBG(("SSH_ERR_STRING_TOO_LARGE"));
164 return SSH_ERR_STRING_TOO_LARGE;
165 }
166 if (sshbuf_len(buf) - 4 < len) {
167 SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE"));
168 return SSH_ERR_MESSAGE_INCOMPLETE;
169 }
170 if (valp != 0)
171 *valp = p + 4;
172 if (lenp != NULL)
173 *lenp = len;
174 return 0;
175}
176
177int
178sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp)
179{
180 size_t len;
181 const u_char *p, *z;
182 int r;
183
184 if (valp != NULL)
185 *valp = NULL;
186 if (lenp != NULL)
187 *lenp = 0;
188 if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)
189 return r;
190 /* Allow a \0 only at the end of the string */
191 if (len > 0 &&
192 (z = memchr(p , '\0', len)) != NULL && z < p + len - 1) {
193 SSHBUF_DBG(("SSH_ERR_INVALID_FORMAT"));
194 return SSH_ERR_INVALID_FORMAT;
195 }
196 if ((r = sshbuf_skip_string(buf)) != 0)
197 return -1;
198 if (valp != NULL) {
199 if ((*valp = malloc(len + 1)) == NULL) {
200 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL"));
201 return SSH_ERR_ALLOC_FAIL;
202 }
203 memcpy(*valp, p, len);
204 (*valp)[len] = '\0';
205 }
206 if (lenp != NULL)
207 *lenp = (size_t)len;
208 return 0;
209}
210
211int
212sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v)
213{
214 u_int32_t len;
215 u_char *p;
216 int r;
217
218 /*
219 * Use sshbuf_peek_string_direct() to figure out if there is
220 * a complete string in 'buf' and copy the string directly
221 * into 'v'.
222 */
223 if ((r = sshbuf_peek_string_direct(buf, NULL, NULL)) != 0 ||
224 (r = sshbuf_get_u32(buf, &len)) != 0 ||
225 (r = sshbuf_reserve(v, len, &p)) != 0 ||
226 (r = sshbuf_get(buf, p, len)) != 0)
227 return r;
228 return 0;
229}
230
231int
232sshbuf_put(struct sshbuf *buf, const void *v, size_t len)
233{
234 u_char *p;
235 int r;
236
237 if ((r = sshbuf_reserve(buf, len, &p)) < 0)
238 return r;
239 memcpy(p, v, len);
240 return 0;
241}
242
243int
244sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v)
245{
246 return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v));
247}
248
249int
250sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
251{
252 va_list ap;
253 int r;
254
255 va_start(ap, fmt);
256 r = sshbuf_putfv(buf, fmt, ap);
257 va_end(ap);
258 return r;
259}
260
261int
262sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap)
263{
264 va_list ap2;
265 int r, len;
266 u_char *p;
267
268 va_copy(ap2, ap);
269 if ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) {
270 r = SSH_ERR_INVALID_ARGUMENT;
271 goto out;
272 }
273 if (len == 0) {
274 r = 0;
275 goto out; /* Nothing to do */
276 }
277 va_end(ap2);
278 va_copy(ap2, ap);
279 if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0)
280 goto out;
281 if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) {
282 r = SSH_ERR_INTERNAL_ERROR;
283 goto out; /* Shouldn't happen */
284 }
285 /* Consume terminating \0 */
286 if ((r = sshbuf_consume_end(buf, 1)) != 0)
287 goto out;
288 r = 0;
289 out:
290 va_end(ap2);
291 return r;
292}
293
294int
295sshbuf_put_u64(struct sshbuf *buf, u_int64_t val)
296{
297 u_char *p;
298 int r;
299
300 if ((r = sshbuf_reserve(buf, 8, &p)) < 0)
301 return r;
302 POKE_U64(p, val);
303 return 0;
304}
305
306int
307sshbuf_put_u32(struct sshbuf *buf, u_int32_t val)
308{
309 u_char *p;
310 int r;
311
312 if ((r = sshbuf_reserve(buf, 4, &p)) < 0)
313 return r;
314 POKE_U32(p, val);
315 return 0;
316}
317
318int
319sshbuf_put_u16(struct sshbuf *buf, u_int16_t val)
320{
321 u_char *p;
322 int r;
323
324 if ((r = sshbuf_reserve(buf, 2, &p)) < 0)
325 return r;
326 POKE_U16(p, val);
327 return 0;
328}
329
330int
331sshbuf_put_u8(struct sshbuf *buf, u_char val)
332{
333 u_char *p;
334 int r;
335
336 if ((r = sshbuf_reserve(buf, 1, &p)) < 0)
337 return r;
338 p[0] = val;
339 return 0;
340}
341
342int
343sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
344{
345 u_char *d;
346 int r;
347
348 if (len > SSHBUF_SIZE_MAX - 4) {
349 SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE"));
350 return SSH_ERR_NO_BUFFER_SPACE;
351 }
352 if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0)
353 return r;
354 POKE_U32(d, len);
355 memcpy(d + 4, v, len);
356 return 0;
357}
358
359int
360sshbuf_put_cstring(struct sshbuf *buf, const char *v)
361{
362 return sshbuf_put_string(buf, (u_char *)v, strlen(v));
363}
364
365int
366sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v)
367{
368 return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v));
369}
370
371int
372sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp)
373{
374 const u_char *p;
375 size_t len;
376 struct sshbuf *ret;
377 int r;
378
379 if (buf == NULL || bufp == NULL)
380 return SSH_ERR_INVALID_ARGUMENT;
381 *bufp = NULL;
382 if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)
383 return r;
384 if ((ret = sshbuf_from(p, len)) == NULL)
385 return SSH_ERR_ALLOC_FAIL;
386 if ((r = sshbuf_consume(buf, len + 4)) != 0 || /* Shouldn't happen */
387 (r = sshbuf_set_parent(ret, buf)) != 0) {
388 sshbuf_free(ret);
389 return r;
390 }
391 *bufp = ret;
392 return 0;
393}
394
395int
396sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len)
397{
398 u_char *d;
399 const u_char *s = (const u_char *)v;
400 int r, prepend;
401
402 if (len > SSHBUF_SIZE_MAX - 5) {
403 SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE"));
404 return SSH_ERR_NO_BUFFER_SPACE;
405 }
406 /* Skip leading zero bytes */
407 for (; len > 0 && *s == 0; len--, s++)
408 ;
409 /*
410 * If most significant bit is set then prepend a zero byte to
411 * avoid interpretation as a negative number.
412 */
413 prepend = len > 0 && (s[0] & 0x80) != 0;
414 if ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0)
415 return r;
416 POKE_U32(d, len + prepend);
417 if (prepend)
418 d[4] = 0;
419 memcpy(d + 4 + prepend, s, len);
420 return 0;
421}