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/ |