Exemple #1
0
static int
vg_regex_test(vg_exec_context_t *vxcp)
{
	vg_regex_context_t *vcrp = (vg_regex_context_t *) vxcp->vxc_vc;

	unsigned char hash1[32], hash2[32];
	int i, zpfx, p, d, nres, re_vec[9];
	char b58[40];
	BIGNUM bnrem;
	BIGNUM *bn, *bndiv, *bnptmp;
	int res = 0;

	pcre *re;

	BN_init(&bnrem);

	/* Hash the hash and write the four byte check code */
	SHA256(vxcp->vxc_binres, 21, hash1);
	SHA256(hash1, sizeof(hash1), hash2);
	memcpy(&vxcp->vxc_binres[21], hash2, 4);

	bn = &vxcp->vxc_bntmp;
	bndiv = &vxcp->vxc_bntmp2;

	BN_bin2bn(vxcp->vxc_binres, 25, bn);

	/* Compute the complete encoded address */
	for (zpfx = 0; zpfx < 25 && vxcp->vxc_binres[zpfx] == 0; zpfx++);
	p = sizeof(b58) - 1;
	b58[p] = '\0';
	while (!BN_is_zero(bn)) {
		BN_div(bndiv, &bnrem, bn, &vxcp->vxc_bnbase, vxcp->vxc_bnctx);
		bnptmp = bn;
		bn = bndiv;
		bndiv = bnptmp;
		d = BN_get_word(&bnrem);
		b58[--p] = vg_b58_alphabet[d];
	}
	while (zpfx--) {
		b58[--p] = vg_b58_alphabet[0];
	}

	/*
	 * Run the regular expressions on it
	 * SLOW, runs in linear time with the number of REs
	 */
restart_loop:
	nres = vcrp->base.vc_npatterns;
	if (!nres) {
		res = 2;
		goto out;
	}
	for (i = 0; i < nres; i++) {
		d = pcre_exec(vcrp->vcr_regex[i],
			      vcrp->vcr_regex_extra[i],
			      &b58[p], (sizeof(b58) - 1) - p, 0,
			      0,
			      re_vec, sizeof(re_vec)/sizeof(re_vec[0]));

		if (d <= 0) {
			if (d != PCRE_ERROR_NOMATCH) {
				fprintf(stderr, "PCRE error: %d\n", d);
				res = 2;
				goto out;
			}
			continue;
		}

		re = vcrp->vcr_regex[i];

		if (vg_exec_context_upgrade_lock(vxcp) &&
		    ((i >= vcrp->base.vc_npatterns) ||
		     (vcrp->vcr_regex[i] != re)))
			goto restart_loop;

		vg_exec_context_consolidate_key(vxcp);
		vcrp->base.vc_output_match(&vcrp->base, vxcp->vxc_key,
					   vcrp->vcr_regex_pat[i]);
		vcrp->base.vc_found++;

		if (vcrp->base.vc_only_one) {
			res = 2;
			goto out;
		}

		if (vcrp->base.vc_remove_on_match) {
			pcre_free(vcrp->vcr_regex[i]);
			if (vcrp->vcr_regex_extra[i])
				pcre_free(vcrp->vcr_regex_extra[i]);
			nres -= 1;
			vcrp->base.vc_npatterns = nres;
			if (!nres) {
				res = 2;
				goto out;
			}
			vcrp->vcr_regex[i] = vcrp->vcr_regex[nres];
			vcrp->vcr_regex_extra[i] =
				vcrp->vcr_regex_extra[nres];
			vcrp->vcr_regex_pat[i] = vcrp->vcr_regex_pat[nres];
			vcrp->base.vc_npatterns = nres;
			vcrp->base.vc_pattern_generation++;
		}
		res = 1;
	}
out:
	BN_clear_free(&bnrem);
	return res;
}
void nsHttpConnectionInfo::BuildHashKey()
{
    //
    // build hash key:
    //
    // the hash key uniquely identifies the connection type.  two connections
    // are "equal" if they end up talking the same protocol to the same server
    // and are both used for anonymous or non-anonymous connection only;
    // anonymity of the connection is setup later from nsHttpChannel::AsyncOpen
    // where we know we use anonymous connection (LOAD_ANONYMOUS load flag)
    //

    const char *keyHost;
    int32_t keyPort;

    if (mUsingHttpProxy && !mUsingConnect) {
        keyHost = ProxyHost();
        keyPort = ProxyPort();
    } else {
        keyHost = Origin();
        keyPort = OriginPort();
    }

    // The hashkey has 4 fields followed by host connection info
    // byte 0 is P/T/. {P,T} for Plaintext/TLS Proxy over HTTP
    // byte 1 is S/. S is for end to end ssl such as https:// uris
    // byte 2 is A/. A is for an anonymous channel (no cookies, etc..)
    // byte 3 is P/. P is for a private browising channel
    // byte 4 is I/. I is for insecure scheme on TLS for http:// uris
    // byte 5 is X/. X is for disallow_spdy flag
    // byte 6 is C/. C is for be Conservative

    mHashKey.AssignLiteral(".......[tlsflags0x00000000]");

    mHashKey.Append(keyHost);
    if (!mNetworkInterfaceId.IsEmpty()) {
        mHashKey.Append('(');
        mHashKey.Append(mNetworkInterfaceId);
        mHashKey.Append(')');
    }
    mHashKey.Append(':');
    mHashKey.AppendInt(keyPort);
    if (!mUsername.IsEmpty()) {
        mHashKey.Append('[');
        mHashKey.Append(mUsername);
        mHashKey.Append(']');
    }

    if (mUsingHttpsProxy) {
        mHashKey.SetCharAt('T', 0);
    } else if (mUsingHttpProxy) {
        mHashKey.SetCharAt('P', 0);
    }
    if (mEndToEndSSL) {
        mHashKey.SetCharAt('S', 1);
    }

    // NOTE: for transparent proxies (e.g., SOCKS) we need to encode the proxy
    // info in the hash key (this ensures that we will continue to speak the
    // right protocol even if our proxy preferences change).
    //
    // NOTE: for SSL tunnels add the proxy information to the cache key.
    // We cannot use the proxy as the host parameter (as we do for non SSL)
    // because this is a single host tunnel, but we need to include the proxy
    // information so that a change in proxy config will mean this connection
    // is not reused

    // NOTE: Adding the username and the password provides a means to isolate
    // keep-alive to the URL bar domain as well: If the username is the URL bar
    // domain, keep-alive connections are not reused by resources bound to
    // different URL bar domains as the respective hash keys are not matching.

    if ((!mUsingHttpProxy && ProxyHost()) ||
        (mUsingHttpProxy && mUsingConnect)) {
        mHashKey.AppendLiteral(" (");
        mHashKey.Append(ProxyType());
        mHashKey.Append(':');
        mHashKey.Append(ProxyHost());
        mHashKey.Append(':');
        mHashKey.AppendInt(ProxyPort());
        mHashKey.Append(')');
        mHashKey.Append('[');
        mHashKey.Append(ProxyUsername());
        mHashKey.Append(':');
        const char* password = ProxyPassword();
        if (strlen(password) > 0) {
            nsAutoCString digestedPassword;
            nsresult rv = SHA256(password, digestedPassword);
            if (rv == NS_OK) {
                mHashKey.Append(digestedPassword);
            }
        }
        mHashKey.Append(']');
    }

    if(!mRoutedHost.IsEmpty()) {
        mHashKey.AppendLiteral(" <ROUTE-via ");
        mHashKey.Append(mRoutedHost);
        mHashKey.Append(':');
        mHashKey.AppendInt(mRoutedPort);
        mHashKey.Append('>');
    }

    if (!mNPNToken.IsEmpty()) {
        mHashKey.AppendLiteral(" {NPN-TOKEN ");
        mHashKey.Append(mNPNToken);
        mHashKey.AppendLiteral("}");
    }

    nsAutoCString originAttributes;
    mOriginAttributes.CreateSuffix(originAttributes);
    mHashKey.Append(originAttributes);
}
Exemple #3
0
getdns_return_t
_getdns_verify_pinset_match(const sha256_pin_t *pinset,
			    X509_STORE_CTX *store)
{
	getdns_return_t ret = GETDNS_RETURN_GENERIC_ERROR;
	X509 *x;
	int i, len;
	unsigned char raw[4096];
	unsigned char *next = raw;
	unsigned char buf[sizeof(pinset->pin)];
	const sha256_pin_t *p;

	if (pinset == NULL || store == NULL)
		return GETDNS_RETURN_GENERIC_ERROR;
	
	/* start at the base of the chain (the end-entity cert) and
	 * make sure that some valid element of the chain does match
	 * the pinset. */

	/* Testing with OpenSSL 1.0.1e-1 on debian indicates that
	 * store->untrusted holds the chain offered by the server in
	 * the order that the server offers it.  If the server offers
	 * bogus certificates (that is, matching and valid certs that
	 * belong to private keys that the server does not control),
	 * the the verification will succeed (including this pinset
	 * check), but the handshake will fail outside of this
	 * verification. */

	/* TODO: how do we handle raw public keys? */

	for (i = 0; i < sk_X509_num(store->untrusted); i++) {
		if (i > 0) {
		/* TODO: how do we ensure that the certificates in
		 * each stage appropriately sign the previous one?
		 * for now, to be safe, we only examine the end-entity
		 * cert: */
			return GETDNS_RETURN_GENERIC_ERROR;
		}

		x = sk_X509_value(store->untrusted, i);
		if (x->cert_info == NULL)
			continue;
#if defined(STUB_DEBUG) && STUB_DEBUG
		DEBUG_STUB("--- %s: name of cert %d:\n", __FUNCTION__, i);
		if (x->cert_info->subject != NULL)
			X509_NAME_print_ex_fp(stderr, x->cert_info->subject, 4, XN_FLAG_ONELINE);
		fprintf(stderr, "\n");
#endif
		if (x->cert_info->key == NULL)
			continue;

		/* digest the cert with sha256 */
		len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL);
		if (len > sizeof(raw)) {
			DEBUG_STUB("--- %s: pubkey %d is larger than %ld octets\n",
				   __FUNCTION__, i, sizeof(raw));
			continue;
		}
		i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next);
		if (next - raw != len) {
			DEBUG_STUB("--- %s: pubkey %d claimed it needed %d octets, really needed %ld\n",
				   __FUNCTION__, i, len, next - raw);
			continue;
		}
		SHA256(raw, len, buf);

		/* compare it */
		for (p = pinset; p; p = p->next)
			if (0 == memcmp(buf, p->pin, sizeof(p->pin))) {
				DEBUG_STUB("--- %s: pubkey %d matched pin %p (%ld)!\n",
					   __FUNCTION__, i, p, sizeof(p->pin));
				return GETDNS_RETURN_GOOD;
			} else
				DEBUG_STUB("--- %s: pubkey %d did not match pin %p!\n",
					   __FUNCTION__, i, p);
	}

	return ret;
}
HashValue160 Hash160(const ConstBuf& mb) {
	return HashValue160(RIPEMD160().ComputeHash(SHA256().ComputeHash(mb)));
}
int StealthSecretSpend(ec_secret& scanSecret, ec_point& ephemPubkey, ec_secret& spendSecret, ec_secret& secretOut)
{
    /*

    c  = H(dP)
    R' = R + cG     [without decrypting wallet]
       = (f + c)G   [after decryption of wallet]
         Remember: mod curve.order, pad with 0x00s where necessary?
    */

    int rv = 0;
    std::vector<uint8_t> vchOutP;

    BN_CTX* bnCtx           = NULL;
    BIGNUM* bnScanSecret    = NULL;
    BIGNUM* bnP             = NULL;
    EC_POINT* P             = NULL;
    BIGNUM* bnOutP          = NULL;
    BIGNUM* bnc             = NULL;
    BIGNUM* bnOrder         = NULL;
    BIGNUM* bnSpend         = NULL;

    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);

    if (!ecgrp)
    {
        printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };

    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecretSpend(): BN_CTX_new failed.\n");
        rv = 1;
        goto End;
    };

    if (!(bnScanSecret = BN_bin2bn(&scanSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnScanSecret BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };

    if (!(bnP = BN_bin2bn(&ephemPubkey[0], ephemPubkey.size(), BN_new())))
    {
        printf("StealthSecretSpend(): bnP BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };

    if (!(P = EC_POINT_bn2point(ecgrp, bnP, NULL, bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };

    // -- dP
    if (!EC_POINT_mul(ecgrp, P, NULL, P, bnScanSecret, bnCtx))
    {
        printf("StealthSecretSpend(): dP EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnOutP = EC_POINT_point2bn(ecgrp, P, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };


    vchOutP.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutP) != (int) ec_compressed_size
            || BN_bn2bin(bnOutP, &vchOutP[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecretSpend(): bnOutP incorrect length.\n");
        rv = 1;
        goto End;
    };

    uint8_t hash1[32];
    SHA256(&vchOutP[0], vchOutP.size(), (uint8_t*)hash1);


    if (!(bnc = BN_bin2bn(&hash1[0], 32, BN_new())))
    {
        printf("StealthSecretSpend(): BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnOrder = BN_new())
            || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): EC_GROUP_get_order failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };

    //if (!BN_add(r, a, b)) return 0;
    //return BN_nnmod(r, r, m, ctx);
    if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n");
        rv = 1;
        goto End;
    };

    if (BN_is_zero(bnSpend)) // possible?
    {
        printf("StealthSecretSpend(): bnSpend is zero.\n");
        rv = 1;
        goto End;
    };

    if (BN_num_bytes(bnSpend) != (int) ec_secret_size
            || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size)
    {
        printf("StealthSecretSpend(): bnSpend incorrect length.\n");
        rv = 1;
        goto End;
    };

End:
    if (bnSpend)        BN_free(bnSpend);
    if (bnOrder)        BN_free(bnOrder);
    if (bnc)            BN_free(bnc);
    if (bnOutP)         BN_free(bnOutP);
    if (P)              EC_POINT_free(P);
    if (bnP)            BN_free(bnP);
    if (bnScanSecret)   BN_free(bnScanSecret);
    if (bnCtx)          BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);

    return rv;
};
int StealthSecret(ec_secret& secret, ec_point& pubkey, const ec_point& pkSpend, ec_secret& sharedSOut, ec_point& pkOut)
{
    /*

    send:
        secret = ephem_secret, pubkey = scan_pubkey

    receive:
        secret = scan_secret, pubkey = ephem_pubkey
        c = H(dP)

    Q = public scan key (EC point, 33 bytes)
    d = private scan key (integer, 32 bytes)
    R = public spend key
    f = private spend key

    Q = dG
    R = fG

    Sender (has Q and R, not d or f):

    P = eG

    c = H(eQ) = H(dP)
    R' = R + cG


    Recipient gets R' and P

    test 0 and infinity?
    */

    int rv = 0;
    std::vector<uint8_t> vchOutQ;

    BN_CTX* bnCtx   = NULL;
    BIGNUM* bnEphem = NULL;
    BIGNUM* bnQ     = NULL;
    EC_POINT* Q     = NULL;
    BIGNUM* bnOutQ  = NULL;
    BIGNUM* bnc     = NULL;
    EC_POINT* C     = NULL;
    BIGNUM* bnR     = NULL;
    EC_POINT* R     = NULL;
    EC_POINT* Rout  = NULL;
    BIGNUM* bnOutR  = NULL;

    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);

    if (!ecgrp)
    {
        printf("StealthSecret(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };

    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecret(): BN_CTX_new failed.\n");
        rv = 1;
        goto End;
    };

    if (!(bnEphem = BN_bin2bn(&secret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecret(): bnEphem BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };

    if (!(bnQ = BN_bin2bn(&pubkey[0], pubkey.size(), BN_new())))
    {
        printf("StealthSecret(): bnQ BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };

    if (!(Q = EC_POINT_bn2point(ecgrp, bnQ, NULL, bnCtx)))
    {
        printf("StealthSecret(): Q EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };

    // -- eQ
    // EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
    // EC_POINT_mul calculates the value generator * n + q * m and stores the result in r. The value n may be NULL in which case the result is just q * m.
    if (!EC_POINT_mul(ecgrp, Q, NULL, Q, bnEphem, bnCtx))
    {
        printf("StealthSecret(): eQ EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnOutQ = EC_POINT_point2bn(ecgrp, Q, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecret(): Q EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };


    vchOutQ.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutQ) != (int) ec_compressed_size
            || BN_bn2bin(bnOutQ, &vchOutQ[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecret(): bnOutQ incorrect length.\n");
        rv = 1;
        goto End;
    };

    SHA256(&vchOutQ[0], vchOutQ.size(), &sharedSOut.e[0]);

    if (!(bnc = BN_bin2bn(&sharedSOut.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecret(): BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };

    // -- cG
    if (!(C = EC_POINT_new(ecgrp)))
    {
        printf("StealthSecret(): C EC_POINT_new failed\n");
        rv = 1;
        goto End;
    };

    if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx))
    {
        printf("StealthSecret(): C EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnR = BN_bin2bn(&pkSpend[0], pkSpend.size(), BN_new())))
    {
        printf("StealthSecret(): bnR BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };


    if (!(R = EC_POINT_bn2point(ecgrp, bnR, NULL, bnCtx)))
    {
        printf("StealthSecret(): R EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };

    if (!EC_POINT_mul(ecgrp, C, bnc, NULL, NULL, bnCtx))
    {
        printf("StealthSecret(): C EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };

    if (!(Rout = EC_POINT_new(ecgrp)))
    {
        printf("StealthSecret(): Rout EC_POINT_new failed\n");
        rv = 1;
        goto End;
    };

    if (!EC_POINT_add(ecgrp, Rout, R, C, bnCtx))
    {
        printf("StealthSecret(): Rout EC_POINT_add failed\n");
        rv = 1;
        goto End;
    };

    if (!(bnOutR = EC_POINT_point2bn(ecgrp, Rout, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecret(): Rout EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };


    pkOut.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutR) != (int) ec_compressed_size
            || BN_bn2bin(bnOutR, &pkOut[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecret(): pkOut incorrect length.\n");
        rv = 1;
        goto End;
    };

End:
    if (bnOutR)     BN_free(bnOutR);
    if (Rout)       EC_POINT_free(Rout);
    if (R)          EC_POINT_free(R);
    if (bnR)        BN_free(bnR);
    if (C)          EC_POINT_free(C);
    if (bnc)        BN_free(bnc);
    if (bnOutQ)     BN_free(bnOutQ);
    if (Q)          EC_POINT_free(Q);
    if (bnQ)        BN_free(bnQ);
    if (bnEphem)    BN_free(bnEphem);
    if (bnCtx)      BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);

    return rv;
};
Exemple #7
0
static int handle_bb_login(login_client_t *c, bb_login_93_pkt *pkt) {
    char query[256];
    int len;
    char tmp[32];
    void *result;
    char **row;
    uint8_t hash[32];

    /* Make sure the username string is sane... */
    len = strlen(pkt->username);
    if(len > 16 || strlen(pkt->password) > 16) {
        send_bb_security(c, 0, LOGIN_93BB_FORCED_DISCONNECT, 0, NULL, 0);
        return -1;
    }

    sylverant_db_escape_str(&conn, tmp, pkt->username, len);
    sprintf(query, "SELECT account_data.account_id, isbanned, teamid, "
            "privlevel, guildcard, blueburst_clients.password, dressflag FROM "
            "account_data INNER JOIN blueburst_clients ON "
            "account_data.account_id = blueburst_clients.account_id WHERE "
            "blueburst_clients.username='******'", tmp);

    /* Query the database for the user... */
    if(sylverant_db_query(&conn, query)) {
        send_bb_security(c, 0, LOGIN_93BB_UNKNOWN_ERROR, 0, NULL, 0);
        return -2;
    }

    result = sylverant_db_result_store(&conn);
    if(!result) {
        send_bb_security(c, 0, LOGIN_93BB_UNKNOWN_ERROR, 0, NULL, 0);
        return -2;
    }

    row = sylverant_db_result_fetch(result);
    if(!row) {
        send_bb_security(c, 0, LOGIN_93BB_NO_USER_RECORD, 0, NULL, 0);
        sylverant_db_result_free(result);
        return -3;
    }

    /* Make sure some simple checks pass first... */
    if(atoi(row[1])) {
        /* User is banned by account. */
        send_bb_security(c, 0, LOGIN_93BB_BANNED, 0, NULL, 0);
        sylverant_db_result_free(result);
        return -4;
    }

    /* If we've gotten this far, we have an account! Check the password. */
    sprintf(tmp, "%s_salt_%s", pkt->password, row[4]);
    SHA256((unsigned char *)tmp, strlen(tmp), hash);

    if(memcmp(hash, row[5], 32)) {
        /* Password check failed... */
        send_bb_security(c, 0, LOGIN_93BB_BAD_USER_PWD, 0, NULL, 0);
        sylverant_db_result_free(result);
        return -6;
    }

    /* Grab the rest of what we care about from the query... */
    errno = 0;
    c->team_id = (uint32_t)strtoul(row[2], NULL, 0);
    c->is_gm = (uint32_t)strtoul(row[3], NULL, 0);
    c->guildcard = (uint32_t)strtoul(row[4], NULL, 0);
    c->account_id = (uint32_t)strtoul(row[0], NULL, 0);
    c->flags = (uint32_t)strtoul(row[6], NULL, 0);
    sylverant_db_result_free(result);

    if(errno) {
        send_bb_security(c, 0, LOGIN_93BB_UNKNOWN_ERROR, 0, NULL, 0);
        return -2;
    }

    /* Copy in the security data */
    memcpy(&c->sec_data, pkt->security_data, sizeof(bb_security_data_t));

    if(c->sec_data.magic != LE32(0xDEADBEEF)) {
        send_bb_security(c, 0, LOGIN_93BB_FORCED_DISCONNECT, 0, NULL, 0);
        return -8;
    }

    /* Send the security data packet */
    if(send_bb_security(c, c->guildcard, LOGIN_93BB_OK, c->team_id,
                        &c->sec_data, sizeof(bb_security_data_t))) {
        return -7;
    }

    /* Has the user picked a character already? */
    if(c->sec_data.sel_char) {
        if(send_timestamp(c)) {
            return -9;
        }

        if(send_ship_list(c, 0)) {
            return -10;
        }

        if(send_scroll_msg(c, "Welcome to Sylverant!")) {
            return -11;
        }
    }

    return 0;
}
Exemple #8
0
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
    CAutoBN_CTX pctx;
    CScript::const_iterator pc = script.begin();
    CScript::const_iterator pend = script.end();
    CScript::const_iterator pbegincodehash = script.begin();
    vector<bool> vfExec;
    vector<valtype> altstack;
    if (script.size() > 10000)
        return false;
    int nOpCount = 0;


    try
    {
        while (pc < pend)
        {
            bool fExec = !count(vfExec.begin(), vfExec.end(), false);

            //
            // Read instruction
            //
            opcodetype opcode;
            valtype vchPushValue;
            if (!script.GetOp(pc, opcode, vchPushValue))
                return false;
            if (vchPushValue.size() > 5000)
                return false;
            if (opcode > OP_16 && nOpCount++ > 200)
                return false;

            if (fExec && opcode <= OP_PUSHDATA4)
                stack.push_back(vchPushValue);
            else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
            switch (opcode)
            {
                //
                // Push value
                //
                case OP_1NEGATE:
                case OP_1:
                case OP_2:
                case OP_3:
                case OP_4:
                case OP_5:
                case OP_6:
                case OP_7:
                case OP_8:
                case OP_9:
                case OP_10:
                case OP_11:
                case OP_12:
                case OP_13:
                case OP_14:
                case OP_15:
                case OP_16:
                {
                    // ( -- value)
                    CBigNum bn((int)opcode - (int)(OP_1 - 1));
                    stack.push_back(bn.getvch());
                }
                break;


                //
                // Control
                //
                case OP_NOP:
                case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
                case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
                break;

                case OP_VER:
                case OP_VERIF:
                case OP_VERNOTIF:
                {
                    return false;
                }
                break;

                case OP_IF:
                case OP_NOTIF:
                {
                    // <expression> if [statements] [else [statements]] endif
                    bool fValue = false;
                    if (fExec)
                    {
                        if (stack.size() < 1)
                            return false;
                        valtype& vch = stacktop(-1);
                        fValue = CastToBool(vch);
                        if (opcode == OP_NOTIF)
                            fValue = !fValue;
                        stack.pop_back();
                    }
                    vfExec.push_back(fValue);
                }
                break;

                case OP_ELSE:
                {
                    if (vfExec.empty())
                        return false;
                    vfExec.back() = !vfExec.back();
                }
                break;

                case OP_ENDIF:
                {
                    if (vfExec.empty())
                        return false;
                    vfExec.pop_back();
                }
                break;

                case OP_VERIFY:
                {
                    // (true -- ) or
                    // (false -- false) and return
                    if (stack.size() < 1)
                        return false;
                    bool fValue = CastToBool(stacktop(-1));
                    if (fValue)
                        stack.pop_back();
                    else
                        return false;
                }
                break;

                case OP_RETURN:
                {
                    return false;
                }
                break;


                //
                // Stack ops
                //
                case OP_TOALTSTACK:
                {
                    if (stack.size() < 1)
                        return false;
                    altstack.push_back(stacktop(-1));
                    stack.pop_back();
                }
                break;

                case OP_FROMALTSTACK:
                {
                    if (altstack.size() < 1)
                        return false;
                    stack.push_back(altstacktop(-1));
                    altstack.pop_back();
                }
                break;

                case OP_2DROP:
                {
                    // (x1 x2 -- )
                    stack.pop_back();
                    stack.pop_back();
                }
                break;

                case OP_2DUP:
                {
                    // (x1 x2 -- x1 x2 x1 x2)
                    if (stack.size() < 2)
                        return false;
                    valtype vch1 = stacktop(-2);
                    valtype vch2 = stacktop(-1);
                    stack.push_back(vch1);
                    stack.push_back(vch2);
                }
                break;

                case OP_3DUP:
                {
                    // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
                    if (stack.size() < 3)
                        return false;
                    valtype vch1 = stacktop(-3);
                    valtype vch2 = stacktop(-2);
                    valtype vch3 = stacktop(-1);
                    stack.push_back(vch1);
                    stack.push_back(vch2);
                    stack.push_back(vch3);
                }
                break;

                case OP_2OVER:
                {
                    // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
                    if (stack.size() < 4)
                        return false;
                    valtype vch1 = stacktop(-4);
                    valtype vch2 = stacktop(-3);
                    stack.push_back(vch1);
                    stack.push_back(vch2);
                }
                break;

                case OP_2ROT:
                {
                    // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
                    if (stack.size() < 6)
                        return false;
                    valtype vch1 = stacktop(-6);
                    valtype vch2 = stacktop(-5);
                    stack.erase(stack.end()-6, stack.end()-4);
                    stack.push_back(vch1);
                    stack.push_back(vch2);
                }
                break;

                case OP_2SWAP:
                {
                    // (x1 x2 x3 x4 -- x3 x4 x1 x2)
                    if (stack.size() < 4)
                        return false;
                    swap(stacktop(-4), stacktop(-2));
                    swap(stacktop(-3), stacktop(-1));
                }
                break;

                case OP_IFDUP:
                {
                    // (x - 0 | x x)
                    if (stack.size() < 1)
                        return false;
                    valtype vch = stacktop(-1);
                    if (CastToBool(vch))
                        stack.push_back(vch);
                }
                break;

                case OP_DEPTH:
                {
                    // -- stacksize
                    CBigNum bn(stack.size());
                    stack.push_back(bn.getvch());
                }
                break;

                case OP_DROP:
                {
                    // (x -- )
                    if (stack.size() < 1)
                        return false;
                    stack.pop_back();
                }
                break;

                case OP_DUP:
                {
                    // (x -- x x)
                    if (stack.size() < 1)
                        return false;
                    valtype vch = stacktop(-1);
                    stack.push_back(vch);
                }
                break;

                case OP_NIP:
                {
                    // (x1 x2 -- x2)
                    if (stack.size() < 2)
                        return false;
                    stack.erase(stack.end() - 2);
                }
                break;

                case OP_OVER:
                {
                    // (x1 x2 -- x1 x2 x1)
                    if (stack.size() < 2)
                        return false;
                    valtype vch = stacktop(-2);
                    stack.push_back(vch);
                }
                break;

                case OP_PICK:
                case OP_ROLL:
                {
                    // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
                    // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
                    if (stack.size() < 2)
                        return false;
                    int n = CBigNum(stacktop(-1)).getint();
                    stack.pop_back();
                    if (n < 0 || n >= stack.size())
                        return false;
                    valtype vch = stacktop(-n-1);
                    if (opcode == OP_ROLL)
                        stack.erase(stack.end()-n-1);
                    stack.push_back(vch);
                }
                break;

                case OP_ROT:
                {
                    // (x1 x2 x3 -- x2 x3 x1)
                    //  x2 x1 x3  after first swap
                    //  x2 x3 x1  after second swap
                    if (stack.size() < 3)
                        return false;
                    swap(stacktop(-3), stacktop(-2));
                    swap(stacktop(-2), stacktop(-1));
                }
                break;

                case OP_SWAP:
                {
                    // (x1 x2 -- x2 x1)
                    if (stack.size() < 2)
                        return false;
                    swap(stacktop(-2), stacktop(-1));
                }
                break;

                case OP_TUCK:
                {
                    // (x1 x2 -- x2 x1 x2)
                    if (stack.size() < 2)
                        return false;
                    valtype vch = stacktop(-1);
                    stack.insert(stack.end()-2, vch);
                }
                break;


                //
                // Splice ops
                //
                case OP_CAT:
                {
                    // (x1 x2 -- out)
                    if (stack.size() < 2)
                        return false;
                    valtype& vch1 = stacktop(-2);
                    valtype& vch2 = stacktop(-1);
                    vch1.insert(vch1.end(), vch2.begin(), vch2.end());
                    stack.pop_back();
                    if (stacktop(-1).size() > 5000)
                        return false;
                }
                break;

                case OP_SUBSTR:
                {
                    // (in begin size -- out)
                    if (stack.size() < 3)
                        return false;
                    valtype& vch = stacktop(-3);
                    int nBegin = CBigNum(stacktop(-2)).getint();
                    int nEnd = nBegin + CBigNum(stacktop(-1)).getint();
                    if (nBegin < 0 || nEnd < nBegin)
                        return false;
                    if (nBegin > vch.size())
                        nBegin = vch.size();
                    if (nEnd > vch.size())
                        nEnd = vch.size();
                    vch.erase(vch.begin() + nEnd, vch.end());
                    vch.erase(vch.begin(), vch.begin() + nBegin);
                    stack.pop_back();
                    stack.pop_back();
                }
                break;

                case OP_LEFT:
                case OP_RIGHT:
                {
                    // (in size -- out)
                    if (stack.size() < 2)
                        return false;
                    valtype& vch = stacktop(-2);
                    int nSize = CBigNum(stacktop(-1)).getint();
                    if (nSize < 0)
                        return false;
                    if (nSize > vch.size())
                        nSize = vch.size();
                    if (opcode == OP_LEFT)
                        vch.erase(vch.begin() + nSize, vch.end());
                    else
                        vch.erase(vch.begin(), vch.end() - nSize);
                    stack.pop_back();
                }
                break;

                case OP_SIZE:
                {
                    // (in -- in size)
                    if (stack.size() < 1)
                        return false;
                    CBigNum bn(stacktop(-1).size());
                    stack.push_back(bn.getvch());
                }
                break;


                //
                // Bitwise logic
                //
                case OP_INVERT:
                {
                    // (in - out)
                    if (stack.size() < 1)
                        return false;
                    valtype& vch = stacktop(-1);
                    for (int i = 0; i < vch.size(); i++)
                        vch[i] = ~vch[i];
                }
                break;

                case OP_AND:
                case OP_OR:
                case OP_XOR:
                {
                    // (x1 x2 - out)
                    if (stack.size() < 2)
                        return false;
                    valtype& vch1 = stacktop(-2);
                    valtype& vch2 = stacktop(-1);
                    MakeSameSize(vch1, vch2);
                    if (opcode == OP_AND)
                    {
                        for (int i = 0; i < vch1.size(); i++)
                            vch1[i] &= vch2[i];
                    }
                    else if (opcode == OP_OR)
                    {
                        for (int i = 0; i < vch1.size(); i++)
                            vch1[i] |= vch2[i];
                    }
                    else if (opcode == OP_XOR)
                    {
                        for (int i = 0; i < vch1.size(); i++)
                            vch1[i] ^= vch2[i];
                    }
                    stack.pop_back();
                }
                break;

                case OP_EQUAL:
                case OP_EQUALVERIFY:
                //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
                {
                    // (x1 x2 - bool)
                    if (stack.size() < 2)
                        return false;
                    valtype& vch1 = stacktop(-2);
                    valtype& vch2 = stacktop(-1);
                    bool fEqual = (vch1 == vch2);
                    // OP_NOTEQUAL is disabled because it would be too easy to say
                    // something like n != 1 and have some wiseguy pass in 1 with extra
                    // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
                    //if (opcode == OP_NOTEQUAL)
                    //    fEqual = !fEqual;
                    stack.pop_back();
                    stack.pop_back();
                    stack.push_back(fEqual ? vchTrue : vchFalse);
                    if (opcode == OP_EQUALVERIFY)
                    {
                        if (fEqual)
                            stack.pop_back();
                        else
                            return false;
                    }
                }
                break;


                //
                // Numeric
                //
                case OP_1ADD:
                case OP_1SUB:
                case OP_2MUL:
                case OP_2DIV:
                case OP_NEGATE:
                case OP_ABS:
                case OP_NOT:
                case OP_0NOTEQUAL:
                {
                    // (in -- out)
                    if (stack.size() < 1)
                        return false;
                    if (stacktop(-1).size() > nMaxNumSize)
                        return false;
                    CBigNum bn(stacktop(-1));
                    switch (opcode)
                    {
                    case OP_1ADD:       bn += bnOne; break;
                    case OP_1SUB:       bn -= bnOne; break;
                    case OP_2MUL:       bn <<= 1; break;
                    case OP_2DIV:       bn >>= 1; break;
                    case OP_NEGATE:     bn = -bn; break;
                    case OP_ABS:        if (bn < bnZero) bn = -bn; break;
                    case OP_NOT:        bn = (bn == bnZero); break;
                    case OP_0NOTEQUAL:  bn = (bn != bnZero); break;
                    }
                    stack.pop_back();
                    stack.push_back(bn.getvch());
                }
                break;

                case OP_ADD:
                case OP_SUB:
                case OP_MUL:
                case OP_DIV:
                case OP_MOD:
                case OP_LSHIFT:
                case OP_RSHIFT:
                case OP_BOOLAND:
                case OP_BOOLOR:
                case OP_NUMEQUAL:
                case OP_NUMEQUALVERIFY:
                case OP_NUMNOTEQUAL:
                case OP_LESSTHAN:
                case OP_GREATERTHAN:
                case OP_LESSTHANOREQUAL:
                case OP_GREATERTHANOREQUAL:
                case OP_MIN:
                case OP_MAX:
                {
                    // (x1 x2 -- out)
                    if (stack.size() < 2)
                        return false;
                    if (stacktop(-2).size() > nMaxNumSize ||
                        stacktop(-1).size() > nMaxNumSize)
                        return false;
                    CBigNum bn1(stacktop(-2));
                    CBigNum bn2(stacktop(-1));
                    CBigNum bn;
                    switch (opcode)
                    {
                    case OP_ADD:
                        bn = bn1 + bn2;
                        break;

                    case OP_SUB:
                        bn = bn1 - bn2;
                        break;

                    case OP_MUL:
                        if (!BN_mul(&bn, &bn1, &bn2, pctx))
                            return false;
                        break;

                    case OP_DIV:
                        if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))
                            return false;
                        break;

                    case OP_MOD:
                        if (!BN_mod(&bn, &bn1, &bn2, pctx))
                            return false;
                        break;

                    case OP_LSHIFT:
                        if (bn2 < bnZero || bn2 > CBigNum(2048))
                            return false;
                        bn = bn1 << bn2.getulong();
                        break;

                    case OP_RSHIFT:
                        if (bn2 < bnZero || bn2 > CBigNum(2048))
                            return false;
                        bn = bn1 >> bn2.getulong();
                        break;

                    case OP_BOOLAND:             bn = (bn1 != bnZero && bn2 != bnZero); break;
                    case OP_BOOLOR:              bn = (bn1 != bnZero || bn2 != bnZero); break;
                    case OP_NUMEQUAL:            bn = (bn1 == bn2); break;
                    case OP_NUMEQUALVERIFY:      bn = (bn1 == bn2); break;
                    case OP_NUMNOTEQUAL:         bn = (bn1 != bn2); break;
                    case OP_LESSTHAN:            bn = (bn1 < bn2); break;
                    case OP_GREATERTHAN:         bn = (bn1 > bn2); break;
                    case OP_LESSTHANOREQUAL:     bn = (bn1 <= bn2); break;
                    case OP_GREATERTHANOREQUAL:  bn = (bn1 >= bn2); break;
                    case OP_MIN:                 bn = (bn1 < bn2 ? bn1 : bn2); break;
                    case OP_MAX:                 bn = (bn1 > bn2 ? bn1 : bn2); break;
                    }
                    stack.pop_back();
                    stack.pop_back();
                    stack.push_back(bn.getvch());

                    if (opcode == OP_NUMEQUALVERIFY)
                    {
                        if (CastToBool(stacktop(-1)))
                            stack.pop_back();
                        else
                            return false;
                    }
                }
                break;

                case OP_WITHIN:
                {
                    // (x min max -- out)
                    if (stack.size() < 3)
                        return false;
                    if (stacktop(-3).size() > nMaxNumSize ||
                        stacktop(-2).size() > nMaxNumSize ||
                        stacktop(-1).size() > nMaxNumSize)
                        return false;
                    CBigNum bn1(stacktop(-3));
                    CBigNum bn2(stacktop(-2));
                    CBigNum bn3(stacktop(-1));
                    bool fValue = (bn2 <= bn1 && bn1 < bn3);
                    stack.pop_back();
                    stack.pop_back();
                    stack.pop_back();
                    stack.push_back(fValue ? vchTrue : vchFalse);
                }
                break;


                //
                // Crypto
                //
                case OP_RIPEMD160:
                case OP_SHA1:
                case OP_SHA256:
                case OP_HASH160:
                case OP_HASH256:
                {
                    // (in -- hash)
                    if (stack.size() < 1)
                        return false;
                    valtype& vch = stacktop(-1);
                    valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
                    if (opcode == OP_RIPEMD160)
                        RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
                    else if (opcode == OP_SHA1)
                        SHA1(&vch[0], vch.size(), &vchHash[0]);
                    else if (opcode == OP_SHA256)
                        SHA256(&vch[0], vch.size(), &vchHash[0]);
                    else if (opcode == OP_HASH160)
                    {
                        uint160 hash160 = Hash160(vch);
                        memcpy(&vchHash[0], &hash160, sizeof(hash160));
                    }
                    else if (opcode == OP_HASH256)
                    {
                        uint256 hash = Hash(vch.begin(), vch.end());
                        memcpy(&vchHash[0], &hash, sizeof(hash));
                    }
                    stack.pop_back();
                    stack.push_back(vchHash);
                }
                break;

                case OP_CODESEPARATOR:
                {
                    // Hash starts after the code separator
                    pbegincodehash = pc;
                }
                break;

                case OP_CHECKSIG:
                case OP_CHECKSIGVERIFY:
                {
                    // (sig pubkey -- bool)
                    if (stack.size() < 2)
                        return false;

                    valtype& vchSig    = stacktop(-2);
                    valtype& vchPubKey = stacktop(-1);

                    ////// debug print
                    //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n");
                    //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n");

                    // Subset of script starting at the most recent codeseparator
                    CScript scriptCode(pbegincodehash, pend);

                    // Drop the signature, since there's no way for a signature to sign itself
                    scriptCode.FindAndDelete(CScript(vchSig));

                    bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);

                    stack.pop_back();
                    stack.pop_back();
                    stack.push_back(fSuccess ? vchTrue : vchFalse);
                    if (opcode == OP_CHECKSIGVERIFY)
                    {
                        if (fSuccess)
                            stack.pop_back();
                        else
                            return false;
                    }
                }
                break;

                case OP_CHECKMULTISIG:
                case OP_CHECKMULTISIGVERIFY:
                {
                    // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)

                    int i = 1;
                    if (stack.size() < i)
                        return false;

                    int nKeysCount = CBigNum(stacktop(-i)).getint();
                    if (nKeysCount < 0)
                        return false;
                    int ikey = ++i;
                    i += nKeysCount;
                    if (stack.size() < i)
                        return false;

                    int nSigsCount = CBigNum(stacktop(-i)).getint();
                    if (nSigsCount < 0 || nSigsCount > nKeysCount)
                        return false;
                    int isig = ++i;
                    i += nSigsCount;
                    if (stack.size() < i)
                        return false;

                    // Subset of script starting at the most recent codeseparator
                    CScript scriptCode(pbegincodehash, pend);

                    // Drop the signatures, since there's no way for a signature to sign itself
                    for (int k = 0; k < nSigsCount; k++)
                    {
                        valtype& vchSig = stacktop(-isig-k);
                        scriptCode.FindAndDelete(CScript(vchSig));
                    }

                    bool fSuccess = true;
                    while (fSuccess && nSigsCount > 0)
                    {
                        valtype& vchSig    = stacktop(-isig);
                        valtype& vchPubKey = stacktop(-ikey);

                        // Check signature
                        if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))
                        {
                            isig++;
                            nSigsCount--;
                        }
                        ikey++;
                        nKeysCount--;

                        // If there are more signatures left than keys left,
                        // then too many signatures have failed
                        if (nSigsCount > nKeysCount)
                            fSuccess = false;
                    }

                    while (i-- > 0)
                        stack.pop_back();
                    stack.push_back(fSuccess ? vchTrue : vchFalse);

                    if (opcode == OP_CHECKMULTISIGVERIFY)
                    {
                        if (fSuccess)
                            stack.pop_back();
                        else
                            return false;
                    }
                }
                break;

                default:
                    return false;
            }

            // Size limits
            if (stack.size() + altstack.size() > 1000)
                return false;
        }
    }
    catch (...)
    {
        return false;
    }


    if (!vfExec.empty())
        return false;

    return true;
}
void SHA256_gen_merkle_root ( char* merkle_root, struct stratum_ctx* sctx )
{
 SHA256( sctx->job.coinbase, (int)sctx->job.coinbase_size, merkle_root );
}