int main(int argc, char* argv[]) { ShowBanner(); if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { cerr << _T("MFC Failed to initialize.\n"); return 1; } if (argc < 2 || !ParseOptions(argc, argv) || pszURL == NULL) ShowUsage(); int nRetCode = 0; CTearSession session(_T("TEAR - MFC Sample App"), dwAccessType); CHttpConnection* pServer = NULL; CHttpFile* pFile = NULL; try { // check to see if this is a reasonable URL CString strServerName; CString strObject; INTERNET_PORT nPort; DWORD dwServiceType; if (!AfxParseURL(pszURL, dwServiceType, strServerName, strObject, nPort) || dwServiceType != INTERNET_SERVICE_HTTP) { cerr << _T("Error: can only use URLs beginning with http://") << endl; ThrowTearException(1); } if (bProgressMode) { cerr << _T("Opening Internet..."); VERIFY(session.EnableStatusCallback(TRUE)); } pServer = session.GetHttpConnection(strServerName, nPort); pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags); pFile->AddRequestHeaders(szHeaders); pFile->SendRequest(); DWORD dwRet; pFile->QueryInfoStatusCode(dwRet); // if access was denied, prompt the user for the password if (dwRet == HTTP_STATUS_DENIED) { DWORD dwPrompt; dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL); // if the user cancelled the dialog, bail out if (dwPrompt != ERROR_INTERNET_FORCE_RETRY) { cerr << _T("Access denied: Invalid password\n"); ThrowTearException(1); } pFile->SendRequest(); pFile->QueryInfoStatusCode(dwRet); } CString strNewLocation; pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation); // were we redirected? // these response status codes come from WININET.H if (dwRet == HTTP_STATUS_MOVED || dwRet == HTTP_STATUS_REDIRECT || dwRet == HTTP_STATUS_REDIRECT_METHOD) { CString strNewLocation; pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation); int nPlace = strNewLocation.Find(_T("Location: ")); if (nPlace == -1) { cerr << _T("Error: Site redirects with no new location") << endl; ThrowTearException(2); } strNewLocation = strNewLocation.Mid(nPlace + 10); nPlace = strNewLocation.Find('\n'); if (nPlace > 0) strNewLocation = strNewLocation.Left(nPlace); // close up the redirected site pFile->Close(); delete pFile; pServer->Close(); delete pServer; if (bProgressMode) { cerr << _T("Caution: redirected to "); cerr << (LPCTSTR) strNewLocation << endl; } // figure out what the old place was if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort)) { cerr << _T("Error: the redirected URL could not be parsed.") << endl; ThrowTearException(2); } if (dwServiceType != INTERNET_SERVICE_HTTP) { cerr << _T("Error: the redirected URL does not reference a HTTP resource.") << endl; ThrowTearException(2); } // try again at the new location pServer = session.GetHttpConnection(strServerName, nPort); pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags); pFile->AddRequestHeaders(szHeaders); pFile->SendRequest(); pFile->QueryInfoStatusCode(dwRet); if (dwRet != HTTP_STATUS_OK) { cerr << _T("Error: Got status code ") << dwRet << endl; ThrowTearException(2); } } cerr << _T("Status Code is ") << dwRet << endl; TCHAR sz[1024]; while (pFile->ReadString(sz, 1023)) { if (bStripMode) StripTags(sz); cout << sz; } // NOTE: Since HTTP servers normally spit back plain text, the // above code (which reads line by line) is just fine. However, // other data sources (eg, FTP servers) might provide binary data // which should be handled a buffer at a time, like this: #if 0 while (nRead > 0) { sz[nRead] = '\0'; if (bStripMode) StripTags(sz); cout << sz; nRead = pFile->Read(sz, 1023); } #endif pFile->Close(); pServer->Close(); } catch (CInternetException* pEx) { // catch errors from WinINet TCHAR szErr[1024]; pEx->GetErrorMessage(szErr, 1024); cerr << _T("Error: (") << pEx->m_dwError << _T(") "); cerr << szErr << endl; nRetCode = 2; pEx->Delete(); } catch (CTearException* pEx) { // catch things wrong with parameters, etc nRetCode = pEx->m_nErrorCode; TRACE1("Error: Exiting with CTearException(%d)\n", nRetCode); pEx->Delete(); } if (pFile != NULL) delete pFile; if (pServer != NULL) delete pServer; session.Close(); return nRetCode; }
bool CParameter::CommandLine (int argc, _TCHAR* argv[]) { bool help = argc == 1; bool ssl = false; unsigned char stage = 0; bool bien = argc > 1; bool multi = false; iSign = true; for (int index = 1; index < argc; index++) { // WINDOWS ENVIRONMENT : If the underlying platform is WINDOWS then, // cope up with multiple arguments following the '-' or '/'. // // LINUX ENVIRONMENT : If the underlying platform is LINUX then, cope // up with multiple arguments following only the '-'. This restriction // of not dealing with arguments following '/' is due to the fact that, // the absolute paths in case of LINUX start with a '/'. So, this could // be mistaken as an option if we treat anything prefixed by a '/' as // an option. Hence, this facility is being removed once for all and // only '-' can(should) be used for specifying an option. if ( (argv [index][0] == '-') #ifndef __LINUX__ || (argv [index][0] == '/') #endif ) { int wCharacter = 1; while (argv[index][wCharacter] !='\0') { switch (argv [index][wCharacter]) { case 'a' : case 'A' : #ifdef _DEBUG iDump = true; #endif break; #ifdef GENERATE_ERRORS case 'b' : case 'B' : { for (int offset = wCharacter+1; argv [index] [offset]; offset++) { switch(argv [index] [offset]) { case 'a' : case 'A' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugArrayCount); break; case 'b' : case 'B' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugInsaneBlob); break; case 'c' : case 'C' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugCRCError); break; case 'e' : case 'E' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugBigEndian); break; case 'f' : case 'F' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugDuffFieldType); break; case 'h' : case 'H' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugHashError); break; case 'l' : case 'L' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugInvalidLength); break; case 'm' : case 'M' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugMissingField); break; case 'n' : case 'N' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugNegativeLength); break; case 's' : case 'S' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugInsaneString); break; case 't' : case 'T' : CSISFieldRoot::SetBug (CSISFieldRoot::EBug32As64); break; case 'u' : case 'U' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugUnexpectedField); break; case 'v' : case 'V' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugInvalidValues); break; case 'x' : case 'X' : CSISFieldRoot::SetBug (CSISFieldRoot::EBugUnknownField); break; } wCharacter++; } } break; #endif // GENERATE_ERRORS case 'c' : case 'C' : { switch (argv [index][wCharacter+1]) { case 'd' : case 'D' : if (iAlgorithm != CSISSignatureAlgorithm::EAlgNone) { multi = true; break; } iAlgorithm = CSISSignatureAlgorithm::EAlgDSA; break; case 'r' : case 'R' : if (iAlgorithm != CSISSignatureAlgorithm::EAlgNone) { multi = true; break; } iAlgorithm = CSISSignatureAlgorithm::EAlgRSA; break; } wCharacter++; } break; case 'h' : case 'H' : case '?' : help = true; break; case 'i' : case 'I' : ssl = true; break; case 'o' : case 'O' : iReport = true; iSign = false; break; //EC023 additional prarameter added to extract the certificate case 'p' : case 'P' : iExtractCert = true; iSign = false; break; #ifdef GENERATE_ERRORS case 'q' : case 'Q' : CSISFieldRoot::SetBugStart (atoi(wstring2string (&argv [index] [wCharacter+1]).c_str ())); wCharacter++; break; case 'r' : case 'R' : CSISFieldRoot::SetBugRepeat (atoi (wstring2string (&argv [index] [wCharacter+1]).c_str ())); wCharacter++; break; #endif // GENERATE_ERRORS case 's' : case 'S' : iSign = true; break; case 'u' : case 'U' : iUnsign = true; iSign = false; break; case 'v' : case 'V' : iVerbose = true; break; case 'x' : case 'X' : { for (int offset = wCharacter+1; argv [index][offset]; offset++) { switch(argv[index][offset]) { case 'c' : case 'C' : CSISFieldRoot::SetDebugOption (CSISFieldRoot::EDbgControllerChecksum); break; case 'd' : case 'D' : CSISFieldRoot::SetDebugOption (CSISFieldRoot::EDbgDataChecksum); break; case 'w' : case 'W' : CSISFieldRoot::SetDebugOption (CSISFieldRoot::EDbgCompress); break; case 'x' : case 'X' : CSISFieldRoot::SetDebugOption (CSISFieldRoot::EDbgNoCompress); break; } wCharacter++; } } break; default : std::cout << "Unknown switch " << argv [index]; bien = false; break; } wCharacter++; } } else { switch (stage) { case 0 : iSISFileName = argv [index]; break; case 1 : iOutput = argv [index]; break; case 2 : iCertificate = argv [index]; break; case 3 : iKey = argv [index]; break; case 4 : iPassPhrase = argv [index]; break; default : if (bien) { std::cout << "Unexpected arguments from "; //<< std::string (argv [index]) << "." << std::endl; HANDLE hndl; DWORD bytesWritten; //Get command prompt handle hndl = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsole(hndl, argv [index], wcslen(argv [index]), &bytesWritten, 0); std::cout << "." << std::endl; bien = false; } break; } stage++; } } if (bien && ! iSign && ! iUnsign && ! iReport && !iExtractCert) { std::cout << "Nothing to do." << std::endl; bien = false; } if (bien && multi) { std::cout << "More than one signing algorithm specified." << std::endl; bien = false; } if (bien) { if (iSign && iUnsign) { std::cout << "Can't sign and unsign in single operation." << std::endl; bien = false; } else if (iSign || iUnsign || iReport || iExtractCert) { if (iSISFileName.empty ()) { std::cout << "Please name the input file." << std::endl; bien = false; } else if ((! iReport && iOutput.empty ())&& (! iExtractCert && iOutput.empty())) { std::cout << "Please name the output file." << std::endl; bien = false; } } } if (iVerbose) { ShowBanner (); } if (bien && ! iSign && ! iCertificate.empty ()) { std::cout << "A certificate is only used for signing a sis file." << std::endl; bien = false; } if (! bien && ! help) { std::cout << "Type \"" << "signsis" << " -?\" for command line options." << std::endl; } if (ssl) { for (int index = 0; index < (sizeof(openSSLLicenseString)/sizeof(openSSLLicenseString[0])); index++) std::cout << openSSLLicenseString [index] << std::endl; std::cout << std::endl; bien = false; } if (help) { std::cout << "Usage: SignSIS [-?] [-c...] [-i] [-o[-p]] [-s] [-u] [-v] input [output [certificate key [passphrase] ] ]" << std::endl << std::endl; std::cout << "-? or -h Output this information" << std::endl; std::cout << "-c... Sign using specific algorithm: -cd for DSA, -cr for RSA" << std::endl; std::cout << "-i Output licence information" << std::endl; std::cout << "-o Report on content of sis file (after any other operation)" << std::endl; std::cout << "-p Extracts the certificates present (This option has to be given along with -o option)"<< std::endl; std::cout << "-s Sign SIS file (requires sis file, certificate, key and passphrase)" << std::endl; std::cout << "-u Remove most recent signature from SIS file" << std::endl; std::cout << "-v Verbose output" << std::endl; std::cout << "input The SIS file to be sign, unsigned or investigated" << std::endl; std::cout << "output The SIS file generated by signing or unsigned" << std::endl; std::cout << "certificate The certificate file used for signing" << std::endl; std::cout << "key The certificate's private key file" << std::endl << std::endl; std::cout << "passphrase The certificate's private key file's passphrase" << std::endl << std::endl; std::cout << "You can sign or unsign a file in a single operation." << std::endl; std::cout << "You can generate SIS files using MakeSIS v5." << std::endl << std::endl; bien = false; } return bien; }