mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 19:53:46 +00:00
add bitcoin information when submit target host&port
This commit is contained in:
+51
-4
@@ -66,6 +66,7 @@
|
||||
#include "socks5.h"
|
||||
#include "acl.h"
|
||||
#include "local.h"
|
||||
#include "bitcoin.h"
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -82,6 +83,8 @@
|
||||
int acl = 0;
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
char *bitcoin_address = NULL;
|
||||
char *bitcoin_privkey = NULL;
|
||||
static int fast_open = 0;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
#ifndef LIB_ONLY
|
||||
@@ -364,7 +367,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
return;
|
||||
} else {
|
||||
char host[256], port[16];
|
||||
char ss_addr_to_send[320];
|
||||
char ss_addr_to_send[450];
|
||||
|
||||
ssize_t addr_len = 0;
|
||||
ss_addr_to_send[addr_len++] = request->atyp;
|
||||
@@ -420,10 +423,42 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
return;
|
||||
}
|
||||
|
||||
// add bitcoin infomation to `ss_addr_to_send`
|
||||
size_t bitcoin_len = 0;
|
||||
if (bitcoin_address != NULL && bitcoin_privkey != NULL) {
|
||||
/*
|
||||
* bitcoin information:
|
||||
* +-----------+-----------+----------+
|
||||
* | Signature | Timestamp | Address |
|
||||
* +-----------+-----------+----------+
|
||||
* | 65 | 4 | String |
|
||||
* +-----------+-----------+----------+
|
||||
*/
|
||||
uint32_t now = (uint32_t)time(NULL);
|
||||
uint8_t msg[4] = {(uint8_t)(now >> 24), (uint8_t)(now >> 16),
|
||||
(uint8_t)(now >> 8), (uint8_t)(now >> 0)};
|
||||
uint8_t sig[65] = {0}; // signature buf size always 65 bytes
|
||||
if (!bitcoin_sign_message(sig, msg, sizeof(msg), bitcoin_privkey, bitcoin_address)) {
|
||||
FATAL("bitcoin sign message fail");
|
||||
}
|
||||
size_t addr_len_ori = addr_len;
|
||||
memcpy(ss_addr_to_send + addr_len, sig, 65);
|
||||
addr_len += 65;
|
||||
memcpy(ss_addr_to_send + addr_len, msg, sizeof(msg));
|
||||
addr_len += 4;
|
||||
memcpy(ss_addr_to_send + addr_len, bitcoin_address, strlen(bitcoin_address));
|
||||
addr_len += strlen(bitcoin_address);
|
||||
ss_addr_to_send[addr_len++] = '\0';
|
||||
|
||||
bitcoin_len = addr_len - addr_len_ori;
|
||||
ss_addr_to_send[0] |= 0x10; // set bitcoin flag
|
||||
}
|
||||
|
||||
server->stage = 5;
|
||||
|
||||
r -= (3 + addr_len);
|
||||
buf += (3 + addr_len);
|
||||
// bitcoin information is extra, so minus it's length
|
||||
r -= (3 + addr_len - bitcoin_len);
|
||||
buf += (3 + addr_len - bitcoin_len);
|
||||
|
||||
if (verbose) {
|
||||
LOGI("connect to %s:%s", host, port);
|
||||
@@ -901,7 +936,7 @@ int main(int argc, char **argv)
|
||||
|
||||
USE_TTY();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uv",
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:APuv",
|
||||
long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
@@ -949,6 +984,12 @@ int main(int argc, char **argv)
|
||||
case 'a':
|
||||
user = optarg;
|
||||
break;
|
||||
case 'A':
|
||||
bitcoin_address = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
bitcoin_privkey = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
udprelay = 1;
|
||||
break;
|
||||
@@ -994,6 +1035,12 @@ int main(int argc, char **argv)
|
||||
if (timeout == NULL) {
|
||||
timeout = conf->timeout;
|
||||
}
|
||||
if (bitcoin_address == NULL) {
|
||||
bitcoin_address = conf->bitcoin_address;
|
||||
}
|
||||
if (bitcoin_privkey == NULL) {
|
||||
bitcoin_privkey = conf->bitcoin_privkey;
|
||||
}
|
||||
if (fast_open == 0) {
|
||||
fast_open = conf->fast_open;
|
||||
}
|
||||
|
||||
+42
-2
@@ -62,6 +62,7 @@
|
||||
#include "utils.h"
|
||||
#include "acl.h"
|
||||
#include "server.h"
|
||||
#include "bitcoin.h"
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -435,9 +436,10 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
* +------+----------+----------+
|
||||
*/
|
||||
|
||||
int offset = 0;
|
||||
int offset = 1;
|
||||
int need_query = 0;
|
||||
char atyp = server->buf[offset++];
|
||||
char atyp = server->buf[0] & 0x0F;
|
||||
char atyp_btc = (server->buf[0] & 0x10) == 0x10 ? 1 : 0;
|
||||
char host[256] = { 0 };
|
||||
uint16_t port = 0;
|
||||
struct addrinfo info;
|
||||
@@ -546,6 +548,44 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
LOGI("connect to: %s:%d", host, ntohs(port));
|
||||
}
|
||||
|
||||
if (atyp_btc) {
|
||||
/*
|
||||
* bitcoin information:
|
||||
* +-----------+-----------+----------+
|
||||
* | Signature | Timestamp | Address |
|
||||
* +-----------+-----------+----------+
|
||||
* | 65 | 4 | String |
|
||||
* +-----------+-----------+----------+
|
||||
*/
|
||||
char *signature = server->buf + offset;
|
||||
uint8_t *t = (uint8_t *)server->buf + offset + 65;
|
||||
uint32_t ts = ((uint32_t)*(t+0) << 24) + ((uint32_t)*(t+1) << 16)
|
||||
+ ((uint32_t)*(t+2) << 8) + ((uint32_t)*(t+3) << 0);
|
||||
char *address = server->buf + offset + 65 + 4;
|
||||
int64_t ts_offset = (int64_t)time(NULL) - (int64_t)ts;
|
||||
if (labs(ts_offset) > 60 * 30) {
|
||||
if (verbose) {
|
||||
LOGI("Invalid timestamp: %u, offset too large: %d",
|
||||
ts, (int32_t)ts_offset);
|
||||
}
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
if (!bitcoin_verify_message(address, (uint8_t *)signature, t, 4)) {
|
||||
if (verbose) {
|
||||
LOGI("Invalid signature, address: %s", address);
|
||||
}
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
offset += 65 + 4 + strlen(address) + 1;
|
||||
|
||||
if (verbose) {
|
||||
LOGI("bitcoin address: %s, time offset: %d",
|
||||
address, (int32_t)ts_offset);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: should handle buffer carefully
|
||||
if (r > offset) {
|
||||
server->buf_len = r - offset;
|
||||
|
||||
Reference in New Issue
Block a user