Browse Source

fix #187

pull/196/merge
Max Lv 10 years ago
parent
commit
93d861f9b9
7 changed files with 87 additions and 56 deletions
  1. 79
      src/encrypt.c
  2. 10
      src/jconf.c
  3. 12
      src/local.c
  4. 3
      src/redir.c
  5. 5
      src/server.c
  6. 6
      src/tunnel.c
  7. 28
      src/utils.h

79
src/encrypt.c

@ -145,22 +145,23 @@ static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] =
static const int supported_ciphers_iv_size[CIPHER_NUM] = static const int supported_ciphers_iv_size[CIPHER_NUM] =
{ {
0, 0, 16, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16 , 8, 8
0, 0, 16, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16, 8, 8
}; };
static const int supported_ciphers_key_size[CIPHER_NUM] = static const int supported_ciphers_key_size[CIPHER_NUM] =
{ {
0, 16, 16, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16 , 32, 32
0, 16, 16, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16, 32, 32
}; };
static int crypto_stream_xor_ic(uint8_t *c, const uint8_t *m, uint64_t mlen, static int crypto_stream_xor_ic(uint8_t *c, const uint8_t *m, uint64_t mlen,
const uint8_t *n, uint64_t ic, const uint8_t *k, int method)
const uint8_t *n, uint64_t ic, const uint8_t *k,
int method)
{ {
switch (method) { switch (method) {
case SALSA20:
return crypto_stream_salsa20_xor_ic(c, m, mlen, n, ic, k);
case CHACHA20:
return crypto_stream_chacha20_xor_ic(c, m, mlen, n, ic, k);
case SALSA20:
return crypto_stream_salsa20_xor_ic(c, m, mlen, n, ic, k);
case CHACHA20:
return crypto_stream_chacha20_xor_ic(c, m, mlen, n, ic, k);
} }
// always return 0 // always return 0
return 0; return 0;
@ -453,8 +454,12 @@ int rand_bytes(uint8_t *output, int len)
urand = fopen("/dev/urandom", "r"); urand = fopen("/dev/urandom", "r");
if (urand) { if (urand) {
fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand);
int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1,
urand);
fclose(urand); fclose(urand);
if (read <= 0) {
rand_buffer.seed = (uint64_t)clock();
}
} else { } else {
rand_buffer.seed = (uint64_t)clock(); rand_buffer.seed = (uint64_t)clock();
} }
@ -687,8 +692,9 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len,
void cipher_context_release(cipher_ctx_t *ctx) void cipher_context_release(cipher_ctx_t *ctx)
{ {
if (enc_method >= SALSA20)
if (enc_method >= SALSA20) {
return; return;
}
#ifdef USE_CRYPTO_APPLECC #ifdef USE_CRYPTO_APPLECC
cipher_cc_t *cc = &ctx->cc; cipher_cc_t *cc = &ctx->cc;
@ -748,11 +754,13 @@ char * ss_encrypt_all(int buf_size, char *plaintext, ssize_t *len, int method)
if (method >= SALSA20) { if (method >= SALSA20) {
crypto_stream_xor_ic((uint8_t *)(ciphertext + iv_len), crypto_stream_xor_ic((uint8_t *)(ciphertext + iv_len),
(const uint8_t *)plaintext, (uint64_t)(p_len), (const uint8_t *)iv,
0, enc_key, method);
(const uint8_t *)plaintext, (uint64_t)(p_len),
(const uint8_t *)iv,
0, enc_key, method);
} else { } else {
err = cipher_context_update(&evp, (uint8_t *)(ciphertext + iv_len), err = cipher_context_update(&evp, (uint8_t *)(ciphertext + iv_len),
&c_len, (const uint8_t *)plaintext, p_len);
&c_len, (const uint8_t *)plaintext,
p_len);
} }
if (!err) { if (!err) {
@ -809,7 +817,7 @@ char * ss_encrypt(int buf_size, char *plaintext, ssize_t *len,
if (enc_method >= SALSA20) { if (enc_method >= SALSA20) {
int padding = ctx->counter % SODIUM_BLOCK_SIZE; int padding = ctx->counter % SODIUM_BLOCK_SIZE;
if (buf_len < iv_len + padding + c_len) { if (buf_len < iv_len + padding + c_len) {
buf_len= max(iv_len + (padding + c_len) * 2, buf_size);
buf_len = max(iv_len + (padding + c_len) * 2, buf_size);
ciphertext = realloc(ciphertext, buf_len); ciphertext = realloc(ciphertext, buf_len);
} }
if (padding) { if (padding) {
@ -818,15 +826,22 @@ char * ss_encrypt(int buf_size, char *plaintext, ssize_t *len,
memset(plaintext, 0, padding); memset(plaintext, 0, padding);
} }
crypto_stream_xor_ic((uint8_t *)(ciphertext + iv_len), crypto_stream_xor_ic((uint8_t *)(ciphertext + iv_len),
(const uint8_t *)plaintext, (uint64_t)(p_len + padding), (const uint8_t *)ctx->evp.iv,
ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method);
(const uint8_t *)plaintext,
(uint64_t)(p_len + padding),
(const uint8_t *)ctx->evp.iv,
ctx->counter / SODIUM_BLOCK_SIZE, enc_key,
enc_method);
ctx->counter += p_len; ctx->counter += p_len;
if (padding) { if (padding) {
memmove(ciphertext + iv_len, ciphertext + iv_len + padding, c_len);
memmove(ciphertext + iv_len, ciphertext + iv_len + padding,
c_len);
} }
} else { } else {
err = cipher_context_update(&ctx->evp, (uint8_t *)(ciphertext + iv_len),
&c_len, (const uint8_t *)plaintext, p_len);
err =
cipher_context_update(&ctx->evp,
(uint8_t *)(ciphertext + iv_len),
&c_len, (const uint8_t *)plaintext,
p_len);
if (!err) { if (!err) {
free(ciphertext); free(ciphertext);
free(plaintext); free(plaintext);
@ -869,12 +884,13 @@ char * ss_decrypt_all(int buf_size, char *ciphertext, ssize_t *len, int method)
if (method >= SALSA20) { if (method >= SALSA20) {
crypto_stream_xor_ic((uint8_t *)plaintext, crypto_stream_xor_ic((uint8_t *)plaintext,
(const uint8_t *)(ciphertext + iv_len), (uint64_t)(c_len - iv_len),
(const uint8_t *)iv, 0, enc_key, method);
(const uint8_t *)(ciphertext + iv_len),
(uint64_t)(c_len - iv_len),
(const uint8_t *)iv, 0, enc_key, method);
} else { } else {
err = cipher_context_update(&evp, (uint8_t *)plaintext, &p_len, err = cipher_context_update(&evp, (uint8_t *)plaintext, &p_len,
(const uint8_t *)(ciphertext + iv_len),
c_len - iv_len);
(const uint8_t *)(ciphertext + iv_len),
c_len - iv_len);
} }
if (!err) { if (!err) {
@ -932,21 +948,26 @@ char * ss_decrypt(int buf_size, char *ciphertext, ssize_t *len,
plaintext = realloc(plaintext, buf_len); plaintext = realloc(plaintext, buf_len);
} }
if (padding) { if (padding) {
ciphertext = realloc(ciphertext, max(c_len + padding, buf_size));
memmove(ciphertext + iv_len + padding, ciphertext + iv_len, c_len - iv_len);
ciphertext =
realloc(ciphertext, max(c_len + padding, buf_size));
memmove(ciphertext + iv_len + padding, ciphertext + iv_len,
c_len - iv_len);
memset(ciphertext + iv_len, 0, padding); memset(ciphertext + iv_len, 0, padding);
} }
crypto_stream_xor_ic((uint8_t *)plaintext, crypto_stream_xor_ic((uint8_t *)plaintext,
(const uint8_t *)(ciphertext + iv_len), (uint64_t)(c_len - iv_len + padding),
(const uint8_t *)ctx->evp.iv, ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method);
(const uint8_t *)(ciphertext + iv_len),
(uint64_t)(c_len - iv_len + padding),
(const uint8_t *)ctx->evp.iv,
ctx->counter / SODIUM_BLOCK_SIZE, enc_key,
enc_method);
ctx->counter += c_len - iv_len; ctx->counter += c_len - iv_len;
if (padding) { if (padding) {
memmove(plaintext, plaintext + padding, p_len); memmove(plaintext, plaintext + padding, p_len);
} }
} else { } else {
err = cipher_context_update(&ctx->evp, (uint8_t *)plaintext, &p_len, err = cipher_context_update(&ctx->evp, (uint8_t *)plaintext, &p_len,
(const uint8_t *)(ciphertext + iv_len),
c_len - iv_len);
(const uint8_t *)(ciphertext + iv_len),
c_len - iv_len);
} }
if (!err) { if (!err) {
@ -1011,7 +1032,7 @@ void enc_key_init(int method, const char *pass)
cipher->iv_size = supported_ciphers_iv_size[method]; cipher->iv_size = supported_ciphers_iv_size[method];
#endif #endif
} else { } else {
cipher = (cipher_kt_t *) get_cipher_type(method);
cipher = (cipher_kt_t *)get_cipher_type(method);
} }
if (cipher == NULL) { if (cipher == NULL) {

10
src/jconf.c

@ -74,16 +74,18 @@ void parse_addr(const char *str, ss_addr_t *addr)
} }
} }
if (ret == -1) { if (ret == -1) {
if (ipv6)
if (ipv6) {
addr->host = ss_strndup(str + 1, strlen(str) - 2); addr->host = ss_strndup(str + 1, strlen(str) - 2);
else
} else {
addr->host = strdup(str); addr->host = strdup(str);
}
addr->port = NULL; addr->port = NULL;
} else { } else {
if (ipv6)
if (ipv6) {
addr->host = ss_strndup(str + 1, ret - 2); addr->host = ss_strndup(str + 1, ret - 2);
else
} else {
addr->host = ss_strndup(str, ret); addr->host = ss_strndup(str, ret);
}
addr->port = strdup(str + ret + 1); addr->port = strdup(str + ret + 1);
} }
} }

12
src/local.c

@ -688,10 +688,14 @@ static struct remote * new_remote(int fd, int timeout)
remote->fd = fd; remote->fd = fd;
ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ);
ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb, min(MAX_CONNECT_TIMEOUT,
timeout), 0);
ev_timer_init(&remote->recv_ctx->watcher, remote_timeout_cb, min(MAX_CONNECT_TIMEOUT,
timeout), timeout);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb,
min(MAX_CONNECT_TIMEOUT,
timeout),
0);
ev_timer_init(&remote->recv_ctx->watcher, remote_timeout_cb,
min(MAX_CONNECT_TIMEOUT,
timeout),
timeout);
remote->recv_ctx->remote = remote; remote->recv_ctx->remote = remote;
remote->send_ctx->remote = remote; remote->send_ctx->remote = remote;
return remote; return remote;

3
src/redir.c

@ -471,7 +471,8 @@ static struct remote * new_remote(int fd, int timeout)
remote->fd = fd; remote->fd = fd;
ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ);
ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb, min(MAX_CONNECT_TIMEOUT, timeout), 0);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb,
min(MAX_CONNECT_TIMEOUT, timeout), 0);
remote->recv_ctx->remote = remote; remote->recv_ctx->remote = remote;
remote->recv_ctx->connected = 0; remote->recv_ctx->connected = 0;
remote->send_ctx->remote = remote; remote->send_ctx->remote = remote;

5
src/server.c

@ -233,7 +233,7 @@ static struct remote *connect_to_remote(struct addrinfo *res,
res->ai_addrlen); res->ai_addrlen);
if (s == -1) { if (s == -1) {
if (errno == EINPROGRESS || errno == EAGAIN if (errno == EINPROGRESS || errno == EAGAIN
|| errno == EWOULDBLOCK) {
|| errno == EWOULDBLOCK) {
// The remote server doesn't support tfo or it's the first connection to the server. // The remote server doesn't support tfo or it's the first connection to the server.
// It will automatically fall back to conventional TCP. // It will automatically fall back to conventional TCP.
} else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || } else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT ||
@ -803,7 +803,8 @@ static struct server * new_server(int fd, struct listen_ctx *listener)
ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ);
ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE);
ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb,
min(MAX_CONNECT_TIMEOUT, listener->timeout), listener->timeout);
min(MAX_CONNECT_TIMEOUT,
listener->timeout), listener->timeout);
server->recv_ctx->server = server; server->recv_ctx->server = server;
server->recv_ctx->connected = 0; server->recv_ctx->connected = 0;
server->send_ctx->server = server; server->send_ctx->server = server;

6
src/tunnel.c

@ -466,8 +466,10 @@ static struct remote * new_remote(int fd, int timeout)
remote->fd = fd; remote->fd = fd;
ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ);
ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb, min(MAX_CONNECT_TIMEOUT,
timeout), 0);
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb,
min(MAX_CONNECT_TIMEOUT,
timeout),
0);
remote->recv_ctx->remote = remote; remote->recv_ctx->remote = remote;
remote->recv_ctx->connected = 0; remote->recv_ctx->connected = 0;
remote->send_ctx->remote = remote; remote->send_ctx->remote = remote;

28
src/utils.h

@ -93,22 +93,22 @@ extern FILE * logfile;
#define USE_SYSLOG(ident) #define USE_SYSLOG(ident)
#define LOGD(format, ...) \
do { \
time_t now = time(NULL); \
char timestr[20]; \
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
fprintf(stderr, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \
fflush(stderr); } \
#define LOGD(format, ...) \
do { \
time_t now = time(NULL); \
char timestr[20]; \
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
fprintf(stderr, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \
fflush(stderr); } \
while (0) while (0)
#define LOGE(format, ...) \
do { \
time_t now = time(NULL); \
char timestr[20]; \
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
fprintf(stderr, " %s ERROR: " format "\n", timestr, ## __VA_ARGS__); \
fflush(stderr); } \
#define LOGE(format, ...) \
do { \
time_t now = time(NULL); \
char timestr[20]; \
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
fprintf(stderr, " %s ERROR: " format "\n", timestr, ## __VA_ARGS__); \
fflush(stderr); } \
while (0) while (0)
#else #else

Loading…
Cancel
Save