Browse Source

fix auth in udprelay

pull/405/head
Max Lv 9 years ago
parent
commit
8d46ced3c9
8 changed files with 28 additions and 18 deletions
  1. 2
      src/common.h
  2. 3
      src/encrypt.c
  3. 4
      src/local.c
  4. 2
      src/redir.c
  5. 2
      src/server.c
  6. 2
      src/tunnel.c
  7. 30
      src/udprelay.c
  8. 1
      src/udprelay.h

2
src/common.h

@ -60,7 +60,7 @@ int init_udprelay(const char *server_host, const char *server_port,
const ss_addr_t tunnel_addr,
#endif
#endif
int method, int timeout, const char *iface);
int method, int auth, int timeout, const char *iface);
void free_udprelay(void);

3
src/encrypt.c

@ -1244,8 +1244,9 @@ char * ss_decrypt_all(int buf_size, char *ciphertext, ssize_t *len, int method,
c_len - iv_len);
}
if (auth) {
if (auth || (plaintext[0] & ONETIMEAUTH_FLAG)) {
char hash[ONETIMEAUTH_BYTES];
memcpy(hash, plaintext + p_len - ONETIMEAUTH_BYTES, ONETIMEAUTH_BYTES);
ret = !ss_onetimeauth_verify(hash, plaintext, p_len - ONETIMEAUTH_BYTES, iv);
if (ret) p_len -= ONETIMEAUTH_BYTES;
}

4
src/local.c

@ -1153,7 +1153,7 @@ int main(int argc, char **argv)
if (mode != TCP_ONLY) {
LOGI("udprelay enabled");
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, iface);
get_sockaddr_len(listen_ctx.remote_addr[0]), m, auth, listen_ctx.timeout, iface);
}
LOGI("listening at %s:%s", local_addr, local_port);
@ -1289,7 +1289,7 @@ int start_ss_local_server(profile_t profile)
LOGI("udprelay enabled");
struct sockaddr *addr = (struct sockaddr *)storage;
init_udprelay(local_addr, local_port_str, addr,
get_sockaddr_len(addr), m, timeout, NULL);
get_sockaddr_len(addr), m, auth, timeout, NULL);
}
LOGI("listening at %s:%s", local_addr, local_port_str);

2
src/redir.c

@ -794,7 +794,7 @@ int main(int argc, char **argv)
if (mode != TCP_ONLY) {
LOGI("UDP relay enabled");
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, NULL);
get_sockaddr_len(listen_ctx.remote_addr[0]), m, auth, listen_ctx.timeout, NULL);
}
if (mode == UDP_ONLY) {

2
src/server.c

@ -1473,7 +1473,7 @@ int main(int argc, char **argv)
// Setup UDP
if (mode != TCP_ONLY) {
init_udprelay(server_host[index], server_port, m, atoi(timeout),
init_udprelay(server_host[index], server_port, m, auth, atoi(timeout),
iface);
}

2
src/tunnel.c

@ -873,7 +873,7 @@ int main(int argc, char **argv)
LOGI("UDP relay enabled");
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]),
tunnel_addr, m, listen_ctx.timeout, iface);
tunnel_addr, m, auth, listen_ctx.timeout, iface);
}
if (mode == UDP_ONLY) {

30
src/udprelay.c

@ -216,14 +216,17 @@ static int construct_udprealy_header(const struct sockaddr_storage *in_addr,
#endif
static int parse_udprealy_header(const char * buf, const int buf_len,
char *host, char *port,
int *auth, char *host, char *port,
struct sockaddr_storage *storage)
{
const uint8_t atyp = *(uint8_t *)buf;
int offset = 1;
if (auth != NULL) *auth |= (atyp & ONETIMEAUTH_FLAG);
// get remote addr and port
if (atyp == 1) {
if ((atyp & ADDRTYPE_MASK) == 1) {
// IP V4
size_t in_addr_len = sizeof(struct in_addr);
if (buf_len > in_addr_len) {
@ -239,7 +242,7 @@ static int parse_udprealy_header(const char * buf, const int buf_len,
}
offset += in_addr_len;
}
} else if (atyp == 3) {
} else if ((atyp & ADDRTYPE_MASK) == 3) {
// Domain name
uint8_t name_len = *(uint8_t *)(buf + offset);
if (name_len < buf_len && name_len < 255 && name_len > 0) {
@ -264,7 +267,7 @@ static int parse_udprealy_header(const char * buf, const int buf_len,
}
}
}
} else if (atyp == 4) {
} else if ((atyp & ADDRTYPE_MASK) == 4) {
// IP V6
size_t in6_addr_len = sizeof(struct in6_addr);
if (buf_len > in6_addr_len) {
@ -657,14 +660,14 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
#ifdef UDPRELAY_REDIR
struct sockaddr_storage dst_addr;
memset(&dst_addr, 0, sizeof(struct sockaddr_storage));
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, &dst_addr);
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL, &dst_addr);
if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) {
LOGI("[udp] ss-redir does not support domain name");
goto CLEAN_UP;
}
#else
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL);
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL, NULL);
#endif
if (len == 0) {
@ -830,7 +833,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
tx += buf_len;
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, 1);
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, server_ctx->auth);
if (buf == NULL) {
ERROR("[udp] server_ss_decrypt_all");
goto CLEAN_UP;
@ -972,8 +975,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
struct sockaddr_storage dst_addr;
memset(&dst_addr, 0, sizeof(struct sockaddr_storage));
int addr_header_len = parse_udprealy_header(buf + offset,
buf_len - offset, host, port,
int addr_header_len = parse_udprealy_header(buf + offset, buf_len - offset,
&server_ctx->auth, host, port,
&dst_addr);
if (addr_header_len == 0) {
// error in parse header
@ -1089,7 +1092,11 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
memmove(buf, buf + offset, buf_len);
}
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, 1);
if (server_ctx->auth) {
buf[0] |= ONETIMEAUTH_FLAG;
}
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, server_ctx->auth);
int s = sendto(remote_ctx->fd, buf, buf_len, 0, remote_addr, remote_addr_len);
@ -1213,7 +1220,7 @@ int init_udprelay(const char *server_host, const char *server_port,
const ss_addr_t tunnel_addr,
#endif
#endif
int method, int timeout, const char *iface)
int method, int auth, int timeout, const char *iface)
{
// Inilitialize ev loop
struct ev_loop *loop = EV_DEFAULT;
@ -1236,6 +1243,7 @@ int init_udprelay(const char *server_host, const char *server_port,
#ifdef UDPRELAY_REMOTE
server_ctx->loop = loop;
#endif
server_ctx->auth = auth;
server_ctx->timeout = max(timeout, MIN_UDP_TIMEOUT);
server_ctx->method = method;
server_ctx->iface = iface;

1
src/udprelay.h

@ -45,6 +45,7 @@ struct server_ctx {
ev_io io;
int fd;
int method;
int auth;
int timeout;
const char *iface;
struct cache *conn_cache;

Loading…
Cancel
Save