int32_t rstzip3::decompress(rstf_unionT * buf, int32_t nrec) { // if there are some records ready to be // copied out, copy out as many as possible int32_t done = 0; if (interface_buffer_count) { int32_t n = interface_buffer_count; if (n > nrec) n = nrec; memcpy(buf+done, interface_buffer+(interface_buffer_size-interface_buffer_count), n*sizeof(rstf_unionT)); interface_buffer_count -= n; done += n; if (done == nrec) return nrec; } // at this point, if we haven't returned, done < nrec and interface_buffer_count == 0 // decompress the next section. while((nrec-done) >= rz3_bufsize) { int32_t n = decompress_buffer(buf+done, rz3_bufsize); // returns the actual number of records decmopressed // this should be equal to rz3_bufsize unless we reached the end of file if (n == 0) return done; done += n; } // at this point, the number of records that can be copied to the caller is < rz3_bufsize. // to avoid buffer overflow, we use the interface buffer once again while(done < nrec) { interface_buffer_size = decompress_buffer(interface_buffer, rz3_bufsize); if (interface_buffer_size == 0) return done; interface_buffer_count = interface_buffer_size; // how many can we copy out? int32_t n = interface_buffer_size; if (n > (nrec-done)) n = (nrec-done); // copy and update (decrement) buffer count memcpy(buf+done, interface_buffer+(interface_buffer_size-interface_buffer_count), n*sizeof(rstf_unionT)); done += n; interface_buffer_count -= n; } // at this point done = nrec. return nrec; } // rstzip3::decompress(rstf_unionT * buf, int32_t nrec)
unsigned char *U6Lzw::decompress_buffer(unsigned char *source, uint32 source_length, uint32 &destination_length) { unsigned char *destination; sint32 uncomp_size; uncomp_size = this->get_uncompressed_buffer_size(source,source_length); if(uncomp_size == -1) return(NULL); else destination_length = uncomp_size; destination = (unsigned char *)malloc(destination_length); if(decompress_buffer(source, source_length, destination, destination_length) == false) { free(destination); return NULL; } return destination; }
int main () { printf ("Results of file_crypto_key_test:\n"); try { filecryptokey_t key; FileSystem::GetFileCryptoKey (FILE_NAME, key); char key_string [sizeof (key) * 2 + 1]; decompress_buffer (sizeof (key), key, key_string); printf ("key: '%s'\n", key_string); } catch (std::exception& e) { printf ("exception: %s\n", e.what ()); } return 0; }
/** @internal * @handles a data received event. It then calls the handlers for the different packet types * or and exception handler callback. * @param user pointer to current ssh_session * @param data pointer to the data received * @len length of data received. It might not be enough for a complete packet * @returns number of bytes read and processed. */ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user){ ssh_session session=(ssh_session) user; unsigned int blocksize = (session->current_crypto ? session->current_crypto->in_cipher->blocksize : 8); int current_macsize = session->current_crypto ? MACSIZE : 0; unsigned char mac[30] = {0}; char buffer[16] = {0}; const void *packet = NULL; int to_be_read; int rc; uint32_t len, compsize, payloadsize; uint8_t padding; size_t processed=0; /* number of byte processed from the callback */ if (data == NULL) { goto error; } if (session->session_state == SSH_SESSION_STATE_ERROR) goto error; switch(session->packet_state) { case PACKET_STATE_INIT: if(receivedlen < blocksize){ /* We didn't receive enough data to read at least one block size, give up */ return 0; } memset(&session->in_packet, 0, sizeof(PACKET)); if (session->in_buffer) { if (buffer_reinit(session->in_buffer) < 0) { goto error; } } else { session->in_buffer = ssh_buffer_new(); if (session->in_buffer == NULL) { goto error; } } memcpy(buffer,data,blocksize); processed += blocksize; len = packet_decrypt_len(session, buffer); if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) { goto error; } if(len > MAX_PACKET_LEN) { ssh_set_error(session, SSH_FATAL, "read_packet(): Packet len too high(%u %.4x)", len, len); goto error; } to_be_read = len - blocksize + sizeof(uint32_t); if (to_be_read < 0) { /* remote sshd sends invalid sizes? */ ssh_set_error(session, SSH_FATAL, "given numbers of bytes left to be read < 0 (%d)!", to_be_read); goto error; } /* saves the status of the current operations */ session->in_packet.len = len; session->packet_state = PACKET_STATE_SIZEREAD; /* FALL TROUGH */ case PACKET_STATE_SIZEREAD: len = session->in_packet.len; to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize; /* if to_be_read is zero, the whole packet was blocksize bytes. */ if (to_be_read != 0) { if(receivedlen - processed < (unsigned int)to_be_read){ /* give up, not enough data in buffer */ SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len); return processed; } packet = ((unsigned char *)data) + processed; // ssh_socket_read(session->socket,packet,to_be_read-current_macsize); if (buffer_add_data(session->in_buffer, packet, to_be_read - current_macsize) < 0) { goto error; } processed += to_be_read - current_macsize; } if (session->current_crypto) { /* * decrypt the rest of the packet (blocksize bytes already * have been decrypted) */ if (packet_decrypt(session, ((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize), buffer_get_rest_len(session->in_buffer) - blocksize) < 0) { ssh_set_error(session, SSH_FATAL, "Decrypt error"); goto error; } /* copy the last part from the incoming buffer */ memcpy(mac,(unsigned char *)packet + to_be_read - current_macsize, MACSIZE); if (packet_hmac_verify(session, session->in_buffer, mac) < 0) { ssh_set_error(session, SSH_FATAL, "HMAC error"); goto error; } processed += current_macsize; } /* skip the size field which has been processed before */ buffer_pass_bytes(session->in_buffer, sizeof(uint32_t)); if (buffer_get_u8(session->in_buffer, &padding) == 0) { ssh_set_error(session, SSH_FATAL, "Packet too short to read padding"); goto error; } if (padding > buffer_get_rest_len(session->in_buffer)) { ssh_set_error(session, SSH_FATAL, "Invalid padding: %d (%d left)", padding, buffer_get_rest_len(session->in_buffer)); goto error; } buffer_pass_bytes_end(session->in_buffer, padding); compsize = buffer_get_rest_len(session->in_buffer); #ifdef WITH_ZLIB if (session->current_crypto && session->current_crypto->do_compress_in && buffer_get_rest_len(session->in_buffer)) { if (decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN) < 0) { goto error; } } #endif /* WITH_ZLIB */ payloadsize=buffer_get_rest_len(session->in_buffer); session->recv_seq++; /* We don't want to rewrite a new packet while still executing the packet callbacks */ session->packet_state = PACKET_STATE_PROCESSING; ssh_packet_parse_type(session); SSH_LOG(SSH_LOG_PACKET, "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", session->in_packet.type, len, padding, compsize, payloadsize); /* execute callbacks */ ssh_packet_process(session, session->in_packet.type); session->packet_state = PACKET_STATE_INIT; if(processed < receivedlen){ /* Handle a potential packet left in socket buffer */ SSH_LOG(SSH_LOG_PACKET,"Processing %" PRIdS " bytes left in socket buffer", receivedlen-processed); rc = ssh_packet_socket_callback(((unsigned char *)data) + processed, receivedlen - processed,user); processed += rc; } return processed; case PACKET_STATE_PROCESSING: SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying."); return 0; } ssh_set_error(session, SSH_FATAL, "Invalid state into packet_read2(): %d", session->packet_state); error: session->session_state= SSH_SESSION_STATE_ERROR; return processed; }
static int packet_read2(SSH_SESSION *session) { unsigned int blocksize = (session->current_crypto ? session->current_crypto->in_cipher->blocksize : 8); int current_macsize = session->current_crypto ? macsize : 0; unsigned char mac[30] = {0}; char buffer[16] = {0}; void *packet=NULL; int to_be_read; int rc = SSH_ERROR; u32 len; u8 padding; enter_function(); if (session->alive == 0) { /* The error message was already set into this session */ leave_function(); return SSH_ERROR; } switch(session->packet_state) { case PACKET_STATE_INIT: memset(&session->in_packet, 0, sizeof(PACKET)); if (session->in_buffer) { if (buffer_reinit(session->in_buffer) < 0) { goto error; } } else { session->in_buffer = buffer_new(); if (session->in_buffer == NULL) { goto error; } } rc = ssh_socket_wait_for_data(session->socket, session, blocksize); if (rc != SSH_OK) { goto error; } rc = SSH_ERROR; /* can't fail since we're sure there is enough data in socket buffer */ ssh_socket_read(session->socket, buffer, blocksize); len = packet_decrypt_len(session, buffer); if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) { goto error; } if(len > MAX_PACKET_LEN) { ssh_set_error(session, SSH_FATAL, "read_packet(): Packet len too high(%u %.4x)", len, len); goto error; } to_be_read = len - blocksize + sizeof(u32); if (to_be_read < 0) { /* remote sshd sends invalid sizes? */ ssh_set_error(session, SSH_FATAL, "given numbers of bytes left to be read < 0 (%d)!", to_be_read); goto error; } /* saves the status of the current operations */ session->in_packet.len = len; session->packet_state = PACKET_STATE_SIZEREAD; case PACKET_STATE_SIZEREAD: len = session->in_packet.len; to_be_read = len - blocksize + sizeof(u32) + current_macsize; /* if to_be_read is zero, the whole packet was blocksize bytes. */ if (to_be_read != 0) { rc = ssh_socket_wait_for_data(session->socket,session,to_be_read); if (rc != SSH_OK) { goto error; } rc = SSH_ERROR; packet = malloc(to_be_read); if (packet == NULL) { ssh_set_error(session, SSH_FATAL, "No space left"); goto error; } ssh_socket_read(session->socket,packet,to_be_read-current_macsize); ssh_log(session,SSH_LOG_PACKET,"Read a %d bytes packet",len); if (buffer_add_data(session->in_buffer, packet, to_be_read - current_macsize) < 0) { SAFE_FREE(packet); goto error; } SAFE_FREE(packet); } if (session->current_crypto) { /* * decrypt the rest of the packet (blocksize bytes already * have been decrypted) */ if (packet_decrypt(session, buffer_get(session->in_buffer) + blocksize, buffer_get_len(session->in_buffer) - blocksize) < 0) { ssh_set_error(session, SSH_FATAL, "Decrypt error"); goto error; } ssh_socket_read(session->socket, mac, macsize); if (packet_hmac_verify(session, session->in_buffer, mac) < 0) { ssh_set_error(session, SSH_FATAL, "HMAC error"); goto error; } } buffer_pass_bytes(session->in_buffer, sizeof(u32)); /* pass the size which has been processed before */ if (buffer_get_u8(session->in_buffer, &padding) == 0) { ssh_set_error(session, SSH_FATAL, "Packet too short to read padding"); goto error; } ssh_log(session, SSH_LOG_RARE, "%hhd bytes padding, %d bytes left in buffer", padding, buffer_get_rest_len(session->in_buffer)); if (padding > buffer_get_rest_len(session->in_buffer)) { ssh_set_error(session, SSH_FATAL, "Invalid padding: %d (%d resting)", padding, buffer_get_rest_len(session->in_buffer)); #ifdef DEBUG_CRYPTO ssh_print_hexa("incrimined packet", buffer_get(session->in_buffer), buffer_get_len(session->in_buffer)); #endif goto error; } buffer_pass_bytes_end(session->in_buffer, padding); ssh_log(session, SSH_LOG_RARE, "After padding, %d bytes left in buffer", buffer_get_rest_len(session->in_buffer)); #if defined(HAVE_LIBZ) && defined(WITH_LIBZ) if (session->current_crypto && session->current_crypto->do_compress_in) { ssh_log(session, SSH_LOG_RARE, "Decompressing in_buffer ..."); if (decompress_buffer(session, session->in_buffer) < 0) { goto error; } } #endif session->recv_seq++; session->packet_state = PACKET_STATE_INIT; leave_function(); return SSH_OK; } ssh_set_error(session, SSH_FATAL, "Invalid state into packet_read2(): %d", session->packet_state); error: leave_function(); return rc; }
/** @internal * @handles a data received event. It then calls the handlers for the different packet types * or and exception handler callback. * @param user pointer to current ssh_session * @param data pointer to the data received * @len length of data received. It might not be enough for a complete packet * @returns number of bytes read and processed. */ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) { ssh_session session= (ssh_session) user; unsigned int blocksize = (session->current_crypto ? session->current_crypto->in_cipher->blocksize : 8); unsigned int lenfield_blocksize = (session->current_crypto ? session->current_crypto->in_cipher->lenfield_blocksize : 8); size_t current_macsize = 0; uint8_t *ptr = NULL; int to_be_read; int rc; uint8_t *cleartext_packet = NULL; uint8_t *packet_second_block = NULL; uint8_t *mac = NULL; size_t packet_remaining; uint32_t packet_len, compsize, payloadsize; uint8_t padding; size_t processed = 0; /* number of byte processed from the callback */ if(session->current_crypto != NULL) { current_macsize = hmac_digest_len(session->current_crypto->in_hmac); } if (lenfield_blocksize == 0) { lenfield_blocksize = blocksize; } if (data == NULL) { goto error; } if (session->session_state == SSH_SESSION_STATE_ERROR) { goto error; } #ifdef DEBUG_PACKET SSH_LOG(SSH_LOG_PACKET, "rcv packet cb (len=%zu, state=%s)", receivedlen, session->packet_state == PACKET_STATE_INIT ? "INIT" : session->packet_state == PACKET_STATE_SIZEREAD ? "SIZE_READ" : session->packet_state == PACKET_STATE_PROCESSING ? "PROCESSING" : "unknown"); #endif switch(session->packet_state) { case PACKET_STATE_INIT: if (receivedlen < lenfield_blocksize) { /* * We didn't receive enough data to read at least one * block size, give up */ #ifdef DEBUG_PACKET SSH_LOG(SSH_LOG_PACKET, "Waiting for more data (%zu < %u)", receivedlen, lenfield_blocksize); #endif return 0; } memset(&session->in_packet, 0, sizeof(PACKET)); if (session->in_buffer) { rc = ssh_buffer_reinit(session->in_buffer); if (rc < 0) { goto error; } } else { session->in_buffer = ssh_buffer_new(); if (session->in_buffer == NULL) { goto error; } } ptr = ssh_buffer_allocate(session->in_buffer, lenfield_blocksize); if (ptr == NULL) { goto error; } processed += lenfield_blocksize; packet_len = ssh_packet_decrypt_len(session, ptr, (uint8_t *)data); if (packet_len > MAX_PACKET_LEN) { ssh_set_error(session, SSH_FATAL, "read_packet(): Packet len too high(%u %.4x)", packet_len, packet_len); goto error; } to_be_read = packet_len - lenfield_blocksize + sizeof(uint32_t); if (to_be_read < 0) { /* remote sshd sends invalid sizes? */ ssh_set_error(session, SSH_FATAL, "Given numbers of bytes left to be read < 0 (%d)!", to_be_read); goto error; } session->in_packet.len = packet_len; session->packet_state = PACKET_STATE_SIZEREAD; FALL_THROUGH; case PACKET_STATE_SIZEREAD: packet_len = session->in_packet.len; processed = lenfield_blocksize; to_be_read = packet_len + sizeof(uint32_t) + current_macsize; /* if to_be_read is zero, the whole packet was blocksize bytes. */ if (to_be_read != 0) { if (receivedlen < (unsigned int)to_be_read) { /* give up, not enough data in buffer */ SSH_LOG(SSH_LOG_PACKET, "packet: partial packet (read len) " "[len=%d, receivedlen=%d, to_be_read=%d]", packet_len, (int)receivedlen, to_be_read); return 0; } packet_second_block = (uint8_t*)data + lenfield_blocksize; processed = to_be_read - current_macsize; } /* remaining encrypted bytes from the packet, MAC not included */ packet_remaining = packet_len - (lenfield_blocksize - sizeof(uint32_t)); cleartext_packet = ssh_buffer_allocate(session->in_buffer, packet_remaining); if (session->current_crypto) { /* * Decrypt the rest of the packet (lenfield_blocksize bytes already * have been decrypted) */ if (packet_remaining > 0) { rc = ssh_packet_decrypt(session, cleartext_packet, (uint8_t *)data, lenfield_blocksize, processed - lenfield_blocksize); if (rc < 0) { ssh_set_error(session, SSH_FATAL, "Decryption error"); goto error; } } mac = packet_second_block + packet_remaining; rc = ssh_packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac); if (rc < 0) { ssh_set_error(session, SSH_FATAL, "HMAC error"); goto error; } processed += current_macsize; } else { memcpy(cleartext_packet, packet_second_block, packet_remaining); } /* skip the size field which has been processed before */ ssh_buffer_pass_bytes(session->in_buffer, sizeof(uint32_t)); rc = ssh_buffer_get_u8(session->in_buffer, &padding); if (rc == 0) { ssh_set_error(session, SSH_FATAL, "Packet too short to read padding"); goto error; } if (padding > ssh_buffer_get_len(session->in_buffer)) { ssh_set_error(session, SSH_FATAL, "Invalid padding: %d (%d left)", padding, ssh_buffer_get_len(session->in_buffer)); goto error; } ssh_buffer_pass_bytes_end(session->in_buffer, padding); compsize = ssh_buffer_get_len(session->in_buffer); #ifdef WITH_ZLIB if (session->current_crypto && session->current_crypto->do_compress_in && ssh_buffer_get_len(session->in_buffer) > 0) { rc = decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN); if (rc < 0) { goto error; } } #endif /* WITH_ZLIB */ payloadsize = ssh_buffer_get_len(session->in_buffer); session->recv_seq++; if (session->raw_counter != NULL) { session->raw_counter->in_bytes += payloadsize; session->raw_counter->in_packets++; } /* * We don't want to rewrite a new packet while still executing the * packet callbacks */ session->packet_state = PACKET_STATE_PROCESSING; ssh_packet_parse_type(session); SSH_LOG(SSH_LOG_PACKET, "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", session->in_packet.type, packet_len, padding, compsize, payloadsize); /* Execute callbacks */ ssh_packet_process(session, session->in_packet.type); session->packet_state = PACKET_STATE_INIT; if (processed < receivedlen) { /* Handle a potential packet left in socket buffer */ SSH_LOG(SSH_LOG_PACKET, "Processing %" PRIdS " bytes left in socket buffer", receivedlen-processed); ptr = ((uint8_t*)data) + processed; rc = ssh_packet_socket_callback(ptr, receivedlen - processed,user); processed += rc; } return processed; case PACKET_STATE_PROCESSING: SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying."); return 0; } ssh_set_error(session, SSH_FATAL, "Invalid state into packet_read2(): %d", session->packet_state); error: session->session_state= SSH_SESSION_STATE_ERROR; SSH_LOG(SSH_LOG_PACKET,"Packet: processed %" PRIdS " bytes", processed); return processed; }
void RecordVideo::run() { // Number of frames for user to know about. gui->reset_video(); // Wait for trigger trigger_lock->lock("RecordVideo::run"); while( !done && !write_result ) { if( recording_paused ) { pause_record_lock->unlock(); record_paused_lock->lock(); } if( done ) break; VideoDevice *vdevice = record->vdevice; VFrame *capture_frame = get_buffer(); vdevice->set_field_order(record->reverse_interlace); // Capture a frame grab_result = read_buffer(capture_frame); if( done ) break; if( vdevice->config_updated() ) { flush_buffer(); delete_buffer(); config_update(); gui->reset_video(); record->record_monitor->reconfig(); continue; } if( grab_result ) { Timer::delay(250); continue; } decompress_buffer(capture_frame); record->resync(); write_buffer(); if( record->monitor_video && capture_frame->get_data() ) if( !writing_file || !record->is_behind() ) record->record_monitor->update(capture_frame); if( writing_file && record->fill_underrun_frames ) { VFrame *last_frame = capture_frame; int fill = record->dropped; while( --fill >= 0 ) { capture_frame = get_buffer(); capture_frame->copy_from(last_frame); last_frame = capture_frame; write_buffer(); } } else record->written_frames += record->dropped; if( record->single_frame ) { record->single_frame = 0; record->stop_writing_file(); } if( done ) break; if( !done ) done = write_result; if( done ) break; record->check_batch_complete(); } SET_TRACE flush_buffer(); delete_buffer(); SET_TRACE //TRACE("RecordVideo::run 2"); if( write_result ) { ErrorBox error_box(PROGRAM_NAME ": Error", mwindow->gui->get_abs_cursor_x(1), mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects(_("No space left on disk.")); error_box.run_window(); } SET_TRACE }