/** * Writes a GSO frame to a stream. * * @returns IPRT status code, @see RTStrmWrite. * * @param pStream The stream handle. * @param StartNanoTS What to subtract from the RTTimeNanoTS output. * @param pGso Pointer to the GSO context. * @param pvFrame The start of the GSO frame. * @param cbFrame The size of the GSO frame. * @param cbSegMax The max number of bytes to include in the file for * each segment. */ int PcapStreamGsoFrame(PRTSTREAM pStream, uint64_t StartNanoTS, PCPDMNETWORKGSO pGso, const void *pvFrame, size_t cbFrame, size_t cbSegMax) { struct pcaprec_hdr Hdr; pcapCalcHeader(&Hdr, StartNanoTS, 0, 0); uint8_t const *pbFrame = (uint8_t const *)pvFrame; uint8_t abHdrs[256]; uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame); for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) { uint32_t cbSegPayload; uint32_t offSegPayload = PDMNetGsoCarveSegment(pGso, pbFrame, cbFrame, iSeg, cSegs, abHdrs, &cbSegPayload); pcapUpdateHeader(&Hdr, pGso->cbHdrs + cbSegPayload, cbSegMax); int rc = RTStrmWrite(pStream, &Hdr, sizeof(Hdr)); if (RT_FAILURE(rc)) return rc; rc = RTStrmWrite(pStream, abHdrs, RT_MIN(Hdr.incl_len, pGso->cbHdrs)); if (RT_SUCCESS(rc) && Hdr.incl_len > pGso->cbHdrs) rc = RTStrmWrite(pStream, pbFrame + offSegPayload, Hdr.incl_len - pGso->cbHdrs); if (RT_FAILURE(rc)) return rc; } return VINF_SUCCESS; }
/** * Writes a frame to a stream. * * @returns IPRT status code, @see RTStrmWrite. * * @param pStream The stream handle. * @param StartNanoTS What to subtract from the RTTimeNanoTS output. * @param pvFrame The start of the frame. * @param cbFrame The size of the frame. * @param cbMax The max number of bytes to include in the file. */ int PcapStreamFrame(PRTSTREAM pStream, uint64_t StartNanoTS, const void *pvFrame, size_t cbFrame, size_t cbMax) { struct pcaprec_hdr Hdr; pcapCalcHeader(&Hdr, StartNanoTS, cbFrame, cbMax); int rc1 = RTStrmWrite(pStream, &Hdr, sizeof(Hdr)); int rc2 = RTStrmWrite(pStream, pvFrame, Hdr.incl_len); return RT_SUCCESS(rc1) ? rc2 : rc1; }
/** * Prints a range of lines with a prefix. * * @param pState The diff state. * @param chPrefix The prefix. * @param pStream The stream to get the lines from. * @param iLine The first line. * @param cLines The number of lines. */ static void scmDiffPrintLines(PSCMDIFFSTATE pState, char chPrefix, PSCMSTREAM pStream, size_t iLine, size_t cLines) { while (cLines-- > 0) { SCMEOL enmEol; size_t cchLine; const char *pchLine = ScmStreamGetLineByNo(pStream, iLine, &cchLine, &enmEol); RTStrmPutCh(pState->pDiff, chPrefix); if (pchLine && cchLine) { if (!pState->fSpecialChars) RTStrmWrite(pState->pDiff, pchLine, cchLine); else { size_t offVir = 0; const char *pchStart = pchLine; const char *pchTab = (const char *)memchr(pchLine, '\t', cchLine); while (pchTab) { RTStrmWrite(pState->pDiff, pchStart, pchTab - pchStart); offVir += pchTab - pchStart; size_t cchTab = pState->cchTab - offVir % pState->cchTab; switch (cchTab) { case 1: RTStrmPutStr(pState->pDiff, "."); break; case 2: RTStrmPutStr(pState->pDiff, ".."); break; case 3: RTStrmPutStr(pState->pDiff, "[T]"); break; case 4: RTStrmPutStr(pState->pDiff, "[TA]"); break; case 5: RTStrmPutStr(pState->pDiff, "[TAB]"); break; default: RTStrmPrintf(pState->pDiff, "[TAB%.*s]", cchTab - 5, g_szTabSpaces); break; } offVir += cchTab; /* next */ pchStart = pchTab + 1; pchTab = (const char *)memchr(pchStart, '\t', cchLine - (pchStart - pchLine)); } size_t cchLeft = cchLine - (pchStart - pchLine); if (cchLeft) RTStrmWrite(pState->pDiff, pchStart, cchLeft); } } if (!pState->fSpecialChars) RTStrmPutCh(pState->pDiff, '\n'); else if (enmEol == SCMEOL_LF) RTStrmPutStr(pState->pDiff, "[LF]\n"); else if (enmEol == SCMEOL_CRLF) RTStrmPutStr(pState->pDiff, "[CRLF]\n"); else RTStrmPutStr(pState->pDiff, "[NONE]\n"); iLine++; } }
/** Write a character to standard output and print an error and return false on * failure. */ bool outputCharacter(char ch) { int rc = RTStrmWrite(g_pStdOut, &ch, 1); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error writing output: %Rrc\n", rc); return false; } return true; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Create an empty address space that we can load modules and stuff into * as we parse the parameters. */ RTDBGAS hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTUINTPTR_MAX, ""); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc", rc); /* * Create a debugging configuration instance to work with so that we can * make use of (i.e. test) path searching and such. */ RTDBGCFG hDbgCfg; rc = RTDbgCfgCreate(&hDbgCfg, "IPRT", true /*fNativePaths*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgCfgCreate -> %Rrc", rc); /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--input", 'i', RTGETOPT_REQ_STRING }, { "--local-file", 'l', RTGETOPT_REQ_NOTHING }, { "--cache-file", 'c', RTGETOPT_REQ_NOTHING }, { "--pe-image", 'p', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--x86", '8', RTGETOPT_REQ_NOTHING }, { "--amd64", '6', RTGETOPT_REQ_NOTHING }, { "--whatever", '*', RTGETOPT_REQ_NOTHING }, }; PRTSTREAM pInput = g_pStdIn; PRTSTREAM pOutput = g_pStdOut; unsigned cVerbosityLevel = 0; enum { kOpenMethod_FromImage, kOpenMethod_FromPeImage } enmOpenMethod = kOpenMethod_FromImage; bool fCacheFile = false; RTLDRARCH enmArch = RTLDRARCH_WHATEVER; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'i': rc = RTStrmOpen(ValueUnion.psz, "r", &pInput); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open '%s' for reading: %Rrc", ValueUnion.psz, rc); break; case 'c': fCacheFile = true; break; case 'l': fCacheFile = false; break; case 'p': enmOpenMethod = kOpenMethod_FromPeImage; break; case 'v': cVerbosityLevel++; break; case '8': enmArch = RTLDRARCH_X86_32; break; case '6': enmArch = RTLDRARCH_AMD64; break; case '*': enmArch = RTLDRARCH_WHATEVER; break; case 'h': RTPrintf("Usage: %s [options] <module> <address> [<module> <address> [..]]\n" "\n" "Options:\n" " -i,--input=file\n" " Specify a input file instead of standard input.\n" " --pe-image\n" " Use RTDbgModCreateFromPeImage to open the file." " -v, --verbose\n" " Display the address space before doing the filtering.\n" " --amd64,--x86,--whatever\n" " Selects the desired architecture.\n" " -h, -?, --help\n" " Display this help text and exit successfully.\n" " -V, --version\n" " Display the revision and exit successfully.\n" , RTPathFilename(argv[0])); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("$Revision$\n"); return RTEXITCODE_SUCCESS; case VINF_GETOPT_NOT_OPTION: { /* <module> <address> */ const char *pszModule = ValueUnion.psz; rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); uint64_t u64Address = ValueUnion.u64; uint32_t cbImage = 0; uint32_t uTimestamp = 0; if (fCacheFile) { rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); cbImage = ValueUnion.u32; rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); uTimestamp = ValueUnion.u32; } RTDBGMOD hMod; if (enmOpenMethod == kOpenMethod_FromImage) rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, enmArch, hDbgCfg); else rc = RTDbgModCreateFromPeImage(&hMod, pszModule, NULL, NIL_RTLDRMOD, cbImage, uTimestamp, hDbgCfg); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc", pszModule, rc); rc = RTDbgAsModuleLink(hDbgAs, hMod, u64Address, 0 /* fFlags */); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc", pszModule, u64Address, rc); break; } default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Display the address space. */ if (cVerbosityLevel) { RTPrintf("*** Address Space Dump ***\n"); uint32_t cModules = RTDbgAsModuleCount(hDbgAs); for (uint32_t iModule = 0; iModule < cModules; iModule++) { RTDBGMOD hDbgMod = RTDbgAsModuleByIndex(hDbgAs, iModule); RTPrintf("Module #%u: %s\n", iModule, RTDbgModName(hDbgMod)); RTDBGASMAPINFO aMappings[128]; uint32_t cMappings = RT_ELEMENTS(aMappings); rc = RTDbgAsModuleQueryMapByIndex(hDbgAs, iModule, &aMappings[0], &cMappings, 0 /*fFlags*/); if (RT_SUCCESS(rc)) { for (uint32_t iMapping = 0; iMapping < cMappings; iMapping++) { if (aMappings[iMapping].iSeg == NIL_RTDBGSEGIDX) RTPrintf(" mapping #%u: %RTptr-%RTptr\n", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + RTDbgModImageSize(hDbgMod) - 1); else { RTDBGSEGMENT SegInfo; rc = RTDbgModSegmentByIndex(hDbgMod, aMappings[iMapping].iSeg, &SegInfo); if (RT_SUCCESS(rc)) RTPrintf(" mapping #%u: %RTptr-%RTptr (segment #%u - '%s')", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + SegInfo.cb, SegInfo.iSeg, SegInfo.szName); else RTPrintf(" mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address); } if (cVerbosityLevel > 1) { uint32_t cSymbols = RTDbgModSymbolCount(hDbgMod); RTPrintf(" %u symbols\n", cSymbols); for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++) { RTDBGSYMBOL SymInfo; rc = RTDbgModSymbolByOrdinal(hDbgMod, iSymbol, &SymInfo); if (RT_SUCCESS(rc)) RTPrintf(" #%04u at %08x:%RTptr %05llx %s\n", SymInfo.iOrdinal, SymInfo.iSeg, SymInfo.offSeg, (uint64_t)SymInfo.cb, SymInfo.szName); } } } } else RTMsgError("RTDbgAsModuleQueryMapByIndex failed: %Rrc", rc); RTDbgModRelease(hDbgMod); } RTPrintf("*** End of Address Space Dump ***\n"); } /* * Read text from standard input and see if there is anything we can translate. */ for (;;) { /* Get a line. */ char szLine[_64K]; rc = RTStrmGetLine(pInput, szLine, sizeof(szLine)); if (rc == VERR_EOF) break; if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine() -> %Rrc\n", rc); /* * Search the line for potential addresses and replace them with * symbols+offset. */ const char *pszStart = szLine; const char *psz = szLine; char ch; while ((ch = *psz) != '\0') { size_t cchAddress; uint64_t u64Address; if ( ( ch == '0' && (psz[1] == 'x' || psz[1] == 'X') && TryParseAddress(psz, &cchAddress, &u64Address)) || ( RT_C_IS_XDIGIT(ch) && TryParseAddress(psz, &cchAddress, &u64Address)) ) { /* Print. */ psz += cchAddress; if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); pszStart = psz; /* Try get the module. */ RTUINTPTR uAddr; RTDBGSEGIDX iSeg; RTDBGMOD hDbgMod; rc = RTDbgAsModuleByAddr(hDbgAs, u64Address, &hDbgMod, &uAddr, &iSeg); if (RT_SUCCESS(rc)) { if (iSeg != UINT32_MAX) RTStrmPrintf(pOutput, "=[%s:%u", RTDbgModName(hDbgMod), iSeg); else RTStrmPrintf(pOutput, "=[%s", RTDbgModName(hDbgMod), iSeg); /* * Do we have symbols? */ RTDBGSYMBOL Symbol; RTINTPTR offSym; rc = RTDbgAsSymbolByAddr(hDbgAs, u64Address, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &offSym, &Symbol, NULL); if (RT_SUCCESS(rc)) { if (!offSym) RTStrmPrintf(pOutput, "!%s", Symbol.szName); else if (offSym > 0) RTStrmPrintf(pOutput, "!%s+%#llx", Symbol.szName, offSym); else RTStrmPrintf(pOutput, "!%s-%#llx", Symbol.szName, -offSym); } else RTStrmPrintf(pOutput, "+%#llx", u64Address - uAddr); /* * Do we have line numbers? */ RTDBGLINE Line; RTINTPTR offLine; rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line, NULL); if (RT_SUCCESS(rc)) RTStrmPrintf(pOutput, " %Rbn(%u)", Line.szFilename, Line.uLineNo); RTStrmPrintf(pOutput, "]"); RTDbgModRelease(hDbgMod); } } else psz++; } if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); RTStrmPutCh(pOutput, '\n'); } return RTEXITCODE_SUCCESS; }
/** * Writes the stream header. * * @returns IPRT status code, @see RTStrmWrite. * * @param pStream The stream handle. * @param StartNanoTS What to subtract from the RTTimeNanoTS output. */ int PcapStreamHdr(PRTSTREAM pStream, uint64_t StartNanoTS) { int rc1 = RTStrmWrite(pStream, &s_Hdr, sizeof(s_Hdr)); int rc2 = PcapStreamFrame(pStream, StartNanoTS, s_szDummyData, 60, sizeof(s_szDummyData)); return RT_SUCCESS(rc1) ? rc2 : rc1; }
int main(int argc, char **argv) { unsigned cErrors = 0; RTR3InitExe(argc, &argv, 0); if (argc <= 1) { RTPrintf("usage: %s default\n", argv[0]); return 1; } for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "default")) ; else { RTPrintf("Unknown parameter '%s'\n", argv[i]); return 1; } } RTHTTP hHttp; char *pszBuf = NULL; PRTSTREAM CAFile = NULL; int rc = RTHttpCreate(&hHttp); // create certificate file if (RT_SUCCESS(rc)) rc = RTStrmOpen(CAFILE_NAME, "w+b", &CAFile); // fetch root CA certificate (new one, often avoided in cert chains by // using an intermediate cert which is signed by old root) if (RT_SUCCESS(rc)) rc = RTHttpGet(hHttp, "http://www.verisign.com/repository/roots/root-certificates/PCA-3G5.pem", &pszBuf); if (RT_SUCCESS(rc) && pszBuf) { uint8_t *abSha1; size_t cbSha1; uint8_t *abSha512; size_t cbSha512; size_t cbBuf = strlen(pszBuf); const uint8_t abSha1PCA3G5[] = { 0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5 }; const uint8_t abSha512PCA3G5[] = { 0xd4, 0xf8, 0x10, 0x54, 0x72, 0x77, 0x0a, 0x2d, 0xe3, 0x17, 0xb3, 0xcf, 0xed, 0x61, 0xae, 0x5c, 0x5d, 0x3e, 0xde, 0xa1, 0x41, 0x35, 0xb2, 0xdf, 0x60, 0xe2, 0x61, 0xfe, 0x3a, 0xc1, 0x66, 0xa3, 0x3c, 0x88, 0x54, 0x04, 0x4f, 0x1d, 0x13, 0x46, 0xe3, 0x8c, 0x06, 0x92, 0x9d, 0x70, 0x54, 0xc3, 0x44, 0xeb, 0x2c, 0x74, 0x25, 0x9e, 0x5d, 0xfb, 0xd2, 0x6b, 0xa8, 0x9a, 0xf0, 0xb3, 0x6a, 0x01 }; rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, &abSha1, &cbSha1, &abSha512, &cbSha512); if (RT_SUCCESS(rc)) { if (cbSha1 != sizeof(abSha1PCA3G5)) { RTPrintf("Wrong SHA1 digest size of PCA-3G5\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha1PCA3G5, abSha1, cbSha1)) { RTPrintf("Wrong SHA1 digest for PCA-3G5:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha1, abSha1, sizeof(abSha1PCA3G5), abSha1PCA3G5); rc = VERR_INTERNAL_ERROR; } if (cbSha512 != sizeof(abSha512PCA3G5)) { RTPrintf("Wrong SHA512 digest size of PCA-3G5\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha512PCA3G5, abSha512, cbSha512)) { RTPrintf("Wrong SHA512 digest for PCA-3G5:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha512, abSha512, sizeof(abSha512PCA3G5), abSha512PCA3G5); rc = VERR_INTERNAL_ERROR; } RTMemFree(abSha1); RTMemFree(abSha512); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, pszBuf, cbBuf); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); } } if (pszBuf) { RTMemFree(pszBuf); pszBuf = NULL; } // fetch root CA certificate (old one, but still very widely used) if (RT_SUCCESS(rc)) rc = RTHttpGet(hHttp, "http://www.verisign.com/repository/roots/root-certificates/PCA-3.pem", &pszBuf); if (RT_SUCCESS(rc) && pszBuf) { uint8_t *abSha1; size_t cbSha1; uint8_t *abSha512; size_t cbSha512; size_t cbBuf = strlen(pszBuf); const uint8_t abSha1PCA3[] = { 0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55, 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b }; const uint8_t abSha512PCA3[] = { 0xbb, 0xf7, 0x8a, 0x19, 0x9f, 0x37, 0xee, 0xa2, 0xce, 0xc8, 0xaf, 0xe3, 0xd6, 0x22, 0x54, 0x20, 0x74, 0x67, 0x6e, 0xa5, 0x19, 0xb7, 0x62, 0x1e, 0xc1, 0x2f, 0xd5, 0x08, 0xf4, 0x64, 0xc4, 0xc6, 0xbb, 0xc2, 0xf2, 0x35, 0xe7, 0xbe, 0x32, 0x0b, 0xde, 0xb2, 0xfc, 0x44, 0x92, 0x5b, 0x8b, 0x9b, 0x77, 0xa5, 0x40, 0x22, 0x18, 0x12, 0xcb, 0x3d, 0x0a, 0x67, 0x83, 0x87, 0xc5, 0x45, 0xc4, 0x99 }; rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, &abSha1, &cbSha1, &abSha512, &cbSha512); if (RT_SUCCESS(rc)) { if (cbSha1 != sizeof(abSha1PCA3)) { RTPrintf("Wrong SHA1 digest size of PCA-3\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha1PCA3, abSha1, cbSha1)) { RTPrintf("Wrong SHA1 digest for PCA-3:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha1, abSha1, sizeof(abSha1PCA3), abSha1PCA3); rc = VERR_INTERNAL_ERROR; } if (cbSha512 != sizeof(abSha512PCA3)) { RTPrintf("Wrong SHA512 digest size of PCA-3\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha512PCA3, abSha512, cbSha512)) { RTPrintf("Wrong SHA512 digest for PCA-3:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha512, abSha512, sizeof(abSha512PCA3), abSha512PCA3); rc = VERR_INTERNAL_ERROR; } RTMemFree(abSha1); RTMemFree(abSha512); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, pszBuf, cbBuf); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); } } if (pszBuf) { RTMemFree(pszBuf); pszBuf = NULL; } // close certificate file if (CAFile) { RTStrmClose(CAFile); CAFile = NULL; } if (RT_SUCCESS(rc)) rc = RTHttpSetCAFile(hHttp, CAFILE_NAME); if (RT_SUCCESS(rc)) rc = RTHttpGet(hHttp, "https://update.virtualbox.org/query.php?platform=LINUX_32BITS_UBUNTU_12_04&version=4.1.18", &pszBuf); if ( RT_FAILURE(rc) && rc != VERR_HTTP_COULDNT_CONNECT) cErrors++; if (RT_FAILURE(rc)) RTPrintf("Error code: %Rrc\n", rc); else RTPrintf("Success!\n"); RTPrintf("Got: %s\n", pszBuf); if (pszBuf) { RTMemFree(pszBuf); pszBuf = NULL; } RTHttpDestroy(hHttp); // RTFileDelete(CAFILE_NAME); return !!cErrors; }
static int extractPCA3G5(RTHTTP hHttp, PRTSTREAM CAFile, uint8_t *pu8Buf, size_t cbBuf) { uint8_t *abSha1; size_t cbSha1; uint8_t *abSha512; size_t cbSha512; char *pszBuf = (char*)pu8Buf; const uint8_t abSha1PCA3G5[] = { 0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5 }; const uint8_t abSha512PCA3G5[] = { 0xd4, 0xf8, 0x10, 0x54, 0x72, 0x77, 0x0a, 0x2d, 0xe3, 0x17, 0xb3, 0xcf, 0xed, 0x61, 0xae, 0x5c, 0x5d, 0x3e, 0xde, 0xa1, 0x41, 0x35, 0xb2, 0xdf, 0x60, 0xe2, 0x61, 0xfe, 0x3a, 0xc1, 0x66, 0xa3, 0x3c, 0x88, 0x54, 0x04, 0x4f, 0x1d, 0x13, 0x46, 0xe3, 0x8c, 0x06, 0x92, 0x9d, 0x70, 0x54, 0xc3, 0x44, 0xeb, 0x2c, 0x74, 0x25, 0x9e, 0x5d, 0xfb, 0xd2, 0x6b, 0xa8, 0x9a, 0xf0, 0xb3, 0x6a, 0x01 }; int rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, &abSha1, &cbSha1, &abSha512, &cbSha512); if (RT_SUCCESS(rc)) { if (cbSha1 != sizeof(abSha1PCA3G5)) { RTPrintf("Wrong SHA1 digest size of PCA-3G5\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha1PCA3G5, abSha1, cbSha1)) { RTPrintf("Wrong SHA1 digest for PCA-3G5:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha1, abSha1, sizeof(abSha1PCA3G5), abSha1PCA3G5); rc = VERR_INTERNAL_ERROR; } if (cbSha512 != sizeof(abSha512PCA3G5)) { RTPrintf("Wrong SHA512 digest size of PCA-3G5\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha512PCA3G5, abSha512, cbSha512)) { RTPrintf("Wrong SHA512 digest for PCA-3G5:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha512, abSha512, sizeof(abSha512PCA3G5), abSha512PCA3G5); rc = VERR_INTERNAL_ERROR; } RTMemFree(abSha1); RTMemFree(abSha512); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, pszBuf, cbBuf); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); } return rc; }
static int extractPCA3(RTHTTP hHttp, PRTSTREAM CAFile, uint8_t *pu8Buf, size_t cbBuf) { uint8_t *abSha1; size_t cbSha1; uint8_t *abSha512; size_t cbSha512; char *pszBuf = (char*)pu8Buf; const uint8_t abSha1PCA3[] = { 0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55, 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b }; const uint8_t abSha512PCA3[] = { 0xbb, 0xf7, 0x8a, 0x19, 0x9f, 0x37, 0xee, 0xa2, 0xce, 0xc8, 0xaf, 0xe3, 0xd6, 0x22, 0x54, 0x20, 0x74, 0x67, 0x6e, 0xa5, 0x19, 0xb7, 0x62, 0x1e, 0xc1, 0x2f, 0xd5, 0x08, 0xf4, 0x64, 0xc4, 0xc6, 0xbb, 0xc2, 0xf2, 0x35, 0xe7, 0xbe, 0x32, 0x0b, 0xde, 0xb2, 0xfc, 0x44, 0x92, 0x5b, 0x8b, 0x9b, 0x77, 0xa5, 0x40, 0x22, 0x18, 0x12, 0xcb, 0x3d, 0x0a, 0x67, 0x83, 0x87, 0xc5, 0x45, 0xc4, 0x99 }; int rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, &abSha1, &cbSha1, &abSha512, &cbSha512); if (RT_SUCCESS(rc)) { if (cbSha1 != sizeof(abSha1PCA3)) { RTPrintf("Wrong SHA1 digest size of PCA-3\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha1PCA3, abSha1, cbSha1)) { RTPrintf("Wrong SHA1 digest for PCA-3:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha1, abSha1, sizeof(abSha1PCA3), abSha1PCA3); rc = VERR_INTERNAL_ERROR; } if (cbSha512 != sizeof(abSha512PCA3)) { RTPrintf("Wrong SHA512 digest size of PCA-3\n"); rc = VERR_INTERNAL_ERROR; } else if (memcmp(abSha512PCA3, abSha512, cbSha512)) { RTPrintf("Wrong SHA512 digest for PCA-3:\n" "Got: %.*Rhxs\n" "Expected: %.*Rhxs\n", cbSha512, abSha512, sizeof(abSha512PCA3), abSha512PCA3); rc = VERR_INTERNAL_ERROR; } RTMemFree(abSha1); RTMemFree(abSha512); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, pszBuf, cbBuf); if (RT_SUCCESS(rc)) rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); } return rc; }
RTDECL(int) RTCrStoreCertExportAsPem(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename) { /* * Validate input. */ AssertReturn(!fFlags, VERR_INVALID_FLAGS); /* * Start the enumeration first as this validates the store handle. */ RTCRSTORECERTSEARCH Search; int rc = RTCrStoreCertFindAll(hStore, &Search); if (RT_SUCCESS(rc)) { /* * Open the file for writing. * * Note! We must use text and no binary here, because the base-64 API * below will use host specific EOL markers, not CRLF as PEM * specifies. */ PRTSTREAM hStrm; rc = RTStrmOpen(pszFilename, "w", &hStrm); if (RT_SUCCESS(rc)) { /* * Enumerate the certificates in the store, writing them out one by one. */ size_t cbBase64 = 0; char *pszBase64 = NULL; PCRTCRCERTCTX pCertCtx; while ((pCertCtx = RTCrStoreCertSearchNext(hStore, &Search)) != NULL) { const char *pszMarker; switch (pCertCtx->fFlags & RTCRCERTCTX_F_ENC_MASK) { case RTCRCERTCTX_F_ENC_X509_DER: pszMarker = "CERTIFICATE"; break; case RTCRCERTCTX_F_ENC_TAF_DER: pszMarker = "TRUST ANCHOR"; break; default: pszMarker = NULL; break; } if (pszMarker && pCertCtx->cbEncoded > 0) { /* * Do the base64 conversion first. */ size_t cchEncoded = RTBase64EncodedLength(pCertCtx->cbEncoded); if (cchEncoded < cbBase64) { /* likely */ } else { size_t cbNew = RT_ALIGN(cchEncoded + 64, 128); void *pvNew = RTMemRealloc(pszBase64, cbNew); if (!pvNew) { rc = VERR_NO_MEMORY; break; } cbBase64 = cbNew; pszBase64 = (char *)pvNew; } rc = RTBase64Encode(pCertCtx->pabEncoded, pCertCtx->cbEncoded, pszBase64, cbBase64, &cchEncoded); if (RT_FAILURE(rc)) break; RTStrmPrintf(hStrm, "-----BEGIN %s-----\n", pszMarker); RTStrmWrite(hStrm, pszBase64, cchEncoded); rc = RTStrmPrintf(hStrm, "\n-----END %s-----\n", pszMarker); if (RT_FAILURE(rc)) break; } RTCrCertCtxRelease(pCertCtx); } if (pCertCtx) RTCrCertCtxRelease(pCertCtx); RTMemFree(pszBase64); /* * Flush the output file before closing. */ int rc2 = RTStrmFlush(hStrm); if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) rc = rc2; RTStrmClearError(hStrm); /** @todo fix RTStrmClose... */ rc2 = RTStrmClose(hStrm); if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) rc = rc2; } int rc2 = RTCrStoreCertSearchDestroy(hStore, &Search); AssertRC(rc2); } return rc; }
RTDECL(RTEXITCODE) RTPathRmCmd(unsigned cArgs, char **papszArgs) { /* * Parse the command line. */ static const RTGETOPTDEF s_aOptions[] = { /* operations */ { "--dirs-and-more", 'd', RTGETOPT_REQ_NOTHING }, { "--force", 'f', RTGETOPT_REQ_NOTHING }, { "--prompt", 'i', RTGETOPT_REQ_NOTHING }, { "--prompt-once", 'I', RTGETOPT_REQ_NOTHING }, { "--interactive", RTPATHRMCMD_OPT_INTERACTIVE, RTGETOPT_REQ_STRING }, { "--one-file-system", RTPATHRMCMD_OPT_ONE_FILE_SYSTEM, RTGETOPT_REQ_NOTHING }, { "--preserve-root", RTPATHRMCMD_OPT_PRESERVE_ROOT, RTGETOPT_REQ_NOTHING }, { "--no-preserve-root", RTPATHRMCMD_OPT_NO_PRESERVE_ROOT, RTGETOPT_REQ_NOTHING }, { "--recursive", 'R', RTGETOPT_REQ_NOTHING }, { "--recursive", 'r', RTGETOPT_REQ_NOTHING }, { "--safe-delete", 'P', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, /* IPRT extensions */ { "--machine-readable", RTPATHRMCMD_OPT_MACHINE_READABLE, RTGETOPT_REQ_NOTHING }, { "--machinereadable", RTPATHRMCMD_OPT_MACHINE_READABLE, RTGETOPT_REQ_NOTHING }, /* bad long option style */ }; RTGETOPTSTATE GetState; int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOpt failed: %Rrc", rc); RTPATHRMCMDOPTS Opts; RT_ZERO(Opts); Opts.fPreserveRoot = true; Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_NONE; RTGETOPTUNION ValueUnion; while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0 && rc != VINF_GETOPT_NOT_OPTION) { switch (rc) { case 'd': Opts.fDirsAndOther = true; break; case 'f': Opts.fForce = true; Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_NONE; break; case 'i': Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_ALL; break; case 'I': Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_ONCE; break; case RTPATHRMCMD_OPT_INTERACTIVE: if (!strcmp(ValueUnion.psz, "always")) Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_ALL; else if (!strcmp(ValueUnion.psz, "once")) Opts.enmInteractive = RTPATHRMCMDINTERACTIVE_ONCE; else return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown --interactive option value: '%s'\n", ValueUnion.psz); break; case RTPATHRMCMD_OPT_ONE_FILE_SYSTEM: Opts.fOneFileSystem = true; break; case RTPATHRMCMD_OPT_PRESERVE_ROOT: Opts.fPreserveRoot = true; break; case RTPATHRMCMD_OPT_NO_PRESERVE_ROOT: Opts.fPreserveRoot = false; break; case 'R': case 'r': Opts.fRecursive = true; Opts.fDirsAndOther = true; break; case 'P': Opts.fSafeDelete = true; break; case 'v': Opts.fVerbose = true; break; case RTPATHRMCMD_OPT_MACHINE_READABLE: Opts.fMachineReadable = true; break; case 'h': RTPrintf("Usage: to be written\nOption dump:\n"); for (unsigned i = 0; i < RT_ELEMENTS(s_aOptions); i++) if (RT_C_IS_PRINT(s_aOptions[i].iShort)) RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong); else RTPrintf(" %s\n", s_aOptions[i].pszLong); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Options we don't support. */ if (Opts.fOneFileSystem) return RTMsgErrorExit(RTEXITCODE_FAILURE, "The --one-file-system option is not yet implemented.\n"); if (Opts.enmInteractive != RTPATHRMCMDINTERACTIVE_NONE) return RTMsgErrorExit(RTEXITCODE_FAILURE, "The -i, -I and --interactive options are not implemented yet.\n"); /* * No files means error. */ if (rc != VINF_GETOPT_NOT_OPTION && !Opts.fForce) return RTMsgErrorExit(RTEXITCODE_FAILURE, "No files or directories specified.\n"); /* * Machine readable init + header. */ if (Opts.fMachineReadable) { rc = RTStrmSetMode(g_pStdOut, true /*fBinary*/, false /*fCurrentCodeSet*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmSetMode failed: %Rrc.\n", rc); static const char s_achHeader[] = "hdr_id=rm\0hdr_ver=1"; RTStrmWrite(g_pStdOut, s_achHeader, sizeof(s_achHeader)); } /* * Delete the specified files/dirs/whatever. */ RTEXITCODE rcExit = RTEXITCODE_SUCCESS; while (rc == VINF_GETOPT_NOT_OPTION) { rc = rtPathRmOne(&Opts, ValueUnion.psz); if (RT_FAILURE(rc)) rcExit = RTEXITCODE_FAILURE; /* next */ rc = RTGetOpt(&GetState, &ValueUnion); } if (rc != 0) rcExit = RTGetOptPrintError(rc, &ValueUnion); /* * Terminate the machine readable stuff. */ if (Opts.fMachineReadable) { RTStrmWrite(g_pStdOut, "\0\0\0", 4); rc = RTStrmFlush(g_pStdOut); if (RT_FAILURE(rc) && rcExit == RTEXITCODE_SUCCESS) rcExit = RTEXITCODE_FAILURE; } return rcExit; }
/** The actual implemenation code for @a createServiceFile. */ bool createServiceFileCore(char **ppachTemplate, struct SERVICEPARAMETERS *pParameters) { /* The size of the template data we have read. */ size_t cchTemplate = 0; /* The size of the buffer we have allocated. */ size_t cbBuffer = 0; /* How much of the template data we have written out. */ size_t cchWritten = 0; int rc = VINF_SUCCESS; /* First of all read in the file. */ while (rc != VINF_EOF) { size_t cchRead; if (cchTemplate == cbBuffer) { cbBuffer += READ_SIZE; *ppachTemplate = (char *)RTMemRealloc((void *)*ppachTemplate, cbBuffer); } if (!*ppachTemplate) { RTStrmPrintf(g_pStdErr, "Out of memory.\n"); return false; } rc = RTStrmReadEx(g_pStdIn, *ppachTemplate + cchTemplate, cbBuffer - cchTemplate, &cchRead); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error reading input: %Rrc\n", rc); return false; } if (!cchRead) rc = VINF_EOF; cchTemplate += cchRead; } while (true) { /* Find the next '%' character if any and write out up to there (or the * end if there is no '%'). */ char *pchNext = (char *) memchr((void *)(*ppachTemplate + cchWritten), '%', cchTemplate - cchWritten); size_t cchToWrite = pchNext ? pchNext - *ppachTemplate - cchWritten : cchTemplate - cchWritten; rc = RTStrmWrite(g_pStdOut, *ppachTemplate + cchWritten, cchToWrite); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error writing output: %Rrc\n", rc); return false; } cchWritten += cchToWrite; if (!pchNext) break; /* And substitute any of our well-known strings. We favour code * readability over efficiency here. */ if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, COMMAND, sizeof(COMMAND) - 1)) { if (!pParameters->pcszCommand) { RTStrmPrintf(g_pStdErr, "--command not specified.\n"); return false; } if (!writeCommand(pParameters->enmFormat, pParameters->pcszCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, ARGUMENTS, sizeof(ARGUMENTS) - 1)) { if ( pParameters->pcszArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, DESCRIPTION, sizeof(DESCRIPTION) - 1)) { if (!pParameters->pcszDescription) { RTStrmPrintf(g_pStdErr, "--description not specified.\n"); return false; } if (!writePrintableString(pParameters->enmFormat, pParameters->pcszDescription)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, SERVICE_NAME, sizeof(SERVICE_NAME) - 1)) { if ( !pParameters->pcszCommand && !pParameters->pcszServiceName) { RTStrmPrintf(g_pStdErr, "Neither --command nor --service-name specified.\n"); return false; } if (pParameters->pcszServiceName) { if (!writePrintableString(pParameters->enmFormat, pParameters->pcszServiceName)) return false; } else { const char *pcszFileName = RTPathFilename(pParameters->pcszCommand); const char *pcszSuffix = RTPathSuffix(pParameters->pcszCommand); char *pszName = RTStrDupN(pcszFileName, pcszSuffix ? pcszSuffix - pcszFileName : RTPATH_MAX); bool fRc; if (!pszName) { RTStrmPrintf(g_pStdErr, "Out of memory.\n"); return false; } fRc = writePrintableString(pParameters->enmFormat, pszName); RTStrFree(pszName); if (!fRc) return false; } } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_ONESHOT, sizeof(HAVE_ONESHOT) - 1)) { if (!pParameters->fOneShot) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_DAEMON, sizeof(HAVE_DAEMON) - 1)) { if (pParameters->fOneShot) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STOP_COMMAND, sizeof(STOP_COMMAND) - 1)) { if ( pParameters->pcszStopCommand && !writeCommand(pParameters->enmFormat, pParameters->pcszStopCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STOP_ARGUMENTS, sizeof(STOP_ARGUMENTS) - 1)) { if ( pParameters->pcszStopArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszStopArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_STOP_COMMAND, sizeof(HAVE_STOP_COMMAND) - 1)) { if (!pParameters->pcszStopCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, NO_STOP_COMMAND, sizeof(NO_STOP_COMMAND) - 1)) { if (pParameters->pcszStopCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STATUS_COMMAND, sizeof(STATUS_COMMAND) - 1)) { if ( pParameters->pcszStatusCommand && !writeCommand(pParameters->enmFormat, pParameters->pcszStatusCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STATUS_ARGUMENTS, sizeof(STATUS_ARGUMENTS) - 1)) { if ( pParameters->pcszStatusArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszStatusArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_STATUS_COMMAND, sizeof(HAVE_STATUS_COMMAND) - 1)) { if (!pParameters->pcszStatusCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, NO_STATUS_COMMAND, sizeof(NO_STATUS_COMMAND) - 1)) { if (pParameters->pcszStatusCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, "%%", 2)) { rc = RTStrmPutCh(g_pStdOut, '%'); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error writing output: %Rrc\n", rc); return false; } } else { RTStrmPrintf(g_pStdErr, "Unknown substitution sequence in input at \"%.*s\"\n", RT_MIN(16, cchTemplate - cchWritten), *ppachTemplate + cchWritten); return false; } } return true; }