1
0
mirror of https://git.zap.org.au/git/trader.git synced 2024-10-13 18:03:39 -04:00

Use separate input and output buffers for scramble() and unscramble()

This commit is contained in:
John Zaitseff 2014-05-22 15:34:32 +10:00
parent cec51ded7d
commit 549b2d517d
4 changed files with 105 additions and 49 deletions

View File

@ -51,12 +51,13 @@ static const unsigned char game_file_crypt_key[] = {
#define load_game_scanf(_fmt, _var, _cond) \
do { \
if (fgets(buf, BUFSIZE, file) == NULL) { \
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
err_exit(_("%s: missing field on line %d"), \
filename, lineno); \
} \
if (sscanf(unscramble(crypt_key, buf, BUFSIZE), _fmt "\n", \
&(_var)) != 1) { \
if (sscanf(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
buf, BUFSIZE), _fmt "\n", &(_var)) \
!= 1) { \
err_exit(_("%s: illegal field on line %d: `%s'"), \
filename, lineno, buf); \
} \
@ -88,11 +89,12 @@ static const unsigned char game_file_crypt_key[] = {
char *s; \
int len; \
\
if (fgets(buf, BUFSIZE, file) == NULL) { \
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
err_exit(_("%s: missing field on line %d"), \
filename, lineno); \
} \
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) == 0) { \
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
buf, BUFSIZE)) == 0) { \
err_exit(_("%s: illegal value on line %d"), \
filename, lineno); \
} \
@ -127,11 +129,12 @@ static const unsigned char game_file_crypt_key[] = {
char *s; \
int len; \
\
if (fgets(buf, BUFSIZE, file) == NULL) { \
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
err_exit(_("%s: missing field on line %d"), \
filename, lineno); \
} \
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) == 0) { \
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
buf, BUFSIZE)) == 0) { \
err_exit(_("%s: illegal value on line %d"), \
filename, lineno); \
} \
@ -157,8 +160,8 @@ static const unsigned char game_file_crypt_key[] = {
#define save_game_printf(_fmt, _var) \
do { \
snprintf(buf, BUFSIZE, _fmt "\n", _var); \
scramble(crypt_key, buf, BUFSIZE); \
fprintf(file, "%s", buf); \
scramble(&crypt_key, buf, BUFSIZE, bigbuf, BIGBUFSIZE); \
fprintf(file, "%s", bigbuf); \
} while (0)
#define save_game_write_int(_var) \
@ -224,10 +227,11 @@ bool load_game (int num)
int saved_errno, lineno;
char *prev_locale;
char *buf;
char *buf, *bigbuf;
wchar_t *wcbuf;
int crypt_key;
unsigned char crypt_key;
int crypt_key_input;
int n, i, j;
#ifdef USE_UTF8_GAME_FILE
@ -239,6 +243,7 @@ bool load_game (int num)
assert(num >= 1 && num <= 9);
buf = xmalloc(BUFSIZE);
bigbuf = xmalloc(BIGBUFSIZE);
wcbuf = xmalloc(BUFSIZE * sizeof(wchar_t));
filename = game_filename(num);
@ -267,6 +272,7 @@ bool load_game (int num)
}
free(buf);
free(bigbuf);
free(wcbuf);
free(filename);
return false;
@ -336,9 +342,10 @@ bool load_game (int num)
lineno = 4;
// Read in the game file encryption key
if (fscanf(file, "%i\n", &crypt_key) != 1) {
if (fscanf(file, "%i\n", &crypt_key_input) != 1) {
err_exit(_("%s: illegal or missing field on line %d"), filename, lineno);
}
crypt_key = (unsigned char) crypt_key_input;
lineno++;
// Read in various game variables
@ -377,10 +384,11 @@ bool load_game (int num)
// Read in galaxy map
for (int x = 0; x < MAX_X; x++) {
if (fgets(buf, BUFSIZE, file) == NULL) {
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) {
err_exit(_("%s: missing field on line %d"), filename, lineno);
}
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) != MAX_Y + 1) {
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, buf, BUFSIZE))
!= MAX_Y + 1) {
err_exit(_("%s: illegal field on line %d"), filename, lineno);
}
@ -414,6 +422,7 @@ bool load_game (int num)
#endif
free(buf);
free(bigbuf);
free(wcbuf);
free(filename);
free(prev_locale);
@ -428,13 +437,14 @@ bool load_game (int num)
bool save_game (int num)
{
const char *data_dir;
char *buf, *filename;
char *buf, *bigbuf;
char *filename;
FILE *file;
char *codeset;
int saved_errno;
char *prev_locale;
struct stat statbuf;
int crypt_key;
unsigned char crypt_key;
int i, j, x, y;
#ifdef USE_UTF8_GAME_FILE
@ -446,6 +456,7 @@ bool save_game (int num)
assert(num >= 1 && num <= 9);
buf = xmalloc(BUFSIZE);
bigbuf = xmalloc(BIGBUFSIZE);
crypt_key = option_dont_encrypt ? 0 :
game_file_crypt_key[randi(GAME_FILE_CRYPT_KEY_SIZE)];
@ -469,6 +480,7 @@ bool save_game (int num)
strerror(saved_errno));
free(buf);
free(bigbuf);
return false;
}
}
@ -489,6 +501,7 @@ bool save_game (int num)
"^{File %s: %s^}"), num, filename, strerror(saved_errno));
free(buf);
free(bigbuf);
free(filename);
return false;
}
@ -568,8 +581,8 @@ bool save_game (int num)
*p++ = '\n';
*p = '\0';
scramble(crypt_key, buf, BUFSIZE);
fprintf(file, "%s", buf);
scramble(&crypt_key, buf, BUFSIZE, bigbuf, BIGBUFSIZE);
fprintf(file, "%s", bigbuf);
}
// Write out a dummy sentinal value
@ -589,6 +602,7 @@ bool save_game (int num)
#endif
free(buf);
free(bigbuf);
free(filename);
free(prev_locale);
return true;

View File

@ -62,7 +62,7 @@
#endif
#define BUFSIZE 1024 // For various string buffers
#define BIGBUFSIZE 2048 // For buffers known to be larger
#define BIGBUFSIZE 4096 // For buffers known to be larger
#endif /* included_TRADER_H */

View File

@ -62,6 +62,27 @@ wchar_t *mon_thousands_sep; // Local monetary thousands separator
#define MOD_POSIX_P_CS_PRECEDES 1
#define MOD_POSIX_P_SEP_BY_SPACE 0
// Constants used for scrambling and unscrambling game data
#define SCRAMBLE_PAD_CHAR '.'
#define UNSCRAMBLE_INVALID (-1)
#define UNSCRAMBLE_PAD_CHAR (-2)
static const char scramble_index[] =
"0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-_";
static const char unscramble_index[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -2, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, -1, -1, -1, -1, 63,
-1, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, -1, -1, -1, -1, -1
};
#define UNSCRAMBLE_INDEX_SIZE (sizeof(unscramble_index) / sizeof(unscramble_index[0]))
/************************************************************************
* Module-specific variables *
@ -421,7 +442,9 @@ ssize_t l_strfmon (char *restrict buf, size_t maxsize,
/***********************************************************************/
// scramble: Scramble (encrypt) the buffer
char *scramble (int key, char *restrict buf, int bufsize)
char *scramble (unsigned char *restrict key,
char *restrict inbuf, int inbufsize,
char *restrict outbuf, int outbufsize)
{
/* The algorithm used here is reversable: scramble(scramble(...))
will (or, at least, should!) return the same as the original
@ -429,11 +452,13 @@ char *scramble (int key, char *restrict buf, int bufsize)
function assumes all other characters are permitted in files.
This is true on all POSIX systems. */
if (buf != NULL && key != 0) {
char *p = buf;
unsigned char k = ~key;
assert(outbuf != NULL);
for (int i = 0; i < bufsize && *p != '\0'; i++, k++, p++) {
if (inbuf != NULL && key != NULL && *key != 0) {
char *p = inbuf;
unsigned char k = ~*key;
for (int i = 0; i < inbufsize && *p != '\0'; i++, k++, p++) {
char c = *p;
char r = c ^ k; // Simple encryption: XOR on a moving key
@ -444,16 +469,20 @@ char *scramble (int key, char *restrict buf, int bufsize)
}
}
return buf;
strcpy(outbuf, inbuf);
return outbuf;
}
/***********************************************************************/
// unscramble: Unscramble (decrypt) the buffer
char *unscramble (int key, char *restrict buf, int bufsize)
char *unscramble (unsigned char *restrict key,
char *restrict inbuf, int inbufsize,
char *restrict outbuf, int outbufsize)
{
return scramble(key, buf, bufsize);
return scramble(key, inbuf, inbufsize, outbuf, outbufsize);
}

View File

@ -265,41 +265,54 @@ extern ssize_t l_strfmon (char *restrict buf, size_t maxsize,
*/
/*
Function: scramble - Scramble (encrypt) the buffer
Parameters: key - Encryption key
buf - Pointer to buffer to encrypt
bufsize - Size of buffer
Returns: char * - Pointer to buffer
Function: scramble - Scramble (encrypt) the buffer
Parameters: key - Pointer to encryption/decryption key
inbuf - Pointer to input buffer to encrypt
inbufsize - Size of input buffer
outbuf - Pointer to output buffer
outbufsize - Size of output buffer
Returns: char * - Pointer to output buffer
This function scrambles (encrypts) the buffer *buf using a trivial
in-place encryption algorithm. If key is zero, or buf is NULL or
bufsize is less than 1, no encryption takes place.
This function scrambles (encrypts) the buffer *inbuf using a trivial
encryption algorithm and places the result in *outbuf. If key is NULL
or *key is zero, no encryption takes place: the input buffer is copied
to the output buffer as-is.
The buffer should contain a C-style string terminated by '\0'. The
characters '\r', '\n' and '\0' are guaranteed to remain the same before
and after encryption. At most bufsize bytes are encrypted; buf is
returned as the result.
The input buffer should contain a C-style string terminated by '\0'.
The characters '\r', '\n' and '\0' are guaranteed to remain the same
before and after encryption. Note that inbuf and outbuf MUST point to
different buffers, and that outbuf typically must be four times larger
than inbuf. At most inbufsize bytes are encrypted; outbuf is returned
as the result.
*/
extern char *scramble (int key, char *restrict buf, int bufsize);
extern char *scramble (unsigned char *restrict key,
char *restrict inbuf, int inbufsize,
char *restrict outbuf, int outbufsize);
/*
Function: unscramble - Unscramble (decrypt) the buffer
Parameters: key - Encryption/decryption key
buf - Pointer to buffer to decrypt
bufsize - Size of buffer
Returns: char * - Pointer to buffer
Parameters: key - Pointer to encryption/decryption key
inbuf - Pointer to input buffer to decrypt
inbufsize - Size of input buffer
outbuf - Pointer to output buffer
outbufsize - Size of output buffer
Returns: char * - Pointer to output buffer
This function does the reverse of scramble(): it unscrambles (decrypts)
the buffer *buf using an in-place algorithm. If key is zero, or buf is
NULL or bufsize is less than 1, no decryption takes place.
the buffer *inbuf using a trivial algorithm and places the result in
*outbuf. If key is NULL or *key is zero, no decryption takes place:
the input buffer is copied to the output buffer as-is.
The buffer should contain a C-style string terminated by '\0'. As for
scramble(), the characters '\r', '\n' and '\0' will not be changed (nor
will any encrypted character map back to these values). At most
bufsize bytes are decrypted; buf is returned as the result.
will any encrypted character map back to these values). Note that
inbuf and outbuf MUST point to different buffers. At most bufsize
bytes are decrypted; outbuf is returned as the result.
*/
extern char *unscramble (int key, char *restrict buf, int bufsize);
extern char *unscramble (unsigned char *restrict key,
char *restrict inbuf, int inbufsize,
char *restrict outbuf, int outbufsize);
/************************************************************************