gzip.c   gzip.c 
skipping to change at line 27 skipping to change at line 27
* License for more details. * License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to * along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA. * MA 02111-1307, USA.
*/ */
#include "config.h" #include "config.h"
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/buffer.h"
#include "libssh/session.h"
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) #if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
#include <zlib.h> #include <zlib.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#define BLOCKSIZE 4092 #define BLOCKSIZE 4092
static z_stream *initcompress(SSH_SESSION *session, int level) { static z_stream *initcompress(ssh_session session, int level) {
z_stream *stream = NULL; z_stream *stream = NULL;
int status; int status;
stream = malloc(sizeof(z_stream)); stream = malloc(sizeof(z_stream));
if (stream == NULL) { if (stream == NULL) {
return NULL; return NULL;
} }
memset(stream, 0, sizeof(z_stream)); memset(stream, 0, sizeof(z_stream));
status = deflateInit(stream, level); status = deflateInit(stream, level);
if (status != Z_OK) { if (status != Z_OK) {
SAFE_FREE(stream); SAFE_FREE(stream);
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"status %d inititalising zlib deflate", status); "status %d inititalising zlib deflate", status);
return NULL; return NULL;
} }
return stream; return stream;
} }
static BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level) { static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int l evel){
z_stream *zout = session->current_crypto->compress_out_ctx; z_stream *zout = session->current_crypto->compress_out_ctx;
void *in_ptr = buffer_get(source); void *in_ptr = buffer_get(source);
unsigned long in_size = buffer_get_len(source); unsigned long in_size = buffer_get_len(source);
BUFFER *dest = NULL; ssh_buffer dest = NULL;
static unsigned char out_buf[BLOCKSIZE] = {0}; static unsigned char out_buf[BLOCKSIZE] = {0};
unsigned long len; unsigned long len;
int status; int status;
if(zout == NULL) { if(zout == NULL) {
zout = session->current_crypto->compress_out_ctx = initcompress(session , level); zout = session->current_crypto->compress_out_ctx = initcompress(session , level);
if (zout == NULL) { if (zout == NULL) {
return NULL; return NULL;
} }
} }
skipping to change at line 101 skipping to change at line 103
if (buffer_add_data(dest, out_buf, len) < 0) { if (buffer_add_data(dest, out_buf, len) < 0) {
buffer_free(dest); buffer_free(dest);
return NULL; return NULL;
} }
zout->next_out = out_buf; zout->next_out = out_buf;
} while (zout->avail_out == 0); } while (zout->avail_out == 0);
return dest; return dest;
} }
int compress_buffer(SSH_SESSION *session, BUFFER *buf) { int compress_buffer(ssh_session session, ssh_buffer buf) {
BUFFER *dest = NULL; ssh_buffer dest = NULL;
dest = gzip_compress(session, buf, 9); dest = gzip_compress(session, buf, 9);
if (dest == NULL) { if (dest == NULL) {
return -1; return -1;
} }
if (buffer_reinit(buf) < 0) { if (buffer_reinit(buf) < 0) {
buffer_free(dest); buffer_free(dest);
return -1; return -1;
} }
skipping to change at line 125 skipping to change at line 127
buffer_free(dest); buffer_free(dest);
return -1; return -1;
} }
buffer_free(dest); buffer_free(dest);
return 0; return 0;
} }
/* decompression */ /* decompression */
static z_stream *initdecompress(SSH_SESSION *session) { static z_stream *initdecompress(ssh_session session) {
z_stream *stream = NULL; z_stream *stream = NULL;
int status; int status;
stream = malloc(sizeof(z_stream)); stream = malloc(sizeof(z_stream));
if (stream == NULL) { if (stream == NULL) {
return NULL; return NULL;
} }
memset(stream,0,sizeof(z_stream)); memset(stream,0,sizeof(z_stream));
status = inflateInit(stream); status = inflateInit(stream);
if (status != Z_OK) { if (status != Z_OK) {
SAFE_FREE(stream); SAFE_FREE(stream);
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Status = %d initiating inflate context!", status); "Status = %d initiating inflate context!", status);
return NULL; return NULL;
} }
return stream; return stream;
} }
static BUFFER *gzip_decompress(SSH_SESSION *session, BUFFER *source) { static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, s ize_t maxlen) {
z_stream *zin = session->current_crypto->compress_in_ctx; z_stream *zin = session->current_crypto->compress_in_ctx;
void *in_ptr = buffer_get_rest(source); void *in_ptr = buffer_get_rest(source);
unsigned long in_size = buffer_get_rest_len(source); unsigned long in_size = buffer_get_rest_len(source);
static unsigned char out_buf[BLOCKSIZE] = {0}; static unsigned char out_buf[BLOCKSIZE] = {0};
BUFFER *dest = NULL; ssh_buffer dest = NULL;
unsigned long len; unsigned long len;
int status; int status;
if (zin == NULL) { if (zin == NULL) {
zin = session->current_crypto->compress_in_ctx = initdecompress(session ); zin = session->current_crypto->compress_in_ctx = initdecompress(session );
if (zin == NULL) { if (zin == NULL) {
return NULL; return NULL;
} }
} }
skipping to change at line 186 skipping to change at line 188
"status %d inflating zlib packet", status); "status %d inflating zlib packet", status);
buffer_free(dest); buffer_free(dest);
return NULL; return NULL;
} }
len = BLOCKSIZE - zin->avail_out; len = BLOCKSIZE - zin->avail_out;
if (buffer_add_data(dest,out_buf,len) < 0) { if (buffer_add_data(dest,out_buf,len) < 0) {
buffer_free(dest); buffer_free(dest);
return NULL; return NULL;
} }
if (buffer_get_len(dest) > maxlen){
/* Size of packet exceded, avoid a denial of service attack */
buffer_free(dest);
return NULL;
}
zin->next_out = out_buf; zin->next_out = out_buf;
} while (zin->avail_out == 0); } while (zin->avail_out == 0);
return dest; return dest;
} }
int decompress_buffer(SSH_SESSION *session,BUFFER *buf){ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen){
BUFFER *dest = NULL; ssh_buffer dest = NULL;
dest = gzip_decompress(session,buf); dest = gzip_decompress(session,buf, maxlen);
if (dest == NULL) { if (dest == NULL) {
return -1; return -1;
} }
if (buffer_reinit(buf) < 0) { if (buffer_reinit(buf) < 0) {
buffer_free(dest); buffer_free(dest);
return -1; return -1;
} }
if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) { if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
 End of changes. 11 change blocks. 
12 lines changed or deleted 18 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/