mirror of https://github.com/ericonr/purr-c.git
Split mmap_file implementation.
Also add some useful definitions.
This commit is contained in:
parent
52f7829b48
commit
06eb9d4222
10
encrypt.c
10
encrypt.c
|
@ -11,6 +11,7 @@
|
||||||
#include "libbaseencode/baseencode.h"
|
#include "libbaseencode/baseencode.h"
|
||||||
|
|
||||||
#include "purr.h"
|
#include "purr.h"
|
||||||
|
#include "mmap_file.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function takes an mmap_file struct, and creates an encrypted buffer from it.
|
* This function takes an mmap_file struct, and creates an encrypted buffer from it.
|
||||||
|
@ -27,8 +28,7 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
|
||||||
if (blocks * br_aes_big_BLOCK_SIZE < file_size) blocks++;
|
if (blocks * br_aes_big_BLOCK_SIZE < file_size) blocks++;
|
||||||
file_size = blocks * br_aes_big_BLOCK_SIZE;
|
file_size = blocks * br_aes_big_BLOCK_SIZE;
|
||||||
|
|
||||||
struct mmap_file rv =
|
struct mmap_file rv = {.size = file_size, .prot = PROT_MEM, .flags = MAP_MEM};
|
||||||
{.size = file_size, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
|
|
||||||
|
|
||||||
uint8_t *key = calloc(KEY_LEN, 1);
|
uint8_t *key = calloc(KEY_LEN, 1);
|
||||||
uint8_t *iv = calloc(IV_LEN, 1);
|
uint8_t *iv = calloc(IV_LEN, 1);
|
||||||
|
@ -80,8 +80,7 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
size_t len = strlen(data);
|
size_t len = strlen(data);
|
||||||
struct mmap_file rv_64 =
|
struct mmap_file rv_64 = {.size = len, .prot = PROT_MEM, .flags = MAP_MEM};
|
||||||
{.size = len, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
|
|
||||||
rv_64.data = mmap(NULL, rv_64.size, rv_64.prot, rv_64.flags, -1, 0);
|
rv_64.data = mmap(NULL, rv_64.size, rv_64.prot, rv_64.flags, -1, 0);
|
||||||
if (ERROR_MMAP(rv_64)) {
|
if (ERROR_MMAP(rv_64)) {
|
||||||
perror("mmap()");
|
perror("mmap()");
|
||||||
|
@ -106,8 +105,7 @@ struct mmap_file encrypt_mmap(struct mmap_file file, uint8_t **keyp, uint8_t **i
|
||||||
|
|
||||||
struct mmap_file decrypt_mmap(struct mmap_file file, const uint8_t *key, const uint8_t *iv)
|
struct mmap_file decrypt_mmap(struct mmap_file file, const uint8_t *key, const uint8_t *iv)
|
||||||
{
|
{
|
||||||
struct mmap_file rv =
|
struct mmap_file rv = {.size = file.size, .prot = PROT_MEM, .flags = MAP_MEM};
|
||||||
{.size = file.size, .prot = PROT_WRITE | PROT_READ, .flags = MAP_ANONYMOUS | MAP_PRIVATE};
|
|
||||||
|
|
||||||
#ifdef DECODE_BASE_64
|
#ifdef DECODE_BASE_64
|
||||||
baseencode_error_t berr;
|
baseencode_error_t berr;
|
||||||
|
|
103
files.c
103
files.c
|
@ -3,15 +3,8 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include "purr.h"
|
#include "purr.h"
|
||||||
|
#include "mmap_file.h"
|
||||||
// 128KiB
|
|
||||||
#define OUTPUT_FILE_SIZE (128 * 1024)
|
|
||||||
|
|
||||||
struct strip_header_info {
|
struct strip_header_info {
|
||||||
struct mmap_file *output;
|
struct mmap_file *output;
|
||||||
|
@ -21,100 +14,6 @@ struct strip_header_info {
|
||||||
bool no_strip, debug;
|
bool no_strip, debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mmap_file create_mmap_from_file(const char *name, int prot)
|
|
||||||
{
|
|
||||||
struct mmap_file rv = {.prot = prot};
|
|
||||||
int fd;
|
|
||||||
if (prot == PROT_READ) {
|
|
||||||
fd = open(name, O_RDONLY);
|
|
||||||
rv.flags = MAP_PRIVATE;
|
|
||||||
|
|
||||||
if (fd == -1) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fd, &st) == -1) {
|
|
||||||
perror("fstat()");
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
rv.size = st.st_size;
|
|
||||||
} else if (prot == PROT_WRITE) {
|
|
||||||
fd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
|
||||||
rv.flags = MAP_PRIVATE;
|
|
||||||
|
|
||||||
if (fd == -1) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ftruncate is good enough for now
|
|
||||||
// TODO: we can truncate again once we know the content-size,
|
|
||||||
// otherwise this will leave the file with the wrong size
|
|
||||||
if (0 && ftruncate(fd, OUTPUT_FILE_SIZE) == -1) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
rv.size = OUTPUT_FILE_SIZE;
|
|
||||||
} else if (name == NULL && prot == (PROT_WRITE | PROT_READ)) {
|
|
||||||
fd = -1;
|
|
||||||
rv.flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
|
||||||
rv.size = OUTPUT_FILE_SIZE;
|
|
||||||
} else {
|
|
||||||
fputs("unsupported prot flags\n", stderr);
|
|
||||||
errno = 0;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv.data = mmap(NULL, rv.size, rv.prot, rv.flags, fd, 0);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_from_mmap(struct mmap_file *file, int n)
|
|
||||||
{
|
|
||||||
assert(file->prot & PROT_READ);
|
|
||||||
|
|
||||||
if (file->size == file->offset) {
|
|
||||||
// can't read any more
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t max = file->size - file->offset;
|
|
||||||
file->cursor = file->data + file->offset;
|
|
||||||
if (n < max) {
|
|
||||||
// can fit the read
|
|
||||||
file->offset += n;
|
|
||||||
} else {
|
|
||||||
// can read less than n
|
|
||||||
file->offset = file->size;
|
|
||||||
n = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_into_mmap(struct mmap_file *file, const uint8_t *buffer, int n)
|
|
||||||
{
|
|
||||||
assert(file->prot & PROT_WRITE);
|
|
||||||
|
|
||||||
if (file->size == file->offset) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t max = file->size - file->offset;
|
|
||||||
file->cursor = file->data + file->offset;
|
|
||||||
if (n < max) {
|
|
||||||
file->offset += n;
|
|
||||||
} else {
|
|
||||||
file->offset = file->size;
|
|
||||||
n = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(file->cursor, buffer, n);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t fwrite_strip(const uint8_t *buf, int rlen, struct strip_header_info *st)
|
static size_t fwrite_strip(const uint8_t *buf, int rlen, struct strip_header_info *st)
|
||||||
{
|
{
|
||||||
const char *separator = "\r\n\r\n";
|
const char *separator = "\r\n\r\n";
|
||||||
|
|
5
makefile
5
makefile
|
@ -11,7 +11,8 @@ LIBS = $(BASEENCODE)
|
||||||
LIBSOBJS = $(BASEENCODEOBJS)
|
LIBSOBJS = $(BASEENCODEOBJS)
|
||||||
|
|
||||||
FINAL = purr
|
FINAL = purr
|
||||||
OBJS = purr.o socket.o urls.o files.o comm.o formats.o encrypt.o
|
HEADERS = purr.h mmap_file.h
|
||||||
|
OBJS = purr.o socket.o urls.o files.o comm.o formats.o encrypt.o mmap_file.o
|
||||||
|
|
||||||
TEST = tests
|
TEST = tests
|
||||||
TOBJS = tests.o formats.o urls.o
|
TOBJS = tests.o formats.o urls.o
|
||||||
|
@ -21,7 +22,7 @@ all: $(FINAL)
|
||||||
check: $(TEST)
|
check: $(TEST)
|
||||||
./tests
|
./tests
|
||||||
|
|
||||||
$(OBJS): purr.h
|
$(OBJS): $(HEADERS)
|
||||||
$(OBJS): CFLAGS += $(WARN) $(INC)
|
$(OBJS): CFLAGS += $(WARN) $(INC)
|
||||||
purr: $(OBJS) $(LIBS)
|
purr: $(OBJS) $(LIBS)
|
||||||
tests: $(TOBJS) $(LIBS)
|
tests: $(TOBJS) $(LIBS)
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "mmap_file.h"
|
||||||
|
|
||||||
|
struct mmap_file create_mmap_from_file(const char *name, int prot)
|
||||||
|
{
|
||||||
|
struct mmap_file rv = {.prot = prot};
|
||||||
|
int fd;
|
||||||
|
if (prot == PROT_READ) {
|
||||||
|
fd = open(name, O_RDONLY);
|
||||||
|
rv.flags = MAP_PRIVATE;
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st) == -1) {
|
||||||
|
perror("fstat()");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv.size = st.st_size;
|
||||||
|
} else if (prot == PROT_WRITE) {
|
||||||
|
fd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
rv.flags = MAP_PRIVATE;
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ftruncate is good enough for now
|
||||||
|
// TODO: we can truncate again once we know the content-size,
|
||||||
|
// otherwise this will leave the file with the wrong size
|
||||||
|
if (0 && ftruncate(fd, OUTPUT_FILE_SIZE) == -1) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv.size = OUTPUT_FILE_SIZE;
|
||||||
|
} else if (name == NULL && prot == PROT_MEM) {
|
||||||
|
fd = -1;
|
||||||
|
rv.flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
||||||
|
rv.size = OUTPUT_FILE_SIZE;
|
||||||
|
} else {
|
||||||
|
fputs("unsupported prot flags\n", stderr);
|
||||||
|
errno = 0;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv.data = mmap(NULL, rv.size, rv.prot, rv.flags, fd, 0);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_from_mmap(struct mmap_file *file, int n)
|
||||||
|
{
|
||||||
|
assert(file->prot & PROT_READ);
|
||||||
|
|
||||||
|
if (file->size == file->offset) {
|
||||||
|
// can't read any more
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t max = file->size - file->offset;
|
||||||
|
file->cursor = file->data + file->offset;
|
||||||
|
if (n < max) {
|
||||||
|
// can fit the read
|
||||||
|
file->offset += n;
|
||||||
|
} else {
|
||||||
|
// can read less than n
|
||||||
|
file->offset = file->size;
|
||||||
|
n = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_into_mmap(struct mmap_file *file, const uint8_t *buffer, int n)
|
||||||
|
{
|
||||||
|
assert(file->prot & PROT_WRITE);
|
||||||
|
|
||||||
|
if (file->size == file->offset) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t max = file->size - file->offset;
|
||||||
|
file->cursor = file->data + file->offset;
|
||||||
|
if (n < max) {
|
||||||
|
file->offset += n;
|
||||||
|
} else {
|
||||||
|
file->offset = file->size;
|
||||||
|
n = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(file->cursor, buffer, n);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef __MMAP_FILE_H_
|
||||||
|
#define __MMAP_FILE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#define RESET_MMAP(file) do{(file).offset = 0; (file).cursor = 0}while(0);
|
||||||
|
#define ERROR_MMAP(file) ((file).data == MAP_FAILED || (file).data == NULL)
|
||||||
|
#define CLOSE_MMAP(file) do{if((file).data != MAP_FAILED && (file).data != NULL) munmap((file).data, (file).size);}while(0);
|
||||||
|
|
||||||
|
// definitions for memory backed mappings
|
||||||
|
#define PROT_MEM (PROT_WRITE | PROT_READ)
|
||||||
|
#define MAP_MEM (MAP_ANONYMOUS | MAP_PRIVATE)
|
||||||
|
|
||||||
|
// 128KiB
|
||||||
|
#define OUTPUT_FILE_SIZE (128 * 1024)
|
||||||
|
|
||||||
|
struct mmap_file {
|
||||||
|
uint8_t *data, *cursor;
|
||||||
|
off_t size, offset;
|
||||||
|
int prot, flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mmap_file.c */
|
||||||
|
struct mmap_file create_mmap_from_file(const char *, int);
|
||||||
|
int read_from_mmap(struct mmap_file *, int);
|
||||||
|
int write_into_mmap(struct mmap_file *, const uint8_t *, int);
|
||||||
|
|
||||||
|
/* encrypt.c */
|
||||||
|
struct mmap_file encrypt_mmap(struct mmap_file, uint8_t **, uint8_t **);
|
||||||
|
struct mmap_file decrypt_mmap(struct mmap_file, const uint8_t *, const uint8_t *);
|
||||||
|
|
||||||
|
#endif // __MMAP_FILE_H_
|
3
purr.c
3
purr.c
|
@ -9,6 +9,7 @@
|
||||||
#include <s6-networking/sbearssl.h>
|
#include <s6-networking/sbearssl.h>
|
||||||
|
|
||||||
#include "purr.h"
|
#include "purr.h"
|
||||||
|
#include "mmap_file.h"
|
||||||
|
|
||||||
__attribute__ ((noreturn))
|
__attribute__ ((noreturn))
|
||||||
static void usage(bool fail)
|
static void usage(bool fail)
|
||||||
|
@ -89,7 +90,7 @@ int main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mmap_file input;
|
struct mmap_file input;
|
||||||
struct mmap_file output = create_mmap_from_file(NULL, PROT_WRITE | PROT_READ);
|
struct mmap_file output = create_mmap_from_file(NULL, PROT_MEM);
|
||||||
if (ERROR_MMAP(output)) {
|
if (ERROR_MMAP(output)) {
|
||||||
perror("couldn't open output file");
|
perror("couldn't open output file");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
18
purr.h
18
purr.h
|
@ -4,7 +4,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <bearssl.h>
|
#include <bearssl.h>
|
||||||
|
|
||||||
|
@ -22,10 +21,6 @@
|
||||||
#define ENCODE_BASE_64
|
#define ENCODE_BASE_64
|
||||||
#define DECODE_BASE_64
|
#define DECODE_BASE_64
|
||||||
|
|
||||||
#define RESET_MMAP(file) do{(file).offset = 0; (file).cursor = 0}while(0);
|
|
||||||
#define ERROR_MMAP(file) ((file).data == MAP_FAILED || (file).data == NULL)
|
|
||||||
#define CLOSE_MMAP(file) do{if((file).data != MAP_FAILED && (file).data != NULL) munmap((file).data, (file).size);}while(0);
|
|
||||||
|
|
||||||
struct connection_information {
|
struct connection_information {
|
||||||
br_sslio_context *ioc;
|
br_sslio_context *ioc;
|
||||||
br_ssl_client_context *sc;
|
br_ssl_client_context *sc;
|
||||||
|
@ -44,12 +39,6 @@ struct transmission_information {
|
||||||
bool no_strip, debug, ssl;
|
bool no_strip, debug, ssl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mmap_file {
|
|
||||||
uint8_t *data, *cursor;
|
|
||||||
off_t size, offset;
|
|
||||||
int prot, flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* sockets.c */
|
/* sockets.c */
|
||||||
int socket_read(void *, uint8_t *, size_t);
|
int socket_read(void *, uint8_t *, size_t);
|
||||||
int socket_write(void *, const uint8_t *, size_t);
|
int socket_write(void *, const uint8_t *, size_t);
|
||||||
|
@ -60,9 +49,6 @@ int get_encryption_params(char *, uint8_t **, uint8_t **);
|
||||||
int host_connect(const char *, const char *, bool);
|
int host_connect(const char *, const char *, bool);
|
||||||
|
|
||||||
/* files.c */
|
/* files.c */
|
||||||
struct mmap_file create_mmap_from_file(const char *, int);
|
|
||||||
int read_from_mmap(struct mmap_file *, int);
|
|
||||||
int write_into_mmap(struct mmap_file *, const uint8_t *, int);
|
|
||||||
size_t ssl_to_mmap(struct transmission_information);
|
size_t ssl_to_mmap(struct transmission_information);
|
||||||
size_t mmap_to_ssl(struct transmission_information);
|
size_t mmap_to_ssl(struct transmission_information);
|
||||||
|
|
||||||
|
@ -73,8 +59,4 @@ int send_and_receive(struct connection_information *);
|
||||||
char *print_hex(const uint8_t *, int, bool);
|
char *print_hex(const uint8_t *, int, bool);
|
||||||
int decode_hex(const char *, uint8_t *, int);
|
int decode_hex(const char *, uint8_t *, int);
|
||||||
|
|
||||||
/* encrypt.c */
|
|
||||||
struct mmap_file encrypt_mmap(struct mmap_file, uint8_t **, uint8_t **);
|
|
||||||
struct mmap_file decrypt_mmap(struct mmap_file, const uint8_t *, const uint8_t *);
|
|
||||||
|
|
||||||
#endif // __PURR_H_
|
#endif // __PURR_H_
|
||||||
|
|
Loading…
Reference in New Issue