openssh/bufaux.c

246 lines
6.5 KiB
C
Raw Normal View History

1999-10-27 11:42:43 +08:00
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Auxiliary functions for storing and retrieving various data types to/from
* Buffers.
*
- (djm) Merge OpenBSD changes: - markus@cvs.openbsd.org 2000/09/05 02:59:57 [session.c] print hostname (not hushlogin) - markus@cvs.openbsd.org 2000/09/05 13:18:48 [authfile.c ssh-add.c] enable ssh-add -d for DSA keys - markus@cvs.openbsd.org 2000/09/05 13:20:49 [sftp-server.c] cleanup - markus@cvs.openbsd.org 2000/09/06 03:46:41 [authfile.h] prototype - deraadt@cvs.openbsd.org 2000/09/07 14:27:56 [ALL] cleanup copyright notices on all files. I have attempted to be accurate with the details. everything is now under Tatu's licence (which I copied from his readme), and/or the core-sdi bsd-ish thing for deattack, or various openbsd developers under a 2-term bsd licence. We're not changing any rules, just being accurate. - markus@cvs.openbsd.org 2000/09/07 14:40:30 [channels.c channels.h clientloop.c serverloop.c ssh.c] cleanup window and packet sizes for ssh2 flow control; ok niels - markus@cvs.openbsd.org 2000/09/07 14:53:00 [scp.c] typo - markus@cvs.openbsd.org 2000/09/07 15:13:37 [auth-options.c auth-options.h auth-rh-rsa.c auth-rsa.c auth.c] [authfile.h canohost.c channels.h compat.c hostfile.h log.c match.h] [pty.c readconf.c] some more Copyright fixes - markus@cvs.openbsd.org 2000/09/08 03:02:51 [README.openssh2] bye bye - deraadt@cvs.openbsd.org 2000/09/11 18:38:33 [LICENCE cipher.c] a few more comments about it being ARC4 not RC4 - markus@cvs.openbsd.org 2000/09/12 14:53:11 [log-client.c log-server.c log.c ssh.1 ssh.c ssh.h sshd.8 sshd.c] multiple debug levels - markus@cvs.openbsd.org 2000/09/14 14:25:15 [clientloop.c] typo - deraadt@cvs.openbsd.org 2000/09/15 01:13:51 [ssh-agent.c] check return value for setenv(3) for failure, and deal appropriately
2000-09-16 10:29:08 +08:00
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
*
* SSH2 packet format added by Markus Friedl
- (djm) Merge OpenBSD changes: - markus@cvs.openbsd.org 2000/09/05 02:59:57 [session.c] print hostname (not hushlogin) - markus@cvs.openbsd.org 2000/09/05 13:18:48 [authfile.c ssh-add.c] enable ssh-add -d for DSA keys - markus@cvs.openbsd.org 2000/09/05 13:20:49 [sftp-server.c] cleanup - markus@cvs.openbsd.org 2000/09/06 03:46:41 [authfile.h] prototype - deraadt@cvs.openbsd.org 2000/09/07 14:27:56 [ALL] cleanup copyright notices on all files. I have attempted to be accurate with the details. everything is now under Tatu's licence (which I copied from his readme), and/or the core-sdi bsd-ish thing for deattack, or various openbsd developers under a 2-term bsd licence. We're not changing any rules, just being accurate. - markus@cvs.openbsd.org 2000/09/07 14:40:30 [channels.c channels.h clientloop.c serverloop.c ssh.c] cleanup window and packet sizes for ssh2 flow control; ok niels - markus@cvs.openbsd.org 2000/09/07 14:53:00 [scp.c] typo - markus@cvs.openbsd.org 2000/09/07 15:13:37 [auth-options.c auth-options.h auth-rh-rsa.c auth-rsa.c auth.c] [authfile.h canohost.c channels.h compat.c hostfile.h log.c match.h] [pty.c readconf.c] some more Copyright fixes - markus@cvs.openbsd.org 2000/09/08 03:02:51 [README.openssh2] bye bye - deraadt@cvs.openbsd.org 2000/09/11 18:38:33 [LICENCE cipher.c] a few more comments about it being ARC4 not RC4 - markus@cvs.openbsd.org 2000/09/12 14:53:11 [log-client.c log-server.c log.c ssh.1 ssh.c ssh.h sshd.8 sshd.c] multiple debug levels - markus@cvs.openbsd.org 2000/09/14 14:25:15 [clientloop.c] typo - deraadt@cvs.openbsd.org 2000/09/15 01:13:51 [ssh-agent.c] check return value for setenv(3) for failure, and deal appropriately
2000-09-16 10:29:08 +08:00
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- (djm) Merge OpenBSD changes: - markus@cvs.openbsd.org 2000/09/05 02:59:57 [session.c] print hostname (not hushlogin) - markus@cvs.openbsd.org 2000/09/05 13:18:48 [authfile.c ssh-add.c] enable ssh-add -d for DSA keys - markus@cvs.openbsd.org 2000/09/05 13:20:49 [sftp-server.c] cleanup - markus@cvs.openbsd.org 2000/09/06 03:46:41 [authfile.h] prototype - deraadt@cvs.openbsd.org 2000/09/07 14:27:56 [ALL] cleanup copyright notices on all files. I have attempted to be accurate with the details. everything is now under Tatu's licence (which I copied from his readme), and/or the core-sdi bsd-ish thing for deattack, or various openbsd developers under a 2-term bsd licence. We're not changing any rules, just being accurate. - markus@cvs.openbsd.org 2000/09/07 14:40:30 [channels.c channels.h clientloop.c serverloop.c ssh.c] cleanup window and packet sizes for ssh2 flow control; ok niels - markus@cvs.openbsd.org 2000/09/07 14:53:00 [scp.c] typo - markus@cvs.openbsd.org 2000/09/07 15:13:37 [auth-options.c auth-options.h auth-rh-rsa.c auth-rsa.c auth.c] [authfile.h canohost.c channels.h compat.c hostfile.h log.c match.h] [pty.c readconf.c] some more Copyright fixes - markus@cvs.openbsd.org 2000/09/08 03:02:51 [README.openssh2] bye bye - deraadt@cvs.openbsd.org 2000/09/11 18:38:33 [LICENCE cipher.c] a few more comments about it being ARC4 not RC4 - markus@cvs.openbsd.org 2000/09/12 14:53:11 [log-client.c log-server.c log.c ssh.1 ssh.c ssh.h sshd.8 sshd.c] multiple debug levels - markus@cvs.openbsd.org 2000/09/14 14:25:15 [clientloop.c] typo - deraadt@cvs.openbsd.org 2000/09/15 01:13:51 [ssh-agent.c] check return value for setenv(3) for failure, and deal appropriately
2000-09-16 10:29:08 +08:00
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
1999-10-27 11:42:43 +08:00
#include "includes.h"
NOTE: This update changes the RSA key generation. *NEW RSA KEYS NEED TO BE GENERATED* =) Refer to to entry "2001/01/16 19:20:06" for more details. 20010118 - (bal) Super Sized OpenBSD Resync - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus [sshd.c] maxfd+1 - markus@cvs.openbsd.org 2001/01/13 17:59:18 [ssh-keygen.1] small ssh-keygen manpage cleanup; stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:03:07 [scp.c ssh-keygen.c sshd.c] getopt() returns -1 not EOF; stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:06:54 [ssh-keyscan.c] use SSH_DEFAULT_PORT; from stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:12:47 [ssh-keyscan.c] free() -> xfree(); fix memory leak; from stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:14:13 [ssh-add.c] typo, from stevesk@sweden.hp.com - markus@cvs.openbsd.org 2001/01/13 18:32:50 [packet.c session.c ssh.c sshconnect.c sshd.c] split out keepalive from packet_interactive (from dale@accentre.com) set IPTOS_LOWDELAY TCP_NODELAY IPTOS_THROUGHPUT for ssh2, too. - markus@cvs.openbsd.org 2001/01/13 18:36:45 [packet.c packet.h] reorder, typo - markus@cvs.openbsd.org 2001/01/13 18:38:00 [auth-options.c] fix comment - markus@cvs.openbsd.org 2001/01/13 18:43:31 [session.c] Wall - markus@cvs.openbsd.org 2001/01/13 19:14:08 [clientloop.h clientloop.c ssh.c] move callback to headerfile - markus@cvs.openbsd.org 2001/01/15 21:40:10 [ssh.c] use log() instead of stderr - markus@cvs.openbsd.org 2001/01/15 21:43:51 [dh.c] use error() not stderr! - markus@cvs.openbsd.org 2001/01/15 21:45:29 [sftp-server.c] rename must fail if newpath exists, debug off by default - markus@cvs.openbsd.org 2001/01/15 21:46:38 [sftp-server.c] readable long listing for sftp-server, ok deraadt@ - markus@cvs.openbsd.org 2001/01/16 19:20:06 [key.c ssh-rsa.c] make "ssh-rsa" key format for ssh2 confirm to the ietf-drafts; from galb@vandyke.com. note that you have to delete older ssh2-rsa keys, since they are in the wrong format, too. they must be removed from .ssh/authorized_keys2 and .ssh/known_hosts2, etc. (cd; grep -v ssh-rsa .ssh/authorized_keys2 > TMP && mv TMP .ssh/authorized_keys2) additionally, we now check that BN_num_bits(rsa->n) >= 768. - markus@cvs.openbsd.org 2001/01/16 20:54:27 [sftp-server.c] remove some statics. simpler handles; idea from nisse@lysator.liu.se - deraadt@cvs.openbsd.org 2001/01/16 23:58:08 [bufaux.c radix.c sshconnect.h sshconnect1.c] indent - (bal) Added bsd-strmode.[ch] since some non-OpenBSD platforms may be missing such feature.
2001-01-18 10:04:35 +08:00
RCSID("$OpenBSD: bufaux.c,v 1.16 2001/01/16 23:58:08 deraadt Exp $");
1999-10-27 11:42:43 +08:00
#include "ssh.h"
#include <openssl/bn.h>
#include "bufaux.h"
#include "xmalloc.h"
#include "getput.h"
/*
* Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
* by (bits+7)/8 bytes of binary data, msb first.
*/
1999-10-27 11:42:43 +08:00
void
buffer_put_bignum(Buffer *buffer, BIGNUM *value)
{
int bits = BN_num_bits(value);
int bin_size = (bits + 7) / 8;
u_char *buf = xmalloc(bin_size);
int oi;
char msg[2];
/* Get the value of in binary */
oi = BN_bn2bin(value, buf);
if (oi != bin_size)
fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bin_size);
/* Store the number of bits in the buffer in two bytes, msb first. */
PUT_16BIT(msg, bits);
buffer_append(buffer, msg, 2);
/* Store the binary data. */
buffer_append(buffer, (char *)buf, oi);
memset(buf, 0, bin_size);
xfree(buf);
1999-10-27 11:42:43 +08:00
}
/*
* Retrieves an BIGNUM from the buffer.
*/
1999-10-27 11:42:43 +08:00
int
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
{
int bits, bytes;
u_char buf[2], *bin;
/* Get the number for bits. */
buffer_get(buffer, (char *) buf, 2);
bits = GET_16BIT(buf);
/* Compute the number of binary bytes that follow. */
bytes = (bits + 7) / 8;
if (buffer_len(buffer) < bytes)
fatal("buffer_get_bignum: input buffer too small");
NOTE: This update changes the RSA key generation. *NEW RSA KEYS NEED TO BE GENERATED* =) Refer to to entry "2001/01/16 19:20:06" for more details. 20010118 - (bal) Super Sized OpenBSD Resync - markus@cvs.openbsd.org 2001/01/11 22:14:20 GMT 2001 by markus [sshd.c] maxfd+1 - markus@cvs.openbsd.org 2001/01/13 17:59:18 [ssh-keygen.1] small ssh-keygen manpage cleanup; stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:03:07 [scp.c ssh-keygen.c sshd.c] getopt() returns -1 not EOF; stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:06:54 [ssh-keyscan.c] use SSH_DEFAULT_PORT; from stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:12:47 [ssh-keyscan.c] free() -> xfree(); fix memory leak; from stevesk@pobox.com - markus@cvs.openbsd.org 2001/01/13 18:14:13 [ssh-add.c] typo, from stevesk@sweden.hp.com - markus@cvs.openbsd.org 2001/01/13 18:32:50 [packet.c session.c ssh.c sshconnect.c sshd.c] split out keepalive from packet_interactive (from dale@accentre.com) set IPTOS_LOWDELAY TCP_NODELAY IPTOS_THROUGHPUT for ssh2, too. - markus@cvs.openbsd.org 2001/01/13 18:36:45 [packet.c packet.h] reorder, typo - markus@cvs.openbsd.org 2001/01/13 18:38:00 [auth-options.c] fix comment - markus@cvs.openbsd.org 2001/01/13 18:43:31 [session.c] Wall - markus@cvs.openbsd.org 2001/01/13 19:14:08 [clientloop.h clientloop.c ssh.c] move callback to headerfile - markus@cvs.openbsd.org 2001/01/15 21:40:10 [ssh.c] use log() instead of stderr - markus@cvs.openbsd.org 2001/01/15 21:43:51 [dh.c] use error() not stderr! - markus@cvs.openbsd.org 2001/01/15 21:45:29 [sftp-server.c] rename must fail if newpath exists, debug off by default - markus@cvs.openbsd.org 2001/01/15 21:46:38 [sftp-server.c] readable long listing for sftp-server, ok deraadt@ - markus@cvs.openbsd.org 2001/01/16 19:20:06 [key.c ssh-rsa.c] make "ssh-rsa" key format for ssh2 confirm to the ietf-drafts; from galb@vandyke.com. note that you have to delete older ssh2-rsa keys, since they are in the wrong format, too. they must be removed from .ssh/authorized_keys2 and .ssh/known_hosts2, etc. (cd; grep -v ssh-rsa .ssh/authorized_keys2 > TMP && mv TMP .ssh/authorized_keys2) additionally, we now check that BN_num_bits(rsa->n) >= 768. - markus@cvs.openbsd.org 2001/01/16 20:54:27 [sftp-server.c] remove some statics. simpler handles; idea from nisse@lysator.liu.se - deraadt@cvs.openbsd.org 2001/01/16 23:58:08 [bufaux.c radix.c sshconnect.h sshconnect1.c] indent - (bal) Added bsd-strmode.[ch] since some non-OpenBSD platforms may be missing such feature.
2001-01-18 10:04:35 +08:00
bin = (u_char *) buffer_ptr(buffer);
BN_bin2bn(bin, bytes, value);
buffer_consume(buffer, bytes);
return 2 + bytes;
1999-10-27 11:42:43 +08:00
}
/*
* Stores an BIGNUM in the buffer in SSH2 format.
*/
void
buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
{
int bytes = BN_num_bytes(value) + 1;
u_char *buf = xmalloc(bytes);
int oi;
int hasnohigh = 0;
buf[0] = '\0';
/* Get the value of in binary */
oi = BN_bn2bin(value, buf+1);
if (oi != bytes-1)
fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bytes);
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
if (value->neg) {
/**XXX should be two's-complement */
int i, carry;
u_char *uc = buf;
log("negativ!");
for(i = bytes-1, carry = 1; i>=0; i--) {
uc[i] ^= 0xff;
if(carry)
carry = !++uc[i];
}
}
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
memset(buf, 0, bytes);
xfree(buf);
}
int
buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
{
/**XXX should be two's-complement */
int len;
u_char *bin = (u_char *)buffer_get_string(buffer, (u_int *)&len);
BN_bin2bn(bin, len, value);
xfree(bin);
return len;
}
/*
* Returns an integer from the buffer (4 bytes, msb first).
*/
u_int
buffer_get_int(Buffer *buffer)
1999-10-27 11:42:43 +08:00
{
u_char buf[4];
buffer_get(buffer, (char *) buf, 4);
return GET_32BIT(buf);
1999-10-27 11:42:43 +08:00
}
u_int64_t
buffer_get_int64(Buffer *buffer)
{
u_char buf[8];
buffer_get(buffer, (char *) buf, 8);
return GET_64BIT(buf);
}
/*
* Stores an integer in the buffer in 4 bytes, msb first.
*/
void
buffer_put_int(Buffer *buffer, u_int value)
1999-10-27 11:42:43 +08:00
{
char buf[4];
PUT_32BIT(buf, value);
buffer_append(buffer, buf, 4);
1999-10-27 11:42:43 +08:00
}
void
buffer_put_int64(Buffer *buffer, u_int64_t value)
{
char buf[8];
PUT_64BIT(buf, value);
buffer_append(buffer, buf, 8);
}
/*
* Returns an arbitrary binary string from the buffer. The string cannot
* be longer than 256k. The returned value points to memory allocated
* with xmalloc; it is the responsibility of the calling function to free
* the data. If length_ptr is non-NULL, the length of the returned data
* will be stored there. A null character will be automatically appended
* to the returned string, and is not counted in length.
*/
char *
buffer_get_string(Buffer *buffer, u_int *length_ptr)
1999-10-27 11:42:43 +08:00
{
u_int len;
char *value;
/* Get the length. */
len = buffer_get_int(buffer);
if (len > 256 * 1024)
fatal("Received packet with bad string length %d", len);
/* Allocate space for the string. Add one byte for a null character. */
value = xmalloc(len + 1);
/* Get the string. */
buffer_get(buffer, value, len);
/* Append a null character to make processing easier. */
value[len] = 0;
/* Optionally return the length of the string. */
if (length_ptr)
*length_ptr = len;
return value;
1999-10-27 11:42:43 +08:00
}
/*
* Stores and arbitrary binary string in the buffer.
*/
void
buffer_put_string(Buffer *buffer, const void *buf, u_int len)
1999-10-27 11:42:43 +08:00
{
buffer_put_int(buffer, len);
buffer_append(buffer, buf, len);
1999-10-27 11:42:43 +08:00
}
void
buffer_put_cstring(Buffer *buffer, const char *s)
{
buffer_put_string(buffer, s, strlen(s));
}
1999-10-27 11:42:43 +08:00
/*
* Returns a character from the buffer (0 - 255).
*/
int
buffer_get_char(Buffer *buffer)
1999-10-27 11:42:43 +08:00
{
char ch;
buffer_get(buffer, &ch, 1);
return (u_char) ch;
1999-10-27 11:42:43 +08:00
}
/*
* Stores a character in the buffer.
*/
void
buffer_put_char(Buffer *buffer, int value)
1999-10-27 11:42:43 +08:00
{
char ch = value;
buffer_append(buffer, &ch, 1);
1999-10-27 11:42:43 +08:00
}