Browse Source

clean up

pull/66/head
Max Lv 10 years ago
parent
commit
fa2acecd62
11 changed files with 1065 additions and 936 deletions
  1. 225
      src/encrypt.c
  2. 6
      src/encrypt.h
  3. 8
      src/include.h
  4. 3
      src/jconf.c
  5. 1273
      src/json.c
  6. 283
      src/json.h
  7. 3
      src/local.c
  8. 2
      src/tunnel.c
  9. 49
      src/udprelay.c
  10. 116
      src/utils.c
  11. 33
      src/win32.c

225
src/encrypt.c

@ -109,11 +109,13 @@ static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] =
};
#ifdef USE_CRYPTO_POLARSSL
static const int supported_ciphers_iv_size[CIPHER_NUM] = {
static const int supported_ciphers_iv_size[CIPHER_NUM] =
{
0, 0, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16
};
static const int supported_ciphers_key_size[CIPHER_NUM] = {
static const int supported_ciphers_key_size[CIPHER_NUM] =
{
0, 16, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16
};
#endif
@ -211,7 +213,8 @@ unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md)
return MD5(d, n, md);
#elif defined(USE_CRYPTO_POLARSSL)
static unsigned char m[16];
if (md == NULL) {
if (md == NULL)
{
md = m;
}
md5(d, n, md);
@ -257,7 +260,8 @@ int cipher_iv_size(const cipher_kt_t *cipher)
#if defined(USE_CRYPTO_OPENSSL)
return EVP_CIPHER_iv_length (cipher);
#elif defined(USE_CRYPTO_POLARSSL)
if (cipher == NULL) {
if (cipher == NULL)
{
return 0;
}
return cipher->iv_size;
@ -269,11 +273,13 @@ int cipher_key_size (const cipher_kt_t *cipher)
#if defined(USE_CRYPTO_OPENSSL)
return EVP_CIPHER_key_length(cipher);
#elif defined(USE_CRYPTO_POLARSSL)
if (cipher == NULL) {
if (cipher == NULL)
{
return 0;
}
/* Override PolarSSL 32 bit default key size with sane 128 bit default */
if (cipher->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == cipher->base->cipher) {
if (cipher->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == cipher->base->cipher)
{
return 128 / 8;
}
return cipher->key_length / 8;
@ -299,28 +305,37 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8
nkey = cipher_key_size(cipher);
niv = cipher_iv_size(cipher);
rv = nkey;
if (pass == NULL) {
if (pass == NULL)
{
return nkey;
}
memset(&c, 0, sizeof(md_context_t));
if (md_init_ctx(&c, md)) {
if (md_init_ctx(&c, md))
{
return 0;
}
addmd = 0;
mds = md_get_size(md);
for (;;) {
for (;;)
{
int error;
do {
do
{
error = 1;
if (md_starts(&c)) {
if (md_starts(&c))
{
break;
}
if (addmd) {
if (md_update(&c, &(md_buf[0]), mds)) {
if (addmd)
{
if (md_update(&c, &(md_buf[0]), mds))
{
break;
}
} else {
}
}
else
{
addmd = 1;
}
if (md_update(&c, pass, datal))
@ -328,16 +343,20 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8
if (md_finish(&c, &(md_buf[0])))
break;
error = 0;
} while (0);
if (error) {
}
while (0);
if (error)
{
md_free_ctx(&c);
memset(md_buf, 0, MAX_MD_SIZE);
return 0;
}
i=0;
if (nkey) {
for (;;) {
if (nkey)
{
for (;;)
{
if (nkey == 0) break;
if (i == mds) break;
if (key != NULL)
@ -346,8 +365,10 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8
i++;
}
}
if (niv && (i != mds)) {
for (;;) {
if (niv && (i != mds))
{
for (;;)
{
if (niv == 0) break;
if (i == mds) break;
if (iv != NULL)
@ -374,39 +395,49 @@ int rand_bytes(uint8_t *output, int len)
static unsigned char rand_initialised = 0;
const size_t blen = min(len, CTR_DRBG_MAX_REQUEST);
if (!rand_initialised) {
if (!rand_initialised)
{
#ifdef _WIN32
HCRYPTPROV hProvider;
union {
union
{
unsigned __int64 seed;
BYTE buffer[8];
} rand_buffer;
hProvider = 0;
if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
CryptGenRandom(hProvider, 8, rand_buffer.buffer);
CryptReleaseContext(hProvider, 0);
} else {
}
else
{
rand_buffer.seed = (unsigned __int64) clock();
}
#else
FILE *urand;
union {
union
{
uint64_t seed;
uint8_t buffer[8];
} rand_buffer;
urand = fopen("/dev/urandom", "r");
if (urand) {
if (urand)
{
fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand);
fclose(urand);
} else {
}
else
{
rand_buffer.seed = (uint64_t) clock();
}
#endif
entropy_init(&ec);
if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *) rand_buffer.buffer, 8) != 0) {
if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *) rand_buffer.buffer, 8) != 0)
{
#if POLARSSL_VERSION_NUMBER >= 0x01030000
entropy_free(&ec);
#endif
@ -414,8 +445,10 @@ int rand_bytes(uint8_t *output, int len)
}
rand_initialised = 1;
}
while (len > 0) {
if (ctr_drbg_random(&cd_ctx, output, blen) != 0) {
while (len > 0)
{
if (ctr_drbg_random(&cd_ctx, output, blen) != 0)
{
return 0;
}
output += blen;
@ -427,7 +460,8 @@ int rand_bytes(uint8_t *output, int len)
const cipher_kt_t *get_cipher_type(int method)
{
if (method <= TABLE || method >= CIPHER_NUM) {
if (method <= TABLE || method >= CIPHER_NUM)
{
LOGE("get_cipher_type(): Illegal method");
return NULL;
}
@ -437,7 +471,8 @@ const cipher_kt_t *get_cipher_type(int method)
return EVP_get_cipherbyname(ciphername);
#elif defined(USE_CRYPTO_POLARSSL)
const char *polarname = supported_ciphers_polarssl[method];
if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0) {
if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0)
{
LOGE("Cipher %s currently is not supported by PolarSSL library", ciphername);
return NULL;
}
@ -447,7 +482,8 @@ const cipher_kt_t *get_cipher_type(int method)
const digest_type_t *get_digest_type(const char *digest)
{
if (digest == NULL) {
if (digest == NULL)
{
LOGE("get_digest_type(): Digest name is null");
return NULL;
}
@ -461,7 +497,8 @@ const digest_type_t *get_digest_type(const char *digest)
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
{
if (method <= TABLE || method >= CIPHER_NUM) {
if (method <= TABLE || method >= CIPHER_NUM)
{
LOGE("cipher_context_init(): Illegal method");
return;
}
@ -471,14 +508,20 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
cipher_cc_t *cc = &ctx->cc;
cc->cryptor = NULL;
cc->cipher = supported_ciphers_applecc[method];
if (cc->cipher == kCCAlgorithmInvalid) {
if (cc->cipher == kCCAlgorithmInvalid)
{
cc->valid = kCCContextInvalid;
} else {
}
else
{
cc->valid = kCCContextValid;
if (cc->cipher == kCCAlgorithmRC4) {
if (cc->cipher == kCCAlgorithmRC4)
{
cc->mode = kCCModeRC4;
cc->padding = ccNoPadding;
} else {
}
else
{
cc->mode = kCCModeCFB;
cc->padding = ccPKCS7Padding;
}
@ -489,29 +532,35 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
cipher_evp_t *evp = &ctx->evp;
const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
if (cipher == NULL) {
if (cipher == NULL)
{
LOGE("Cipher %s not found in OpenSSL library", ciphername);
FATAL("Cannot initialize cipher");
}
EVP_CIPHER_CTX_init(evp);
if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc))
{
LOGE("Cannot initialize cipher %s", ciphername);
exit(EXIT_FAILURE);
}
if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len))
{
EVP_CIPHER_CTX_cleanup(evp);
LOGE("Invalid key length: %d", enc_key_len);
exit(EXIT_FAILURE);
}
if (method > RC4) {
if (method > RC4)
{
EVP_CIPHER_CTX_set_padding(evp, 1);
}
#elif defined(USE_CRYPTO_POLARSSL)
if (cipher == NULL) {
if (cipher == NULL)
{
LOGE("Cipher %s not found in PolarSSL library", ciphername);
FATAL("Cannot initialize PolarSSL cipher");
}
if (cipher_init_ctx(evp, cipher) != 0) {
if (cipher_init_ctx(evp, cipher) != 0)
{
FATAL("Cannot initialize PolarSSL cipher context");
}
#endif
@ -519,38 +568,44 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int enc)
{
if (iv == NULL) {
if (iv == NULL)
{
LOGE("cipher_context_set_iv(): IV is null");
return;
}
if (enc) {
if (enc)
{
rand_bytes(iv, iv_len);
}
#ifdef USE_CRYPTO_APPLECC
cipher_cc_t *cc = &ctx->cc;
if (cc->valid == kCCContextValid) {
if (cc->valid == kCCContextValid)
{
memcpy(cc->iv, iv, iv_len);
memcpy(cc->key, enc_key, enc_key_len);
cc->iv_len = iv_len;
cc->key_len = enc_key_len;
cc->encrypt = enc ? kCCEncrypt : kCCDecrypt;
if (cc->cryptor != NULL) {
if (cc->cryptor != NULL)
{
CCCryptorRelease(cc->cryptor);
cc->cryptor = NULL;
}
CCCryptorStatus ret;
ret = CCCryptorCreateWithMode(
cc->encrypt,
cc->mode,
cc->cipher,
cc->padding,
cc->iv, cc->key, cc->key_len,
NULL, 0, 0, 0,
&cc->cryptor);
if (ret != kCCSuccess) {
if (cc->cryptor != NULL) {
cc->encrypt,
cc->mode,
cc->cipher,
cc->padding,
cc->iv, cc->key, cc->key_len,
NULL, 0, 0, 0,
&cc->cryptor);
if (ret != kCCSuccess)
{
if (cc->cryptor != NULL)
{
CCCryptorRelease(cc->cryptor);
cc->cryptor = NULL;
}
@ -561,31 +616,37 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int en
#endif
cipher_evp_t *evp = &ctx->evp;
if (evp == NULL) {
if (evp == NULL)
{
LOGE("cipher_context_set_iv(): Cipher context is null");
return;
}
#if defined(USE_CRYPTO_OPENSSL)
if (!EVP_CipherInit_ex(evp, NULL, NULL, enc_key, iv, enc)) {
if (!EVP_CipherInit_ex(evp, NULL, NULL, enc_key, iv, enc))
{
EVP_CIPHER_CTX_cleanup(evp);
FATAL("Cannot set key and IV");
}
#elif defined(USE_CRYPTO_POLARSSL)
if (cipher_setkey(evp, enc_key, enc_key_len * 8, enc) != 0) {
if (cipher_setkey(evp, enc_key, enc_key_len * 8, enc) != 0)
{
cipher_free_ctx(evp);
FATAL("Cannot set PolarSSL cipher key");
}
#if POLARSSL_VERSION_NUMBER >= 0x01030000
if (cipher_set_iv(evp, iv, iv_len) != 0) {
if (cipher_set_iv(evp, iv, iv_len) != 0)
{
cipher_free_ctx(evp);
FATAL("Cannot set PolarSSL cipher IV");
}
if(cipher_reset(evp) != 0) {
if(cipher_reset(evp) != 0)
{
cipher_free_ctx(evp);
FATAL("Cannot finalize PolarSSL cipher context");
}
#else
if(cipher_reset(evp, iv) != 0) {
if(cipher_reset(evp, iv) != 0)
{
cipher_free_ctx(evp);
FATAL("Cannot set PolarSSL cipher IV");
}
@ -597,14 +658,17 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int en
#endif
}
void cipher_context_release(cipher_ctx_t *ctx) {
void cipher_context_release(cipher_ctx_t *ctx)
{
#ifdef USE_CRYPTO_APPLECC
cipher_cc_t *cc = &ctx->cc;
if (cc->cryptor != NULL) {
if (cc->cryptor != NULL)
{
CCCryptorRelease(cc->cryptor);
cc->cryptor = NULL;
}
if (cc->valid == kCCContextValid) {
if (cc->valid == kCCContextValid)
{
return;
}
#endif
@ -618,10 +682,12 @@ void cipher_context_release(cipher_ctx_t *ctx) {
}
static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen,
const uint8_t *input, int ilen) {
const uint8_t *input, int ilen)
{
#ifdef USE_CRYPTO_APPLECC
cipher_cc_t *cc = &ctx->cc;
if (cc->valid == kCCContextValid) {
if (cc->valid == kCCContextValid)
{
CCCryptorStatus ret;
ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ilen + BLOCK_SIZE, (size_t *) olen);
return (ret == kCCSuccess) ? 1 : 0;
@ -841,7 +907,8 @@ void enc_ctx_init(int method, struct enc_ctx *ctx, int enc)
void enc_key_init(int method, const char *pass)
{
if (method <= TABLE || method >= CIPHER_NUM) {
if (method <= TABLE || method >= CIPHER_NUM)
{
LOGE("enc_key_init(): Illegal method");
return;
}
@ -856,10 +923,13 @@ void enc_key_init(int method, const char *pass)
uint8_t iv[MAX_IV_LENGTH];
const cipher_kt_t *cipher = get_cipher_type(method);
if (cipher == NULL) {
do {
if (cipher == NULL)
{
do
{
#if defined(USE_CRYPTO_POLARSSL) && defined(USE_CRYPTO_APPLECC)
if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) {
if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid)
{
cipher_info.base = NULL;
cipher_info.key_length = supported_ciphers_key_size[method] * 8;
cipher_info.iv_size = supported_ciphers_iv_size[method];
@ -869,15 +939,18 @@ void enc_key_init(int method, const char *pass)
#endif
LOGE("Cipher %s not found in crypto library", supported_ciphers[method]);
FATAL("Cannot initialize cipher");
} while (0);
}
while (0);
}
const digest_type_t *md = get_digest_type("MD5");
if (md == NULL) {
if (md == NULL)
{
FATAL("MD5 Digest not found in crypto library");
}
enc_key_len = bytes_to_key(cipher, md, (const uint8_t *) pass, enc_key, iv);
if (enc_key_len == 0) {
if (enc_key_len == 0)
{
FATAL("Cannot generate key and IV");
}
enc_iv_len = cipher_iv_size(cipher);

6
src/encrypt.h

@ -52,7 +52,8 @@ typedef md_info_t digest_type_t;
#define kCCContextValid 0
#define kCCContextInvalid -1
typedef struct {
typedef struct
{
CCCryptorRef cryptor;
int valid;
CCOperation encrypt;
@ -67,7 +68,8 @@ typedef struct {
#endif
typedef struct {
typedef struct
{
cipher_evp_t evp;
#ifdef USE_CRYPTO_APPLECC
cipher_cc_t cc;

8
src/include.h

@ -3,14 +3,14 @@
int udprelay_init(const char *server_host, const char *server_port,
#ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port,
const char *remote_host, const char *remote_port,
#ifdef UDPRELAY_TUNNEL
const ss_addr_t tunnel_addr,
const ss_addr_t tunnel_addr,
#endif
#endif
#ifdef UDPRELAY_REMOTE
asyncns_t *asyncns,
asyncns_t *asyncns,
#endif
int method, int timeout, const char *iface);
int method, int timeout, const char *iface);
#endif // _INCLUDE_H

3
src/jconf.c

@ -54,7 +54,8 @@ void parse_addr(const char *str, ss_addr_t *addr)
ret = pch - str;
pch = strchr(pch + 1, ':');
}
if (n > 1) {
if (n > 1)
{
if (strcmp(str+ret, "]") != 0)
{
ret = -1;

1273
src/json.c
File diff suppressed because it is too large
View File

283
src/json.h

@ -32,41 +32,41 @@
#define _JSON_H
#ifndef json_char
#define json_char char
#define json_char char
#endif
#ifndef json_int_t
#ifndef _MSC_VER
#include <inttypes.h>
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#ifndef _MSC_VER
#include <inttypes.h>
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#endif
#include <stdlib.h>
#ifdef __cplusplus
#include <string.h>
#include <string.h>
extern "C"
{
extern "C"
{
#endif
typedef struct
{
unsigned long max_memory;
int settings;
unsigned long max_memory;
int settings;
/* Custom allocator support (leave null to use malloc/free)
*/
/* Custom allocator support (leave null to use malloc/free)
*/
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * user_data; /* will be passed to mem_alloc and mem_free */
void * user_data; /* will be passed to mem_alloc and mem_free */
} json_settings;
@ -74,14 +74,14 @@ typedef struct
typedef enum
{
json_none,
json_object,
json_array,
json_integer,
json_double,
json_string,
json_boolean,
json_null
json_none,
json_object,
json_array,
json_integer,
json_double,
json_string,
json_boolean,
json_null
} json_type;
@ -89,181 +89,186 @@ extern const struct _json_value json_value_none;
typedef struct _json_value
{
struct _json_value * parent;
json_type type;
union
{
int boolean;
json_int_t integer;
double dbl;
struct _json_value * parent;
struct
{
unsigned int length;
json_char * ptr; /* null terminated */
json_type type;
} string;
union
{
int boolean;
json_int_t integer;
double dbl;
struct
{
unsigned int length;
struct
{
unsigned int length;
json_char * ptr; /* null terminated */
struct
{
json_char * name;
unsigned int name_length;
} string;
struct _json_value * value;
struct
{
unsigned int length;
} * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} object;
struct
{
json_char * name;
unsigned int name_length;
struct _json_value * value;
} * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{
return values;
}
decltype(values) end () const
{
return values + length;
}
#endif
struct
{
unsigned int length;
struct _json_value ** values;
} object;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
struct
{
unsigned int length;
struct _json_value ** values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{
return values;
}
decltype(values) end () const
{
return values + length;
}
#endif
} array;
} array;
} u;
} u;
union
{
struct _json_value * next_alloc;
void * object_mem;
union
{
struct _json_value * next_alloc;
void * object_mem;
} _reserved;
} _reserved;
/* Some C++ operator sugar */
/* Some C++ operator sugar */
#ifdef __cplusplus
#ifdef __cplusplus
public:
public:
inline _json_value ()
{ memset (this, 0, sizeof (_json_value));
}
inline _json_value ()
{
memset (this, 0, sizeof (_json_value));
}
inline const struct _json_value &operator [] (int index) const
{
inline const struct _json_value &operator [] (int index) const
{
if (type != json_array || index < 0
|| ((unsigned int) index) >= u.array.length)
|| ((unsigned int) index) >= u.array.length)
{
return json_value_none;
return json_value_none;
}
return *u.array.values [index];
}
}
inline const struct _json_value &operator [] (const char * index) const
{
inline const struct _json_value &operator [] (const char * index) const
{
if (type != json_object)
return json_value_none;
return json_value_none;
for (unsigned int i = 0; i < u.object.length; ++ i)
if (!strcmp (u.object.values [i].name, index))
return *u.object.values [i].value;
if (!strcmp (u.object.values [i].name, index))
return *u.object.values [i].value;
return json_value_none;
}
}
inline operator const char * () const
{
inline operator const char * () const
{
switch (type)
{
case json_string:
return u.string.ptr;
case json_string:
return u.string.ptr;
default:
return "";
default:
return "";
};
}
}
inline operator json_int_t () const
{
inline operator json_int_t () const
{
switch (type)
{
case json_integer:
return u.integer;
case json_integer:
return u.integer;
case json_double:
return (json_int_t) u.dbl;
case json_double:
return (json_int_t) u.dbl;
default:
return 0;
default:
return 0;
};
}
}
inline operator bool () const
{
inline operator bool () const
{
if (type != json_boolean)
return false;
return false;
return u.boolean != 0;
}
}
inline operator double () const
{
inline operator double () const
{
switch (type)
{
case json_integer:
return (double) u.integer;
case json_integer:
return (double) u.integer;
case json_double:
return u.dbl;
case json_double:
return u.dbl;
default:
return 0;
default:
return 0;
};
}
}
#endif
#endif
} json_value;
} json_value;
json_value * json_parse (const json_char * json,
size_t length);
json_value * json_parse (const json_char * json,
size_t length);
#define json_error_max 128
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *);
void json_value_free (json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif
#endif

3
src/local.c

@ -361,7 +361,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
return;
}
if (request->cmd == 3) {
if (request->cmd == 3)
{
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;

2
src/tunnel.c

@ -874,7 +874,7 @@ int main (int argc, char **argv)
{
LOGD("udprelay enabled.");
udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port,
tunnel_addr, m, listen_ctx.timeout, iface);
tunnel_addr, m, listen_ctx.timeout, iface);
}
// setuid

49
src/udprelay.c

@ -158,23 +158,24 @@ static char *get_addr_str(const struct sockaddr *sa)
char port[PORTSTRLEN] = {0};
uint16_t p;
switch(sa->sa_family) {
case AF_INET:
inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
addr, INET_ADDRSTRLEN);
p = ntohs(((struct sockaddr_in *)sa)->sin_port);
sprintf(port, "%d", p);
break;
switch(sa->sa_family)
{
case AF_INET:
inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
addr, INET_ADDRSTRLEN);
p = ntohs(((struct sockaddr_in *)sa)->sin_port);
sprintf(port, "%d", p);
break;
case AF_INET6:
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
addr, INET6_ADDRSTRLEN);
p = ntohs(((struct sockaddr_in *)sa)->sin_port);
sprintf(port, "%d", p);
break;
case AF_INET6:
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
addr, INET6_ADDRSTRLEN);
p = ntohs(((struct sockaddr_in *)sa)->sin_port);
sprintf(port, "%d", p);
break;
default:
strncpy(s, "Unknown AF", SS_ADDRSTRLEN);
default:
strncpy(s, "Unknown AF", SS_ADDRSTRLEN);
}
int addr_len = strlen(addr);
@ -504,7 +505,8 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents)
#ifdef UDPRELAY_LOCAL
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
if (buf == NULL){
if (buf == NULL)
{
if (verbose)
{
ERROR("udprelay_server_ss_decrypt_all");
@ -587,7 +589,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
#ifdef UDPRELAY_REMOTE
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
if (buf == NULL){
if (buf == NULL)
{
if (verbose)
{
ERROR("udprelay_server_ss_decrypt_all");
@ -808,7 +811,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
}
struct query_ctx *query_ctx = new_query_ctx(query, buf + addr_header_len,
buf_len - addr_header_len);
buf_len - addr_header_len);
query_ctx->server_ctx = server_ctx;
query_ctx->addr_header_len = addr_header_len;
query_ctx->src_addr = src_addr;
@ -820,7 +823,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
else
{
int s = sendto(remote_ctx->fd, buf + addr_header_len,
buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));
buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));
if (s == -1)
{
@ -848,15 +851,15 @@ void free_cb(void *element)
int udprelay_init(const char *server_host, const char *server_port,
#ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port,
const char *remote_host, const char *remote_port,
#ifdef UDPRELAY_TUNNEL
const ss_addr_t tunnel_addr,
const ss_addr_t tunnel_addr,
#endif
#endif
#ifdef UDPRELAY_REMOTE
asyncns_t *asyncns,
asyncns_t *asyncns,
#endif
int method, int timeout, const char *iface)
int method, int timeout, const char *iface)
{
// Inilitialize ev loop

116
src/utils.c

@ -68,83 +68,83 @@ char *itoa(int i)
int run_as(const char *user)
{
#ifndef __MINGW32__
if (user[0])
if (user[0])
{
#ifdef HAVE_GETPWNAM_R
struct passwd pwdbuf, *pwd;
size_t buflen;
int err;
struct passwd pwdbuf, *pwd;
size_t buflen;
int err;
for (buflen = 128;; buflen *= 2)
for (buflen = 128;; buflen *= 2)
{
char buf[buflen]; /* variable length array */
char buf[buflen]; /* variable length array */
/* Note that we use getpwnam_r() instead of getpwnam(),
which returns its result in a statically allocated buffer and
cannot be considered thread safe. */
err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd);
if(err == 0 && pwd)
/* Note that we use getpwnam_r() instead of getpwnam(),
which returns its result in a statically allocated buffer and
cannot be considered thread safe. */
err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd);
if(err == 0 && pwd)
{
/* setgid first, because we may not be allowed to do it anymore after setuid */
if (setgid(pwd->pw_gid) != 0)
/* setgid first, because we may not be allowed to do it anymore after setuid */
if (setgid(pwd->pw_gid) != 0)
{
LOGE("Could not change group id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
LOGE("Could not change group id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
if (setuid(pwd->pw_uid) != 0)
if (setuid(pwd->pw_uid) != 0)
{
LOGE("Could not change user id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
break;
}
else if (err != ERANGE)
LOGE("Could not change user id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
break;
}
else if (err != ERANGE)
{
if(err)
LOGE("run_as user '%s' could not be found: %s",user,strerror(err));
else
LOGE("run_as user '%s' could not be found.",user);
return 0;
}
else if (buflen >= 16*1024)
if(err)
LOGE("run_as user '%s' could not be found: %s",user,strerror(err));
else
LOGE("run_as user '%s' could not be found.",user);
return 0;
}
else if (buflen >= 16*1024)
{
/* If getpwnam_r() seems defective, call it quits rather than
keep on allocating ever larger buffers until we crash. */
LOGE("getpwnam_r() requires more than %u bytes of buffer space.",(unsigned)buflen);
return 0;
}
/* Else try again with larger buffer. */
}
/* If getpwnam_r() seems defective, call it quits rather than
keep on allocating ever larger buffers until we crash. */
LOGE("getpwnam_r() requires more than %u bytes of buffer space.",(unsigned)buflen);
return 0;
}
/* Else try again with larger buffer. */
}
#else
/* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */
struct passwd *pwd;
/* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */
struct passwd *pwd;
if (!(pwd=getpwnam(user)))
if (!(pwd=getpwnam(user)))
{
LOGE("run_as user %s could not be found.",user);
return 0;
}
/* setgid first, because we may not allowed to do it anymore after setuid */
if (setgid(pwd->pw_gid) != 0)
LOGE("run_as user %s could not be found.",user);
return 0;
}
/* setgid first, because we may not allowed to do it anymore after setuid */
if (setgid(pwd->pw_gid) != 0)
{
LOGE("Could not change group id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
if (setuid(pwd->pw_uid) != 0)
LOGE("Could not change group id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
if (setuid(pwd->pw_uid) != 0)
{
LOGE("Could not change user id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
LOGE("Could not change user id to that of run_as user '%s': %s",
user,strerror(errno));
return 0;
}
#endif
}
}
#endif //__MINGW32__
return 1;
return 1;
}

33
src/win32.c

@ -11,10 +11,12 @@ void winsock_init(void)
int ret;
wVersionRequested = MAKEWORD(1, 1);
ret = WSAStartup(wVersionRequested, &wsaData);
if (ret != 0) {
if (ret != 0)
{
FATAL("Could not initialize winsock");
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
FATAL("Could not find a usable version of winsock");
}
@ -28,11 +30,12 @@ void winsock_cleanup(void)
void ss_error(const char *s)
{
LPVOID *msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &msg, 0, NULL);
if (msg != NULL) {
if (msg != NULL)
{
LOGE("%s: %s", s, (char *)msg);
LocalFree(msg);
}
@ -43,7 +46,8 @@ int setnonblocking(int fd)
u_long iMode = 0;
long int iResult;
iResult = ioctlsocket(fd, FIONBIO, &iMode);
if (iResult != NO_ERROR) {
if (iResult != NO_ERROR)
{
LOGE("ioctlsocket failed with error: %ld\n", iResult);
}
return iResult;
@ -61,15 +65,16 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
unsigned long s = size;
ZeroMemory(&ss, sizeof(ss));
ss.ss_family = af;
switch (af) {
case AF_INET:
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
break;
case AF_INET6:
((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
break;
default:
return NULL;
switch (af)
{
case AF_INET:
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
break;
case AF_INET6:
((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
break;
default:
return NULL;
}
return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL;
}
Loading…
Cancel
Save