main(int argc, char *argv[]) { int sock,i; if (argc<2) { printf("\nDoS against Alibaba 2.0 WebServer by wildcoyote\n\n"); printf("Sintaxe: %s <host> [port - default 80]\n",argv[0]); printf("Send flamez to [email protected], *Enjoy*...\n\n"); } else if (argc==2) DoS(argv[1],80); else DoS(argv[1],atoi(argv[2])); }
// Test that a Sprout tx with negative version is still rejected // by CheckBlock under Sprout consensus rules. TEST(CheckBlock, BlockSproutRejectsBadVersion) { SelectParams(CBaseChainParams::MAIN); CMutableTransaction mtx; mtx.vin.resize(1); mtx.vin[0].prevout.SetNull(); mtx.vin[0].scriptSig = CScript() << 1 << OP_0; mtx.vout.resize(1); mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; mtx.vout[0].nValue = 0; mtx.vout.push_back(CTxOut( GetBlockSubsidy(1, Params().GetConsensus())/5, Params().GetFoundersRewardScriptAtHeight(1))); mtx.fOverwintered = false; mtx.nVersion = -1; mtx.nVersionGroupId = 0; CTransaction tx {mtx}; CBlock block; block.vtx.push_back(tx); MockCValidationState state; CBlockIndex indexPrev {Params().GenesisBlock()}; auto verifier = libzcash::ProofVerifier::Strict(); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1); EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); }
TEST(CheckBlock, VersionTooLow) { auto verifier = libzcash::ProofVerifier::Strict(); CBlock block; block.nVersion = 1; MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1); EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); }
TEST_F(ContextualCheckBlockTest, BadCoinbaseHeight) { // Put a transaction in a block with no height in scriptSig CMutableTransaction mtx = GetFirstBlockCoinbaseTx(); mtx.vin[0].scriptSig = CScript() << OP_0; mtx.vout.pop_back(); // remove the FR output CBlock block; block.vtx.push_back(mtx); // Treating block as genesis should pass MockCValidationState state; EXPECT_TRUE(ContextualCheckBlock(block, state, NULL)); // Give the transaction a Founder's Reward vout mtx.vout.push_back(CTxOut( GetBlockSubsidy(1, Params().GetConsensus())/5, Params().GetFoundersRewardScriptAtHeight(1))); // Treating block as non-genesis should fail CTransaction tx2 {mtx}; block.vtx[0] = tx2; CBlock prev; CBlockIndex indexPrev {prev}; indexPrev.nHeight = 0; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1); EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); // Setting to an incorrect height should fail mtx.vin[0].scriptSig = CScript() << 2 << OP_0; CTransaction tx3 {mtx}; block.vtx[0] = tx3; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-cb-height", false)).Times(1); EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); // After correcting the scriptSig, should pass mtx.vin[0].scriptSig = CScript() << 1 << OP_0; CTransaction tx4 {mtx}; block.vtx[0] = tx4; EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); }
// Expects a height-1 block containing a given transaction to fail // ContextualCheckBlock. This is used in rejecting (Sprout-Overwinter, // Overwinter-Sprout, ...) tests. You should not call it without // calling a SCOPED_TRACE macro first to usefully label any failures. void ExpectInvalidBlockFromTx(const CTransaction& tx, int level, std::string reason) { // Create a block and add the transaction to it. CBlock block; block.vtx.push_back(tx); // Set the previous block index to the genesis block. CBlockIndex indexPrev {Params().GenesisBlock()}; // We now expect this to be an invalid block, for the given reason. MockCValidationState state; EXPECT_CALL(state, DoS(level, false, REJECT_INVALID, reason, false)).Times(1); EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); }
// native sscanf(const data[], const format[], (Float,_}:...); static cell AMX_NATIVE_CALL n_sscanf(AMX * amx, cell * params) { if (g_iTrueMax == 0) { logprintf("sscanf error: System not initialised."); return SSCANF_FAIL_RETURN; } // Friendly note, the most complex set of specifier additions is: // // A<i>(10, 11)[5] // // In that exact order - type, default, size. It's very opposite to how // it's done in code, where you would do the eqivalent to: // // <i>[5] = {10, 11} // // But this method is vastly simpler to parse in this context! Technically // you can, due to legacy support for 'p', do: // // Ai(10, 11)[5] // // But you will get an sscanf warning, and I may remove that ability from // the start - that will mean a new function, but an easy to write one. // In fact the most complex will probably be something like: // // E<ifs[32]s[8]d>(10, 12.3, Hello there, Hi, 42) // // Get the number of parameters passed. We add one as the indexes are out // by one (OBOE - Out By One Error) due to params[0] being the parameter // count, not an actual parameter. const int paramCount = ((int)params[0] / 4) + 1; // Could add a check for only 3 parameters here - I can't think of a time // when you would not want any return values at all, but that doesn't mean // they don't exist - you could just want to check but not save the format. // Update - that is now a possibility with the '{...}' specifiers. if (paramCount < (2 + 1)) { logprintf("sscanf error: Missing required parameters."); return SSCANF_FAIL_RETURN; } //else if (paramCount == (2 + 1)) //{ // Only have an input and a specifier - better hope the whole specifier // is quite (i.e. enclosed in '{...}'). //} // Set up function wide values. // Get and check the main data. // Pointer to the current input data. char * string; STR_PARAM(amx, params[1], string); // Pointer to the current format specifier. char * format; STR_PARAM(amx, params[2], format); // Check for CallRemoteFunction style null strings and correct. if (string[0] == '\1' && string[1] == '\0') { string[0] = '\0'; } // Current parameter to save data to. int paramPos = 3; cell * cptr; InitialiseDelimiter(); // Skip leading space. SkipWhitespace(&string); bool doSave; // Code for the rare cases where the WHOLE format is quiet. if (*format == '{') { ++format; doSave = false; } else { doSave = true; } // Now do the main loop as long as there are variables to store the data in // and input string remaining to get the data from. while (*string && (paramPos < paramCount || !doSave)) { if (!*format) { // End of the format string - if we're here we've got all the // parameters but there is extra string or variables, which may // indicate their code needs fixing, for example: // sscanf(data, "ii", var0, var1, var3, var4); // There is only two format specifiers, but four returns. This may // also be reached if there is too much input data, but that is // considered OK as that is likely a user's fault. if (paramPos < paramCount) { logprintf("sscanf warning: Format specifier does not match parameter count."); } if (!doSave) { // Started a quiet section but never explicitly ended it. logprintf("sscanf warning: Unclosed quiet section."); } return SSCANF_TRUE_RETURN; } else if (IsWhitespace(*format)) { ++format; } else { switch (*format++) { case 'L': DX(bool, L) // FALLTHROUGH case 'l': DOV(bool, L) break; case 'B': DX(int, B) // FALLTHROUGH case 'b': DO(int, B) case 'N': DX(int, N) // FALLTHROUGH case 'n': DO(int, N) case 'C': DX(char, C) // FALLTHROUGH case 'c': DO(char, C) case 'I': case 'D': DX(int, I) // FALLTHROUGH case 'i': case 'd': DO(int, I) case 'H': case 'X': DX(int, H) // FALLTHROUGH case 'h': case 'x': DO(int, H) case 'O': DX(int, O) // FALLTHROUGH case 'o': DO(int, O) case 'F': DXF(double, F) // FALLTHROUGH case 'f': DOF(double, F) case 'G': DXF(double, G) // FALLTHROUGH case 'g': DOF(double, G) case '{': if (doSave) { doSave = false; } else { // Already in a quiet section. logprintf("sscanf warning: Can't have nestled quiet sections."); } continue; case '}': if (doSave) { logprintf("sscanf warning: Not in a quiet section."); } else { doSave = true; } continue; case 'P': logprintf("sscanf warning: You can't have an optional delimiter."); // FALLTHROUGH case 'p': // 'P' doesn't exist. // Theoretically, for compatibility, this should be: // p<delimiter>, but that will break backwards // compatibility with anyone doing "p<" to use '<' as a // delimiter (doesn't matter how rare that may be). Also, // writing deprecation code and both the new and old code // is more trouble than it's worth, and it's slow. // UPDATE: I wrote the "GetSingleType" code for 'a' and // figured out a way to support legacy and new code, while // still maintaining support for the legacy "p<" separator, // so here it is: ResetDelimiter(); AddDelimiter(GetSingleType(&format)); continue; case 'Z': logprintf("sscanf warning: 'Z' doesn't exist - that would be an optional, deprecated optional string!."); // FALLTHROUGH case 'z': logprintf("sscanf warning: 'z' is deprecated, consider using 'S' instead."); // FALLTHROUGH case 'S': if (IsDelimiter(*string)) { char * dest; int length; if (DoSD(&format, &dest, &length)) { // Send the string to PAWN. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); amx_SetString(cptr, dest, 0, 0, length); } } break; } // Implicit "else". SkipDefaultEx(&format); // FALLTHROUGH case 's': { // Get the length. int length = GetLength(&format, false); char * dest; DoS(&string, &dest, length, IsEnd(*format)); // Send the string to PAWN. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); amx_SetString(cptr, dest, 0, 0, length); } } break; case 'U': DX(int, U) // FALLTHROUGH case 'u': DOV(int, U) break; case 'Q': DX(int, Q) // FALLTHROUGH case 'q': DOV(int, Q) break; case 'R': DX(int, R) // FALLTHROUGH case 'r': DOV(int, R) break; case 'A': // We need the default values here. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoA(&format, &string, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoA(&format, &string, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case 'a': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoA(&format, &string, cptr, false)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoA(&format, &string, NULL, false)) { break; } } return SSCANF_FAIL_RETURN; case 'E': // We need the default values here. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoE(&format, &string, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoE(&format, &string, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case 'e': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoE(&format, &string, cptr, false)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoE(&format, &string, NULL, false)) { break; } } return SSCANF_FAIL_RETURN; case 'K': // We need the default values here. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoK(amx, &format, &string, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoK(amx, &format, &string, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case 'k': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoK(amx, &format, &string, cptr, false)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. if (DoK(amx, &format, &string, NULL, false)) { break; } } return SSCANF_FAIL_RETURN; case '\'': // Find the end of the literal. { char * str = format, * write = format; bool escape = false; while (!IsEnd(*str) && (escape || *str != '\'')) { if (*str == '\\') { if (escape) { // "\\" - Go back a step to write this // character over the last character (which // just happens to be the same character). --write; } escape = !escape; } else { if (*str == '\'') { // Overwrite the escape character with the // quote character. Must have been // preceeded by a slash or it wouldn't have // got to here in the loop. --write; } escape = false; } // Copy the string over itself to get rid of excess // escape characters. // Not sure if it's faster in the average case to // always do the copy or check if it's needed. // This write is always safe as it makes the string // shorter, so we'll never run out of space. It // will also not overwrite the original string. *write++ = *str++; } if (*str == '\'') { // Correct end. Make a shorter string to search // for. *write = '\0'; // Find the current section of format in string. char * find = strstr(string, format); if (!find) { // Didn't find the string return SSCANF_FAIL_RETURN; } // Found the string. Update the current string // position to the length of the search term // further along from the start of the term. Use // "write" here as we want the escaped string // length. string = find + (write - format); // Move to after the end of the search string. Use // "str" here as we want the unescaped string // length. format = str + 1; } else { logprintf("sscanf warning: Unclosed string literal."); char * find = strstr(string, format); if (!find) { return SSCANF_FAIL_RETURN; } string = find + (write - format); format = str; } } break; case '%': logprintf("sscanf warning: sscanf specifiers do not require '%' before them."); continue; default: logprintf("sscanf warning: Unknown format specifier '%c', skipping.", *(format - 1)); continue; } // Loop cleanup - only skip one spacer so that we can detect // multiple explicit delimiters in a row, for example: // // hi there // // is NOT multiple explicit delimiters in a row (they're // whitespace). This however is: // // hi , , , there // SkipOneSpacer(&string); } } // Temporary to the end of the code. ResetDelimiter(); AddDelimiter(')'); // We don't need code here to handle the case where paramPos was reached, // but the end of the string wasn't - if that's the case there's no // problem as we just ignore excess string data. while (paramPos < paramCount || !doSave) { // Loop through if there's still parameters remaining. if (!*format) { logprintf("sscanf warning: Format specifier does not match parameter count."); if (!doSave) { // Started a quiet section but never explicitly ended it. logprintf("sscanf warning: Unclosed quiet section."); } return SSCANF_TRUE_RETURN; } else if (IsWhitespace(*format)) { ++format; } else { // Do the main switch again. switch (*format++) { case 'L': DE(bool, L) case 'B': DE(int, B) case 'N': DE(int, N) case 'C': DE(char, C) case 'I': case 'D': DE(int, I) case 'H': case 'X': DE(int, H) case 'O': DE(int, O) case 'F': DEF(double, F) case 'G': DEF(double, G) case 'U': DE(int, U) case 'Q': DE(int, Q) case 'R': DE(int, R) case 'A': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoA(&format, NULL, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. // Also pass NULL data so it knows to only collect the // default values. if (DoA(&format, NULL, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case 'E': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoE(&format, NULL, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. // Also pass NULL data so it knows to only collect the // default values. if (DoE(&format, NULL, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case 'K': if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); if (DoK(amx, &format, NULL, cptr, true)) { break; } } else { // Pass a NULL pointer so data isn't saved anywhere. // Also pass NULL data so it knows to only collect the // default values. if (DoK(amx, &format, NULL, NULL, true)) { break; } } return SSCANF_FAIL_RETURN; case '{': if (doSave) { doSave = false; } else { // Already in a quiet section. logprintf("sscanf warning: Can't have nestled quiet sections."); } break; case '}': if (doSave) { logprintf("sscanf warning: Not in a quiet section."); } else { doSave = true; } break; case 'Z': logprintf("sscanf warning: 'Z' doesn't exist - that would be an optional, deprecated optional string!."); // FALLTHROUGH case 'z': logprintf("sscanf warning: 'z' is deprecated, consider using 'S' instead."); // FALLTHROUGH case 'S': { char * dest; int length; if (DoSD(&format, &dest, &length)) { // Send the string to PAWN. if (doSave) { amx_GetAddr(amx, params[paramPos++], &cptr); amx_SetString(cptr, dest, 0, 0, length); } } } break; case 'P': logprintf("sscanf warning: You can't have an optional delimiter."); // FALLTHROUGH case 'p': // Discard delimiter. This only matters when they have // real inputs, not the default ones used here. GetSingleType(&format); continue; case '\'': // Implicitly optional if the specifiers after it are // optional. { bool escape = false; while (!IsEnd(*format) && (escape || *format != '\'')) { if (*format == '\\') { escape = !escape; } else { escape = false; } ++format; } if (*format == '\'') { ++format; } else { logprintf("sscanf warning: Unclosed string literal."); } } break; // Large block of specifiers all together. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'k': case 'l': case 'n': case 'o': case 'q': case 'r': case 's': case 'u': case 'x': // These are non optional items, but the input string // didn't include them, so we fail - this is in fact the // most basic definition of a fail (the original)! We // don't need any text warnings here - admittedly we don't // know if the format specifier is well formed (there may // not be enough return variables for example), but it // doesn't matter - the coder should have tested for those // things, and the more important thing is that the user // didn't enter the correct data. return SSCANF_FAIL_RETURN; case '%': logprintf("sscanf warning: sscanf specifiers do not require '%' before them."); break; default: logprintf("sscanf warning: Unknown format specifier '%c', skipping.", *(format - 1)); break; } // Don't need any cleanup here. } } if (*format) { do { if (!IsWhitespace(*format)) { // Only print this warning if the remaining characters are not // spaces - spaces are allowed, and sometimes required, on the // ends of formats (e.g. to stop the final 's' specifier // collecting all remaining characters and only get one word). // We could check that the remaining specifier is a valid one, // but this is only a guide - they shouldn't even have other // characters IN the specifier so it doesn't matter - it will // point to a bug, which is the important thing. if (doSave) { if (*format == '}') { logprintf("sscanf warning: Not in a quiet section."); } else if (*format != '{') { // Fix the bad display bug. logprintf("sscanf warning: Format specifier does not match parameter count."); } // Only display it once. break; } else { if (*format == '}') { doSave = true; } else { logprintf("sscanf warning: Format specifier does not match parameter count."); break; } } } ++format; } while (*format); } if (!doSave) { // Started a quiet section but never explicitly ended it. logprintf("sscanf warning: Unclosed quiet section."); } // No more parameters and no more format specifiers which could be read // from - this is a valid return! return SSCANF_TRUE_RETURN; }
bool CBlock::AcceptBlock() { AssertLockHeld(cs_main); if (nVersion > CURRENT_VERSION) return DoS(100, error("AcceptBlock() : reject unknown block version %d", nVersion)); // Check for duplicate uint256 hash = GetHash(); if (mapBlockIndex.count(hash)) return error("AcceptBlock() : block already in mapBlockIndex"); // Get prev block index map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); if (mi == mapBlockIndex.end()) return DoS(10, error("AcceptBlock() : prev block not found")); CBlockIndex* pindexPrev = (*mi).second; int nHeight = pindexPrev->nHeight+1; if (IsProofOfStake() && nHeight < Params().FirstPOSBlock()) return DoS(100, error("AcceptBlock() : reject proof-of-stake at height <= %d", nHeight)); // Check coinbase timestamp if (GetBlockTime() > FutureDrift((int64_t)vtx[0].nTime, IsProofOfStake())) return DoS(50, error("AcceptBlock() : coinbase timestamp is too early")); // Check coinstake timestamp if (IsProofOfStake() && !CheckCoinStakeTimestamp(nHeight, GetBlockTime(), (int64_t)vtx[1].nTime)) return DoS(50, error("AcceptBlock() : coinstake timestamp violation nTimeBlock=%d nTimeTx=%u", GetBlockTime(), vtx[1].nTime)); // Check proof-of-work or proof-of-stake if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); // Check timestamp against prev LogPrintf("GetBlockTime(): %d, <=? pindexPrev->GetPastTimeLimit(): %d\nFutureDrift(GetBlockTime()): %d, <?pindexPrev->GetBlockTime(): %d\n",GetBlockTime(),pindexPrev->GetPastTimeLimit(),FutureDrift(GetBlockTime()),pindexPrev->GetBlockTime()); if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime(), IsProofOfStake()) < pindexPrev->GetBlockTime()) return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, vtx) if (!IsFinalTx(tx, nHeight, GetBlockTime())) return DoS(10, error("AcceptBlock() : contains a non-final transaction")); // Check that the block chain matches the known block chain up to a checkpoint if (!Checkpoints::CheckHardened(nHeight, hash)) return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight)); uint256 hashProof; // Verify hash target and signature of coinstake tx if (IsProofOfStake()) { uint256 targetProofOfStake; if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake)) { return error("AcceptBlock() : check proof-of-stake failed for block %s", hash.ToString()); } } // PoW is checked in CheckBlock() if (IsProofOfWork()) { hashProof = GetPoWHash(); } // Check that the block satisfies synchronized checkpoint if (!Checkpoints::CheckSync(nHeight)) return error("AcceptBlock() : rejected by synchronized checkpoint"); // Enforce rule that the coinbase starts with serialized block height CScript expect = CScript() << nHeight; if (vtx[0].vin[0].scriptSig.size() < expect.size() || !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) return error("AcceptBlock() : out of disk space"); unsigned int nFile = -1; unsigned int nBlockPos = 0; if (!WriteToDisk(nFile, nBlockPos)) return error("AcceptBlock() : WriteToDisk failed"); if (!AddToBlockIndex(nFile, nBlockPos, hashProof)) return error("AcceptBlock() : AddToBlockIndex failed"); // Relay inventory, but don't relay old inventory during initial block download int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); if (hashBestChain == hash) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); }