mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-27 19:23:40 +00:00
disable btc feature when built with PolarSSL
This commit is contained in:
+247
-116
@@ -19,6 +19,13 @@
|
||||
* along with shadowsocks-libev; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
|
||||
#include "bitcoin.h"
|
||||
|
||||
#include <assert.h>
|
||||
@@ -50,15 +57,15 @@
|
||||
|
||||
|
||||
#define skip_char(c) \
|
||||
(((c) == '\r') || ((c) == '\n') || ((c) == ' ') || ((c) == '\t'))
|
||||
(((c) == '\r') || ((c) == '\n') || ((c) == ' ') || ((c) == '\t'))
|
||||
|
||||
const char *vg_b58_alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
const signed char vg_b58_reverse_map[256] = {
|
||||
-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, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1,
|
||||
-1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1,
|
||||
-1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21, -1,
|
||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1,
|
||||
-1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46,
|
||||
47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
|
||||
@@ -72,7 +79,8 @@ const signed char vg_b58_reverse_map[256] = {
|
||||
};
|
||||
|
||||
|
||||
static int vg_b58_decode_check(const char *input, void *buf, size_t len) {
|
||||
static int vg_b58_decode_check(const char *input, void *buf, size_t len)
|
||||
{
|
||||
int i, l, c;
|
||||
unsigned char *xbuf = NULL;
|
||||
BIGNUM bn, bnw, bnbase;
|
||||
@@ -90,11 +98,13 @@ static int vg_b58_decode_check(const char *input, void *buf, size_t len) {
|
||||
/* Build a bignum from the encoded value */
|
||||
l = strlen(input);
|
||||
for (i = 0; i < l; i++) {
|
||||
if (skip_char(input[i]))
|
||||
if (skip_char(input[i])) {
|
||||
continue;
|
||||
}
|
||||
c = vg_b58_reverse_map[(int)input[i]];
|
||||
if (c < 0)
|
||||
if (c < 0) {
|
||||
goto out;
|
||||
}
|
||||
BN_clear(&bnw);
|
||||
BN_set_word(&bnw, c);
|
||||
BN_mul(&bn, &bn, &bnbase, bnctx);
|
||||
@@ -103,41 +113,50 @@ static int vg_b58_decode_check(const char *input, void *buf, size_t len) {
|
||||
|
||||
/* Copy the bignum to a byte buffer */
|
||||
for (i = 0, zpfx = 0; input[i]; i++) {
|
||||
if (skip_char(input[i]))
|
||||
if (skip_char(input[i])) {
|
||||
continue;
|
||||
if (input[i] != vg_b58_alphabet[0])
|
||||
}
|
||||
if (input[i] != vg_b58_alphabet[0]) {
|
||||
break;
|
||||
}
|
||||
zpfx++;
|
||||
}
|
||||
c = BN_num_bytes(&bn);
|
||||
l = zpfx + c;
|
||||
if (l < 5)
|
||||
if (l < 5) {
|
||||
goto out;
|
||||
xbuf = (unsigned char *) malloc(l);
|
||||
if (!xbuf)
|
||||
}
|
||||
xbuf = (unsigned char *)malloc(l);
|
||||
if (!xbuf) {
|
||||
goto out;
|
||||
if (zpfx)
|
||||
}
|
||||
if (zpfx) {
|
||||
memset(xbuf, 0, zpfx);
|
||||
if (c)
|
||||
}
|
||||
if (c) {
|
||||
BN_bn2bin(&bn, xbuf + zpfx);
|
||||
}
|
||||
|
||||
/* Check the hash code */
|
||||
l -= 4;
|
||||
SHA256(xbuf, l, hash1);
|
||||
SHA256(hash1, sizeof(hash1), hash2);
|
||||
if (memcmp(hash2, xbuf + l, 4))
|
||||
if (memcmp(hash2, xbuf + l, 4)) {
|
||||
goto out;
|
||||
}
|
||||
/* Buffer verified */
|
||||
if (len) {
|
||||
if (len > l)
|
||||
if (len > l) {
|
||||
len = l;
|
||||
}
|
||||
memcpy(buf, xbuf, len);
|
||||
}
|
||||
res = l;
|
||||
|
||||
out:
|
||||
if (xbuf)
|
||||
out:
|
||||
if (xbuf) {
|
||||
free(xbuf);
|
||||
}
|
||||
BN_clear_free(&bn);
|
||||
BN_clear_free(&bnw);
|
||||
BN_clear_free(&bnbase);
|
||||
@@ -169,7 +188,7 @@ static void vg_b58_encode_check(void *buf, size_t len, char *result)
|
||||
bndiv = &bnb;
|
||||
|
||||
brlen = (2 * len) + 4;
|
||||
binres = (unsigned char*) malloc(brlen);
|
||||
binres = (unsigned char *)malloc(brlen);
|
||||
memcpy(binres, buf, len);
|
||||
|
||||
SHA256(binres, len, hash1);
|
||||
@@ -178,7 +197,9 @@ static void vg_b58_encode_check(void *buf, size_t len, char *result)
|
||||
|
||||
BN_bin2bn(binres, len + 4, bn);
|
||||
|
||||
for (zpfx = 0; zpfx < (len + 4) && binres[zpfx] == 0; zpfx++);
|
||||
for (zpfx = 0; zpfx < (len + 4) && binres[zpfx] == 0; zpfx++) {
|
||||
;
|
||||
}
|
||||
|
||||
p = (int)brlen;
|
||||
while (!BN_is_zero(bn)) {
|
||||
@@ -196,7 +217,7 @@ static void vg_b58_encode_check(void *buf, size_t len, char *result)
|
||||
|
||||
memcpy(result, &binres[p], brlen - p);
|
||||
result[brlen - p] = '\0';
|
||||
|
||||
|
||||
free(binres);
|
||||
BN_clear_free(&bna);
|
||||
BN_clear_free(&bnb);
|
||||
@@ -208,8 +229,8 @@ static void vg_b58_encode_check(void *buf, size_t len, char *result)
|
||||
static void vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
|
||||
point_conversion_form_t form, int addr_type, char *result)
|
||||
{
|
||||
unsigned char eckey_buf[128] = {0};
|
||||
unsigned char binres[21] = {0,};
|
||||
unsigned char eckey_buf[128] = { 0 };
|
||||
unsigned char binres[21] = { 0, };
|
||||
unsigned char hash1[32];
|
||||
size_t len = 0;
|
||||
|
||||
@@ -222,7 +243,8 @@ static void vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
|
||||
vg_b58_encode_check(binres, sizeof(binres), result);
|
||||
}
|
||||
|
||||
static size_t write_compact_size(const uint64_t val, uint8_t *dest) {
|
||||
static size_t write_compact_size(const uint64_t val, uint8_t *dest)
|
||||
{
|
||||
if (val < 0xfd) {
|
||||
*dest++ = (unsigned char)val;
|
||||
return 1;
|
||||
@@ -243,10 +265,11 @@ static size_t write_compact_size(const uint64_t val, uint8_t *dest) {
|
||||
}
|
||||
|
||||
static void dsha265_message(uint8_t *hash,
|
||||
const uint8_t *msg, const size_t len_msg) {
|
||||
const uint8_t *msg, const size_t len_msg)
|
||||
{
|
||||
const char *magic = "Bitcoin Signed Message:\n"; // bitcoin message magic
|
||||
const size_t len_magic = strlen(magic);
|
||||
size_t buf_size = len_magic + len_msg + 9/*max_compact_size*/ * 2;
|
||||
size_t buf_size = len_magic + len_msg + 9 /*max_compact_size*/ * 2;
|
||||
|
||||
char *buf = (char *)malloc(buf_size);
|
||||
size_t buf_len = 0;
|
||||
@@ -267,33 +290,41 @@ static void dsha265_message(uint8_t *hash,
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) {
|
||||
static int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey) return 0;
|
||||
if (!eckey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
if (pub_key == NULL)
|
||||
if (pub_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
EC_KEY_set_private_key(eckey,priv_key);
|
||||
EC_KEY_set_public_key(eckey,pub_key);
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
EC_KEY_set_public_key(eckey, pub_key);
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (pub_key)
|
||||
err:
|
||||
if (pub_key) {
|
||||
EC_POINT_free(pub_key);
|
||||
if (ctx != NULL)
|
||||
}
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -302,8 +333,11 @@ err:
|
||||
// if check is non-zero, additional checks are performed
|
||||
static int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig,
|
||||
const unsigned char *msg,
|
||||
int msglen, int recid, int check) {
|
||||
if (!eckey) return 0;
|
||||
int msglen, int recid, int check)
|
||||
{
|
||||
if (!eckey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
@@ -323,63 +357,114 @@ static int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig,
|
||||
int i = recid / 2;
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
order = BN_CTX_get(ctx);
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
x = BN_CTX_get(ctx);
|
||||
if (!BN_copy(x, order)) { ret=-1; goto err; }
|
||||
if (!BN_mul_word(x, i)) { ret=-1; goto err; }
|
||||
if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
|
||||
if (!BN_copy(x, order)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
if (!BN_mul_word(x, i)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
if (!BN_add(x, x, ecsig->r)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
field = BN_CTX_get(ctx);
|
||||
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
|
||||
if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
|
||||
if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
|
||||
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if (BN_cmp(x, field) >= 0) {
|
||||
ret = 0; goto err;
|
||||
}
|
||||
if ((R = EC_POINT_new(group)) == NULL) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) {
|
||||
ret = 0; goto err;
|
||||
}
|
||||
if (check) {
|
||||
if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
|
||||
if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
|
||||
if ((O = EC_POINT_new(group)) == NULL) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(group, O)) {
|
||||
ret = 0; goto err;
|
||||
}
|
||||
}
|
||||
if ((Q = EC_POINT_new(group)) == NULL) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
n = EC_GROUP_get_degree(group);
|
||||
e = BN_CTX_get(ctx);
|
||||
if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
|
||||
if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
|
||||
if (!BN_bin2bn(msg, msglen, e)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
if (8 * msglen > n) {
|
||||
BN_rshift(e, e, 8 - (n & 7));
|
||||
}
|
||||
zero = BN_CTX_get(ctx);
|
||||
if (!BN_zero(zero)) { ret=-1; goto err; }
|
||||
if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
|
||||
if (!BN_zero(zero)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
if (!BN_mod_sub(e, zero, e, order, ctx)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
rr = BN_CTX_get(ctx);
|
||||
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
|
||||
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
sor = BN_CTX_get(ctx);
|
||||
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
|
||||
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
eor = BN_CTX_get(ctx);
|
||||
if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
|
||||
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
|
||||
if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
|
||||
if (!BN_mod_mul(eor, e, rr, order, ctx)) {
|
||||
ret = -1; goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
if (!EC_KEY_set_public_key(eckey, Q)) {
|
||||
ret = -2; goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
err:
|
||||
if (ctx) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
if (R != NULL) EC_POINT_free(R);
|
||||
if (O != NULL) EC_POINT_free(O);
|
||||
if (Q != NULL) EC_POINT_free(Q);
|
||||
if (R != NULL) {
|
||||
EC_POINT_free(R);
|
||||
}
|
||||
if (O != NULL) {
|
||||
EC_POINT_free(O);
|
||||
}
|
||||
if (Q != NULL) {
|
||||
EC_POINT_free(Q);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int priv_key_b58_to_address(const char *priv_key_b58,
|
||||
const int is_compressed_pubkey,
|
||||
const int addr_type,
|
||||
char *address) {
|
||||
EC_KEY *pkey = NULL;
|
||||
unsigned char buf[128] = {0};
|
||||
char *address)
|
||||
{
|
||||
EC_KEY *pkey = NULL;
|
||||
unsigned char buf[128] = { 0 };
|
||||
uint8_t pubKey[65]; // public key max size is 65 bytes
|
||||
char ecprot[128];
|
||||
unsigned char *pbegin = NULL;
|
||||
unsigned char *pbegin = NULL;
|
||||
int res, pubkey_size = 0;
|
||||
int fOk = 0;
|
||||
|
||||
@@ -392,13 +477,19 @@ static int priv_key_b58_to_address(const char *priv_key_b58,
|
||||
BIGNUM *bn = BN_bin2bn(buf + 1, 32, BN_new());
|
||||
res = EC_KEY_regenerate_key(pkey, bn);
|
||||
BN_clear_free(bn);
|
||||
if (!res){ goto error; }
|
||||
if (!res) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// get pubkey
|
||||
pubkey_size = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!pubkey_size) { goto error; }
|
||||
if (!pubkey_size) {
|
||||
goto error;
|
||||
}
|
||||
pbegin = pubKey;
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != pubkey_size) { goto error; }
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != pubkey_size) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// encode address
|
||||
vg_encode_address(EC_KEY_get0_public_key(pkey),
|
||||
@@ -409,8 +500,10 @@ static int priv_key_b58_to_address(const char *priv_key_b58,
|
||||
strcpy(address, ecprot);
|
||||
fOk = 1;
|
||||
|
||||
error:
|
||||
if (pkey) { EC_KEY_free(pkey); }
|
||||
error:
|
||||
if (pkey) {
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
return fOk;
|
||||
}
|
||||
|
||||
@@ -419,7 +512,8 @@ error:
|
||||
// -1 : invalid private key
|
||||
// 1 : compressed
|
||||
// 0 : uncompressed
|
||||
static int isCompressedAddress(const char *priv_key_b58, const char *address) {
|
||||
static int isCompressedAddress(const char *priv_key_b58, const char *address)
|
||||
{
|
||||
int is_compressed_pubkey;
|
||||
char buf[64];
|
||||
int res;
|
||||
@@ -429,7 +523,9 @@ static int isCompressedAddress(const char *priv_key_b58, const char *address) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
res = priv_key_b58_to_address(priv_key_b58, is_compressed_pubkey,
|
||||
BITCOIN_ADDRESS_PREFIX_PUBKEY, buf);
|
||||
if (res != 1) { return -1; }
|
||||
if (res != 1) {
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, address, strlen(address)) == 0) {
|
||||
return 1; // compressed
|
||||
}
|
||||
@@ -439,7 +535,9 @@ static int isCompressedAddress(const char *priv_key_b58, const char *address) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
res = priv_key_b58_to_address(priv_key_b58, is_compressed_pubkey,
|
||||
BITCOIN_ADDRESS_PREFIX_PUBKEY, buf);
|
||||
if (res != 1) { return -1; }
|
||||
if (res != 1) {
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, address, strlen(address)) == 0) {
|
||||
return 0; // uncompressed
|
||||
}
|
||||
@@ -449,18 +547,19 @@ static int isCompressedAddress(const char *priv_key_b58, const char *address) {
|
||||
|
||||
static int sign_message(uint8_t *signature_65,
|
||||
const uint8_t *msg, const size_t msg_len,
|
||||
const char *priv_key_b58, int is_compressed_pubkey) {
|
||||
EC_KEY *pkey = NULL;
|
||||
const char *priv_key_b58, int is_compressed_pubkey)
|
||||
{
|
||||
EC_KEY *pkey = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
EC_KEY *eckey = NULL; // recover key
|
||||
EC_KEY *eckey = NULL; // recover key
|
||||
|
||||
uint8_t pubKey[65]; // public key max size is 65 bytes
|
||||
uint8_t pubKey[65]; // public key max size is 65 bytes
|
||||
uint8_t pubKey_rc[65];
|
||||
int pubkey_size, pubkey_rc_size;
|
||||
uint8_t sigbuf[65];
|
||||
|
||||
unsigned char *pbegin = NULL;
|
||||
unsigned char buf[128] = {0};
|
||||
unsigned char buf[128] = { 0 };
|
||||
int res, fOK = 0;
|
||||
int nBitsR, nBitsS;
|
||||
unsigned char hash[32];
|
||||
@@ -477,18 +576,26 @@ static int sign_message(uint8_t *signature_65,
|
||||
res = EC_KEY_regenerate_key(pkey, bn);
|
||||
BN_clear_free(bn);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (!res){ goto error; }
|
||||
if (!res) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// get pubkey
|
||||
pubkey_size = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!pubkey_size) { goto error; }
|
||||
if (!pubkey_size) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
pbegin = pubKey;
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != pubkey_size) { goto error; }
|
||||
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != pubkey_size) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// do sign
|
||||
sig = ECDSA_do_sign(hash, sizeof(hash), pkey);
|
||||
if (!sig) { goto error; }
|
||||
if (!sig) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
nBitsR = BN_num_bits(sig->r);
|
||||
nBitsS = BN_num_bits(sig->s);
|
||||
@@ -501,11 +608,13 @@ static int sign_message(uint8_t *signature_65,
|
||||
POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ECDSA_SIG_recover_key_GFp(eckey, sig, (unsigned char*)hash,
|
||||
if (ECDSA_SIG_recover_key_GFp(eckey, sig, (unsigned char *)hash,
|
||||
sizeof(hash), i, 1) == 1) {
|
||||
// get recover pubkey
|
||||
pubkey_rc_size = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!pubkey_rc_size) { goto error; }
|
||||
if (!pubkey_rc_size) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
pbegin = pubKey_rc;
|
||||
if (i2o_ECPublicKey(eckey, &pbegin) != pubkey_rc_size) {
|
||||
@@ -519,38 +628,48 @@ static int sign_message(uint8_t *signature_65,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nRecId == -1) { goto error; }
|
||||
if (nRecId == -1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
sigbuf[0] = nRecId + 27 + (is_compressed_pubkey ? 4 : 0);
|
||||
BN_bn2bin(sig->r, sigbuf + 33 - (nBitsR+7)/8);
|
||||
BN_bn2bin(sig->s, sigbuf + 65 - (nBitsS+7)/8);
|
||||
BN_bn2bin(sig->r, sigbuf + 33 - (nBitsR + 7) / 8);
|
||||
BN_bn2bin(sig->s, sigbuf + 65 - (nBitsS + 7) / 8);
|
||||
|
||||
memcpy(signature_65, sigbuf, 65);
|
||||
fOK = 1;
|
||||
}
|
||||
|
||||
error:
|
||||
if (pkey) { EC_KEY_free(pkey); }
|
||||
if (eckey) { EC_KEY_free(eckey); }
|
||||
if (sig) { ECDSA_SIG_free(sig); }
|
||||
|
||||
|
||||
error:
|
||||
if (pkey) {
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
if (eckey) {
|
||||
EC_KEY_free(eckey);
|
||||
}
|
||||
if (sig) {
|
||||
ECDSA_SIG_free(sig);
|
||||
}
|
||||
|
||||
return fOK;
|
||||
}
|
||||
|
||||
|
||||
int bitcoin_sign_message(unsigned char *buf_65,
|
||||
const void *msg, const size_t msg_len,
|
||||
const char *priv_key_b58, const char *address) {
|
||||
const char *priv_key_b58, const char *address)
|
||||
{
|
||||
int is_compressed = isCompressedAddress(priv_key_b58, address);
|
||||
return sign_message(buf_65, (uint8_t *)msg, msg_len,
|
||||
priv_key_b58, is_compressed);
|
||||
}
|
||||
|
||||
int bitcoin_verify_message(const char *address, const unsigned char *sig,
|
||||
const void *msg, const size_t msglen) {
|
||||
const void *msg, const size_t msglen)
|
||||
{
|
||||
EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
uint8_t hash[32] = {0};
|
||||
char ecprot[128] = {0};
|
||||
uint8_t hash[32] = { 0 };
|
||||
char ecprot[128] = { 0 };
|
||||
int fOK = 0;
|
||||
|
||||
// message double sha256
|
||||
@@ -558,12 +677,14 @@ int bitcoin_verify_message(const char *address, const unsigned char *sig,
|
||||
|
||||
// recover
|
||||
ECDSA_SIG *esig = ECDSA_SIG_new();
|
||||
BN_bin2bn(&sig[1], 32, esig->r);
|
||||
BN_bin2bn(&sig[1], 32, esig->r);
|
||||
BN_bin2bn(&sig[33], 32, esig->s);
|
||||
int ret = ECDSA_SIG_recover_key_GFp(pkey, esig, hash, sizeof(hash),
|
||||
((sig[0] - 27) & ~4), 0) == 1;
|
||||
ECDSA_SIG_free(esig);
|
||||
if (!ret) { goto error; }
|
||||
if (!ret) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
int is_compressed_pubkey = (sig[0] - 27) & 4;
|
||||
// encode address
|
||||
@@ -576,8 +697,10 @@ int bitcoin_verify_message(const char *address, const unsigned char *sig,
|
||||
fOK = 1;
|
||||
}
|
||||
|
||||
error:
|
||||
if (pkey) { EC_KEY_free(pkey); }
|
||||
error:
|
||||
if (pkey) {
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
return fOK;
|
||||
}
|
||||
|
||||
@@ -591,29 +714,32 @@ struct btc_list {
|
||||
size_t number;
|
||||
char *file;
|
||||
pthread_rwlock_t lock;
|
||||
pthread_t thread;
|
||||
pthread_t thread;
|
||||
int running;
|
||||
};
|
||||
|
||||
static int cmp_btc_client(const void *l, const void *r) {
|
||||
static int cmp_btc_client(const void *l, const void *r)
|
||||
{
|
||||
struct btc_client *pl = (struct btc_client *)l;
|
||||
struct btc_client *pr = (struct btc_client *)r;
|
||||
return strcmp(pl->address, pr->address);
|
||||
}
|
||||
|
||||
extern struct btc_list *bitcoin_init_list(const char *file) {
|
||||
extern struct btc_list *bitcoin_init_list(const char *file)
|
||||
{
|
||||
struct btc_list *l = calloc(1, sizeof(struct btc_list));
|
||||
l->clients = NULL;
|
||||
pthread_rwlock_init(&l->lock, NULL);
|
||||
l->number = 0;
|
||||
l->file = strdup(file);
|
||||
l->number = 0;
|
||||
l->file = strdup(file);
|
||||
l->running = 1;
|
||||
return l;
|
||||
}
|
||||
|
||||
static void *check_list(void *ptr) {
|
||||
static void *check_list(void *ptr)
|
||||
{
|
||||
struct btc_list *list = (struct btc_list *)ptr;
|
||||
time_t last_check_time = 0;
|
||||
time_t last_check_time = 0;
|
||||
time_t last_modify_time = 0;
|
||||
|
||||
struct stat attrib;
|
||||
@@ -654,7 +780,7 @@ static void *check_list(void *ptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t idx = 0;
|
||||
size_t idx = 0;
|
||||
struct btc_client *clients = calloc(size, sizeof(struct btc_client));
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
while (strlen(line) > 0 && !isalpha(line[strlen(line) - 1])) {
|
||||
@@ -691,7 +817,7 @@ static void *check_list(void *ptr) {
|
||||
free(list->clients);
|
||||
}
|
||||
list->clients = clients;
|
||||
list->number = idx;
|
||||
list->number = idx;
|
||||
pthread_rwlock_unlock(&list->lock);
|
||||
|
||||
last_modify_time = attrib.st_mtime;
|
||||
@@ -700,14 +826,16 @@ static void *check_list(void *ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern int bitcoin_setup_update_thread(struct btc_list *list) {
|
||||
extern int bitcoin_setup_update_thread(struct btc_list *list)
|
||||
{
|
||||
if (pthread_create(&list->thread, NULL, check_list, list) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
extern void bitcoin_clean_update_thread(struct btc_list *list) {
|
||||
extern void bitcoin_clean_update_thread(struct btc_list *list)
|
||||
{
|
||||
pthread_rwlock_wrlock(&list->lock);
|
||||
list->running = 0;
|
||||
pthread_rwlock_unlock(&list->lock);
|
||||
@@ -716,7 +844,8 @@ extern void bitcoin_clean_update_thread(struct btc_list *list) {
|
||||
}
|
||||
|
||||
extern int bitcoin_check_address(struct btc_list *list,
|
||||
const char *address) {
|
||||
const char *address)
|
||||
{
|
||||
struct btc_client key, *res = NULL;
|
||||
memset(&key, 0, sizeof(struct btc_client));
|
||||
strncpy(key.address, address, 35);
|
||||
@@ -733,3 +862,5 @@ extern int bitcoin_check_address(struct btc_list *list,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@@ -178,10 +182,12 @@ jconf_t *read_jconf(const char * file)
|
||||
conf.nofile = value->u.integer;
|
||||
} else if (strcmp(name, "nameserver") == 0) {
|
||||
conf.nameserver = to_string(value);
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
} else if (strcmp(name, "bitcoin_address") == 0) {
|
||||
conf.bitcoin_address = to_string(value);
|
||||
} else if (strcmp(name, "bitcoin_privkey") == 0) {
|
||||
conf.bitcoin_privkey = to_string(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -45,8 +45,10 @@ typedef struct {
|
||||
int fast_open;
|
||||
int nofile;
|
||||
char *nameserver;
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
char *bitcoin_address;
|
||||
char *bitcoin_privkey;
|
||||
#endif
|
||||
} jconf_t;
|
||||
|
||||
jconf_t *read_jconf(const char * file);
|
||||
|
||||
+22
-8
@@ -66,7 +66,10 @@
|
||||
#include "socks5.h"
|
||||
#include "acl.h"
|
||||
#include "local.h"
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
#include "bitcoin.h"
|
||||
#endif
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -83,8 +86,6 @@
|
||||
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
|
||||
@@ -92,6 +93,11 @@ static int nofile = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
char *bitcoin_address = NULL;
|
||||
char *bitcoin_privkey = NULL;
|
||||
#endif
|
||||
|
||||
static void server_recv_cb(EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb(EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb(EV_P_ ev_io *w, int revents);
|
||||
@@ -423,6 +429,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
// add bitcoin infomation to `ss_addr_to_send`
|
||||
size_t bitcoin_len = 0;
|
||||
if (bitcoin_address != NULL && bitcoin_privkey != NULL) {
|
||||
@@ -435,9 +442,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
* +-----------+-----------+----------+
|
||||
*/
|
||||
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
|
||||
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");
|
||||
}
|
||||
@@ -454,11 +461,12 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
ss_addr_to_send[0] |= 0x10; // set bitcoin flag
|
||||
}
|
||||
|
||||
server->stage = 5;
|
||||
|
||||
// bitcoin information is extra, so minus it's length
|
||||
r -= (3 + addr_len - bitcoin_len);
|
||||
r -= (3 + addr_len - bitcoin_len);
|
||||
buf += (3 + addr_len - bitcoin_len);
|
||||
#endif
|
||||
|
||||
server->stage = 5;
|
||||
|
||||
if (verbose) {
|
||||
LOGI("connect to %s:%s", host, port);
|
||||
@@ -929,8 +937,10 @@ int main(int argc, char **argv)
|
||||
{
|
||||
{ "fast-open", no_argument, 0, 0 },
|
||||
{ "acl", required_argument, 0, 0 },
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
{ "bitcoin-address", required_argument, 0, 0 },
|
||||
{ "bitcoin-privkey", required_argument, 0, 0 },
|
||||
#endif
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -947,10 +957,12 @@ int main(int argc, char **argv)
|
||||
} else if (option_index == 1) {
|
||||
LOGI("initialize acl...");
|
||||
acl = !init_acl(optarg);
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
} else if (strcmp(long_options[option_index].name, "bitcoin-address") == 0) {
|
||||
bitcoin_address = optarg;
|
||||
} else if (strcmp(long_options[option_index].name, "bitcoin-privkey") == 0) {
|
||||
bitcoin_privkey = optarg;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
@@ -1035,12 +1047,14 @@ int main(int argc, char **argv)
|
||||
if (timeout == NULL) {
|
||||
timeout = conf->timeout;
|
||||
}
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
if (bitcoin_address == NULL) {
|
||||
bitcoin_address = conf->bitcoin_address;
|
||||
}
|
||||
if (bitcoin_privkey == NULL) {
|
||||
bitcoin_privkey = conf->bitcoin_privkey;
|
||||
}
|
||||
#endif
|
||||
if (fast_open == 0) {
|
||||
fast_open = conf->fast_open;
|
||||
}
|
||||
|
||||
+5
-5
@@ -654,13 +654,13 @@ int main(int argc, char **argv)
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(argc == 1) {
|
||||
if(conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
|
||||
if (argc == 1) {
|
||||
if (conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (conf_path != NULL) {
|
||||
jconf_t *conf = read_jconf(conf_path);
|
||||
if (remote_num == 0) {
|
||||
|
||||
+27
-11
@@ -62,7 +62,10 @@
|
||||
#include "utils.h"
|
||||
#include "acl.h"
|
||||
#include "server.h"
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
#include "bitcoin.h"
|
||||
#endif
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -104,13 +107,16 @@ int acl = 0;
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
static int fast_open = 0;
|
||||
struct btc_list *bitcoin_list = NULL;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
static int nofile = 0;
|
||||
#endif
|
||||
static int remote_conn = 0;
|
||||
static int server_conn = 0;
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
struct btc_list *bitcoin_list = NULL;
|
||||
#endif
|
||||
|
||||
static struct cork_dllist connections;
|
||||
|
||||
static void free_connections(struct ev_loop *loop)
|
||||
@@ -440,7 +446,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
int offset = 1;
|
||||
int need_query = 0;
|
||||
char atyp = server->buf[0] & 0x0F;
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
char atyp_btc = (server->buf[0] & 0x10) == 0x10 ? 1 : 0;
|
||||
#endif
|
||||
char host[256] = { 0 };
|
||||
uint16_t port = 0;
|
||||
struct addrinfo info;
|
||||
@@ -549,6 +557,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
LOGI("connect to: %s:%d", host, ntohs(port));
|
||||
}
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
if (bitcoin_list != NULL) {
|
||||
if (atyp_btc == 0) {
|
||||
if (verbose) {
|
||||
@@ -567,8 +576,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
*/
|
||||
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);
|
||||
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) {
|
||||
@@ -600,6 +609,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
address, (int32_t)ts_offset);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX: should handle buffer carefully
|
||||
if (r > offset) {
|
||||
@@ -1143,7 +1153,9 @@ int main(int argc, char **argv)
|
||||
{
|
||||
{ "fast-open", no_argument, 0, 0 },
|
||||
{ "acl", required_argument, 0, 0 },
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
{ "bitcoin-list", required_argument, 0, 0 },
|
||||
#endif
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -1160,12 +1172,14 @@ int main(int argc, char **argv)
|
||||
} else if (option_index == 1) {
|
||||
LOGI("initialize acl...");
|
||||
acl = !init_acl(optarg);
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
} else if (strcmp(long_options[option_index].name, "bitcoin-list") == 0) {
|
||||
LOGI("bitcoin list file: %s", optarg);
|
||||
bitcoin_list = bitcoin_init_list(optarg);
|
||||
if (bitcoin_setup_update_thread(bitcoin_list) == 0) {
|
||||
FATAL("setup bitcoin check list thread failure");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
@@ -1216,13 +1230,13 @@ int main(int argc, char **argv)
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(argc == 1) {
|
||||
if(conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
|
||||
if (argc == 1) {
|
||||
if (conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (conf_path != NULL) {
|
||||
jconf_t *conf = read_jconf(conf_path);
|
||||
if (server_num == 0) {
|
||||
@@ -1280,7 +1294,7 @@ int main(int argc, char **argv)
|
||||
if (method == NULL) {
|
||||
method = "table";
|
||||
}
|
||||
|
||||
|
||||
if (timeout == NULL) {
|
||||
timeout = "60";
|
||||
}
|
||||
@@ -1355,7 +1369,7 @@ int main(int argc, char **argv)
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", host?host:"*", server_port);
|
||||
LOGI("listening at %s:%s", host ? host : "*", server_port);
|
||||
|
||||
struct listen_ctx *listen_ctx = &listen_ctx_list[index];
|
||||
|
||||
@@ -1408,10 +1422,12 @@ int main(int argc, char **argv)
|
||||
if (udprelay) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
if (bitcoin_list) {
|
||||
bitcoin_clean_update_thread(bitcoin_list);
|
||||
}
|
||||
#endif
|
||||
|
||||
resolv_shutdown(loop);
|
||||
|
||||
|
||||
+5
-5
@@ -709,13 +709,13 @@ int main(int argc, char **argv)
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(argc == 1) {
|
||||
if(conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
|
||||
if (argc == 1) {
|
||||
if (conf_path == NULL) {
|
||||
conf_path = DEFAULT_CONF_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (conf_path != NULL) {
|
||||
jconf_t *conf = read_jconf(conf_path);
|
||||
if (remote_num == 0) {
|
||||
|
||||
@@ -266,6 +266,7 @@ void usage()
|
||||
printf(
|
||||
" only available in local and server mode\n");
|
||||
printf("\n");
|
||||
#ifdef USE_CRYPTO_OPENSSL
|
||||
printf(
|
||||
" [--bitcoin-list <bitcoin_file>] config file of address list\n");
|
||||
printf(
|
||||
@@ -281,6 +282,7 @@ void usage()
|
||||
printf(
|
||||
" only available in local mode\n");
|
||||
printf("\n");
|
||||
#endif
|
||||
printf(
|
||||
" [-v] verbose mode\n");
|
||||
printf("\n");
|
||||
|
||||
+11
-11
@@ -121,10 +121,10 @@ extern FILE * logfile;
|
||||
#include <syslog.h>
|
||||
|
||||
extern int use_tty;
|
||||
#define USE_TTY() \
|
||||
do { \
|
||||
use_tty = isatty(STDERR_FILENO); \
|
||||
} while (0) \
|
||||
#define USE_TTY() \
|
||||
do { \
|
||||
use_tty = isatty(STDERR_FILENO); \
|
||||
} while (0) \
|
||||
|
||||
#define HAS_SYSLOG
|
||||
extern int use_syslog;
|
||||
@@ -145,14 +145,14 @@ extern int use_syslog;
|
||||
time_t now = time(NULL); \
|
||||
char timestr[20]; \
|
||||
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
|
||||
if(use_tty) { \
|
||||
if (use_tty) { \
|
||||
fprintf(stderr, "\e[01;32m %s INFO: \e[0m" format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} else { \
|
||||
fprintf(stderr, "%s INFO: " format "\n", timestr, \
|
||||
} else { \
|
||||
fprintf(stderr, "%s INFO: " format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -164,13 +164,13 @@ extern int use_syslog;
|
||||
time_t now = time(NULL); \
|
||||
char timestr[20]; \
|
||||
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
|
||||
if(use_tty) { \
|
||||
if (use_tty) { \
|
||||
fprintf(stderr, "\e[01;35m %s ERROR: \e[0m" format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} else { \
|
||||
fprintf(stderr, " %s ERROR: " format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} } \
|
||||
while (0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user