bufaux.c revision 204917
1/* $OpenBSD: bufaux.c,v 1.48 2010/02/02 22:49:34 djm Exp $ */ 2/* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * Auxiliary functions for storing and retrieving various data types to/from 7 * Buffers. 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 * 15 * 16 * SSH2 packet format added by Markus Friedl 17 * Copyright (c) 2000 Markus Friedl. All rights reserved. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40#include "includes.h" 41 42#include <sys/types.h> 43 44#include <openssl/bn.h> 45 46#include <string.h> 47#include <stdarg.h> 48 49#include "xmalloc.h" 50#include "buffer.h" 51#include "log.h" 52#include "misc.h" 53 54/* 55 * Returns integers from the buffer (msb first). 56 */ 57 58int 59buffer_get_short_ret(u_short *ret, Buffer *buffer) 60{ 61 u_char buf[2]; 62 63 if (buffer_get_ret(buffer, (char *) buf, 2) == -1) 64 return (-1); 65 *ret = get_u16(buf); 66 return (0); 67} 68 69u_short 70buffer_get_short(Buffer *buffer) 71{ 72 u_short ret; 73 74 if (buffer_get_short_ret(&ret, buffer) == -1) 75 fatal("buffer_get_short: buffer error"); 76 77 return (ret); 78} 79 80int 81buffer_get_int_ret(u_int *ret, Buffer *buffer) 82{ 83 u_char buf[4]; 84 85 if (buffer_get_ret(buffer, (char *) buf, 4) == -1) 86 return (-1); 87 *ret = get_u32(buf); 88 return (0); 89} 90 91u_int 92buffer_get_int(Buffer *buffer) 93{ 94 u_int ret; 95 96 if (buffer_get_int_ret(&ret, buffer) == -1) 97 fatal("buffer_get_int: buffer error"); 98 99 return (ret); 100} 101 102int 103buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer) 104{ 105 u_char buf[8]; 106 107 if (buffer_get_ret(buffer, (char *) buf, 8) == -1) 108 return (-1); 109 *ret = get_u64(buf); 110 return (0); 111} 112 113u_int64_t 114buffer_get_int64(Buffer *buffer) 115{ 116 u_int64_t ret; 117 118 if (buffer_get_int64_ret(&ret, buffer) == -1) 119 fatal("buffer_get_int: buffer error"); 120 121 return (ret); 122} 123 124/* 125 * Stores integers in the buffer, msb first. 126 */ 127void 128buffer_put_short(Buffer *buffer, u_short value) 129{ 130 char buf[2]; 131 132 put_u16(buf, value); 133 buffer_append(buffer, buf, 2); 134} 135 136void 137buffer_put_int(Buffer *buffer, u_int value) 138{ 139 char buf[4]; 140 141 put_u32(buf, value); 142 buffer_append(buffer, buf, 4); 143} 144 145void 146buffer_put_int64(Buffer *buffer, u_int64_t value) 147{ 148 char buf[8]; 149 150 put_u64(buf, value); 151 buffer_append(buffer, buf, 8); 152} 153 154/* 155 * Returns an arbitrary binary string from the buffer. The string cannot 156 * be longer than 256k. The returned value points to memory allocated 157 * with xmalloc; it is the responsibility of the calling function to free 158 * the data. If length_ptr is non-NULL, the length of the returned data 159 * will be stored there. A null character will be automatically appended 160 * to the returned string, and is not counted in length. 161 */ 162void * 163buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) 164{ 165 u_char *value; 166 u_int len; 167 168 /* Get the length. */ 169 if (buffer_get_int_ret(&len, buffer) != 0) { 170 error("buffer_get_string_ret: cannot extract length"); 171 return (NULL); 172 } 173 if (len > 256 * 1024) { 174 error("buffer_get_string_ret: bad string length %u", len); 175 return (NULL); 176 } 177 /* Allocate space for the string. Add one byte for a null character. */ 178 value = xmalloc(len + 1); 179 /* Get the string. */ 180 if (buffer_get_ret(buffer, value, len) == -1) { 181 error("buffer_get_string_ret: buffer_get failed"); 182 xfree(value); 183 return (NULL); 184 } 185 /* Append a null character to make processing easier. */ 186 value[len] = '\0'; 187 /* Optionally return the length of the string. */ 188 if (length_ptr) 189 *length_ptr = len; 190 return (value); 191} 192 193void * 194buffer_get_string(Buffer *buffer, u_int *length_ptr) 195{ 196 void *ret; 197 198 if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) 199 fatal("buffer_get_string: buffer error"); 200 return (ret); 201} 202 203void * 204buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) 205{ 206 void *ptr; 207 u_int len; 208 209 if (buffer_get_int_ret(&len, buffer) != 0) 210 return NULL; 211 if (len > 256 * 1024) { 212 error("buffer_get_string_ptr: bad string length %u", len); 213 return NULL; 214 } 215 ptr = buffer_ptr(buffer); 216 buffer_consume(buffer, len); 217 if (length_ptr) 218 *length_ptr = len; 219 return (ptr); 220} 221 222void * 223buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) 224{ 225 void *ret; 226 227 if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) 228 fatal("buffer_get_string_ptr: buffer error"); 229 return (ret); 230} 231 232/* 233 * Stores and arbitrary binary string in the buffer. 234 */ 235void 236buffer_put_string(Buffer *buffer, const void *buf, u_int len) 237{ 238 buffer_put_int(buffer, len); 239 buffer_append(buffer, buf, len); 240} 241void 242buffer_put_cstring(Buffer *buffer, const char *s) 243{ 244 if (s == NULL) 245 fatal("buffer_put_cstring: s == NULL"); 246 buffer_put_string(buffer, s, strlen(s)); 247} 248 249/* 250 * Returns a character from the buffer (0 - 255). 251 */ 252int 253buffer_get_char_ret(char *ret, Buffer *buffer) 254{ 255 if (buffer_get_ret(buffer, ret, 1) == -1) { 256 error("buffer_get_char_ret: buffer_get_ret failed"); 257 return (-1); 258 } 259 return (0); 260} 261 262int 263buffer_get_char(Buffer *buffer) 264{ 265 char ch; 266 267 if (buffer_get_char_ret(&ch, buffer) == -1) 268 fatal("buffer_get_char: buffer error"); 269 return (u_char) ch; 270} 271 272/* 273 * Stores a character in the buffer. 274 */ 275void 276buffer_put_char(Buffer *buffer, int value) 277{ 278 char ch = value; 279 280 buffer_append(buffer, &ch, 1); 281} 282