// Create a backup of the configuration file void BackupCfgWEx(CFG_RW *rw, FOLDER *f, wchar_t *original, UINT revision_number) { wchar_t dirname[MAX_PATH]; wchar_t filename[MAX_PATH]; wchar_t fullpath[MAX_PATH]; wchar_t datestr[MAX_PATH]; SYSTEMTIME st; // Validate arguments if (f == NULL || filename == NULL || rw == NULL) { return; } // Determine the directory name UniFormat(dirname, sizeof(dirname), L"@backup.%s", original[0] == L'@' ? original + 1 : original); // Determine the file name LocalTime(&st); UniFormat(datestr, sizeof(datestr), L"%04u%02u%02u%02u_%s", st.wYear, st.wMonth, st.wDay, st.wHour, original[0] == L'@' ? original + 1 : original); if (revision_number == INFINITE) { UniStrCpy(filename, sizeof(filename), datestr); } else { UniFormat(filename, sizeof(filename), L"%08u_%s", revision_number, original[0] == L'@' ? original + 1 : original); } // Don't save if the date and time has not been changed if (UniStrCmpi(datestr, rw->LastSavedDateStr) == 0) { return; } UniStrCpy(rw->LastSavedDateStr, sizeof(rw->LastSavedDateStr), datestr); // Check the existence of file name if (IsFileExistsW(filename)) { return; } // Create the directory MakeDirW(dirname); // Save the file UniFormat(fullpath, sizeof(fullpath), L"%s/%s", dirname, filename); CfgSaveW(f, fullpath); }
// Operation check of string library bool CheckStringLibrary() { wchar_t *compare_str = L"TEST_TEST_123_123456789012345"; char *teststr = "TEST"; wchar_t *testunistr = L"TEST"; wchar_t tmp[64]; UINT i1 = 123; UINT64 i2 = 123456789012345ULL; UniFormat(tmp, sizeof(tmp), L"%S_%s_%u_%I64u", teststr, testunistr, i1, i2); if (UniStrCmpi(tmp, compare_str) != 0) { return false; } return true; }
// main function int main(int argc, char *argv[]) { wchar_t *s; UINT ret = 0; #ifdef OS_WIN32 SetConsoleTitleA(CEDAR_PRODUCT_STR " VPN Command Line Utility"); #endif // OS_WIN32 InitMayaqua(false, false, argc, argv); InitCedar(); s = GetCommandLineUniStr(); if (s == NULL) { s = CopyUniStr(L""); } if (UniStrCmpi(s, L"exit") != 0) { UINT size = UniStrSize(s) + 64; wchar_t *tmp; tmp = Malloc(size); UniFormat(tmp, size, L"vpncmd %s", s); ret = CommandMain(tmp); Free(tmp); } #ifdef OS_WIN32 { UINT i; LIST *o = MsGetProcessList(); bool b = false; for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *p = LIST_DATA(o, i); if (EndWith(p->ExeFilename, "\\cmd.exe") || EndWith(p->ExeFilename, "\\command.com")) { b = true; break; } } MsFreeProcessList(o); if (b == false) { if (ret != ERR_NO_ERROR) { SleepThread(1000); } } } #endif // OS_WIN32 Free(s); FreeCedar(); FreeMayaqua(); return ret; }
// Certificate authentication of user bool SamAuthUserByCert(HUB *h, char *username, X *x) { bool b = false; // Validate arguments if (h == NULL || username == NULL || x == NULL) { return false; } if (GetGlobalServerFlag(GSF_DISABLE_CERT_AUTH) != 0) { return false; } // Check expiration date if (CheckXDateNow(x) == false) { return false; } // Check the Certification Revocation List if (IsValidCertInHub(h, x) == false) { // Bad wchar_t tmp[MAX_SIZE * 2]; // Log the contents of the certificate GetAllNameFromX(tmp, sizeof(tmp), x); HLog(h, "LH_AUTH_NG_CERT", username, tmp); return false; } AcLock(h); { USER *u; u = AcGetUser(h, username); if (u) { Lock(u->lock); { if (u->AuthType == AUTHTYPE_USERCERT) { // Check whether to matche with the registered certificate AUTHUSERCERT *auth = (AUTHUSERCERT *)u->AuthData; if (CompareX(auth->UserX, x)) { b = true; } } else if (u->AuthType == AUTHTYPE_ROOTCERT) { // Check whether the certificate has been signed by the root certificate AUTHROOTCERT *auth = (AUTHROOTCERT *)u->AuthData; if (h->HubDb != NULL) { LockList(h->HubDb->RootCertList); { X *root_cert; root_cert = GetIssuerFromList(h->HubDb->RootCertList, x); if (root_cert != NULL) { b = true; if (auth->CommonName != NULL && UniIsEmptyStr(auth->CommonName) == false) { // Compare the CN if (UniStrCmpi(x->subject_name->CommonName, auth->CommonName) != 0) { b = false; } } if (auth->Serial != NULL && auth->Serial->size >= 1) { // Compare the serial number if (CompareXSerial(x->serial, auth->Serial) == false) { b = false; } } } } UnlockList(h->HubDb->RootCertList); } } } Unlock(u->lock); ReleaseUser(u); } } AcUnlock(h); if (b) { wchar_t tmp[MAX_SIZE * 2]; // Log the contents of the certificate GetAllNameFromX(tmp, sizeof(tmp), x); HLog(h, "LH_AUTH_OK_CERT", username, tmp); } return b; }
wchar_t *ParseCommandEx(wchar_t *str, wchar_t *name, TOKEN_LIST **param_list) { UNI_TOKEN_LIST *t; UINT i; wchar_t *tmp; wchar_t *ret = NULL; LIST *o; // Validate arguments if (str == NULL) { return NULL; } if (name != NULL && UniIsEmptyStr(name)) { name = NULL; } o = NULL; if (param_list != NULL) { o = NewListFast(CompareStr); } tmp = CopyUniStr(str); UniTrim(tmp); i = UniSearchStrEx(tmp, L"/CMD ", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD\t", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD:", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD=", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD ", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD\t", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD:", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD=", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i != INFINITE) { char *s = CopyStr("CMD"); if (InsertStr(o, s) == false) { Free(s); } if (UniStrCmpi(name, L"CMD") == 0) { ret = CopyUniStr(&str[i + 5]); UniTrim(ret); } else { tmp[i] = 0; } } if (ret == NULL) { t = UniParseCmdLine(tmp); if (t != NULL) { for (i = 0;i < t->NumTokens;i++) { wchar_t *token = t->Token[i]; if ((token[0] == L'-' && token[1] != L'-') || (UniStrCmpi(token, L"--help") == 0) || (token[0] == L'/' && token[1] != L'/')) { UINT i; // Named parameter // Examine whether there is a colon character if (UniStrCmpi(token, L"--help") == 0) { token++; } i = UniSearchStrEx(token, L":", 0, false); if (i == INFINITE) { i = UniSearchStrEx(token, L"=", 0, false); } if (i != INFINITE) { wchar_t *tmp; char *a; // There is a colon character tmp = CopyUniStr(token); tmp[i] = 0; a = CopyUniToStr(&tmp[1]); if (InsertStr(o, a) == false) { Free(a); } if (UniStrCmpi(name, &tmp[1]) == 0) { if (ret == NULL) { // Content ret = UniCopyStr(&token[i + 1]); } } Free(tmp); } else { // There is no colon character char *a; a = CopyUniToStr(&token[1]); if (InsertStr(o, a) == false) { Free(a); } if (UniStrCmpi(name, &token[1]) == 0) { if (ret == NULL) { // Empty character ret = UniCopyStr(L""); } } } } else { // Nameless argument if (name == NULL) { if (ret == NULL) { if (token[0] == L'-' && token[1] == L'-') { ret = UniCopyStr(&token[1]); } else if (token[0] == L'/' && token[1] == L'/') { ret = UniCopyStr(&token[1]); } else { ret = UniCopyStr(token); } } } } } UniFreeToken(t); } } Free(tmp); if (o != NULL) { TOKEN_LIST *t = ZeroMalloc(sizeof(TOKEN_LIST)); UINT i; t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = LIST_DATA(o, i); } ReleaseList(o); *param_list = t; } if (UniStrCmpi(ret, L"none") == 0 || UniStrCmpi(ret, L"null") == 0) { // Null and none are reserved words ret[0] = 0; } return ret; }
// Parse the command list LIST *ParseCommandList(CONSOLE *c, char *cmd_name, wchar_t *command, PARAM param[], UINT num_param) { UINT i; LIST *o; bool ok = true; TOKEN_LIST *param_list; TOKEN_LIST *real_name_list; bool help_mode = false; wchar_t *tmp; // Validate arguments if (c == NULL || command == NULL || (num_param >= 1 && param == NULL) || cmd_name == NULL) { return NULL; } // Initialization for (i = 0;i < num_param;i++) { if (IsEmptyStr(param[i].Name) == false) { if (param[i].Name[0] == '[') { param[i].Tmp = ""; } else { param[i].Tmp = NULL; } } else { param[i].Tmp = ""; } } real_name_list = ZeroMalloc(sizeof(TOKEN_LIST)); real_name_list->NumTokens = num_param; real_name_list->Token = ZeroMalloc(sizeof(char *) * real_name_list->NumTokens); for (i = 0;i < real_name_list->NumTokens;i++) { real_name_list->Token[i] = CopyStr(param[i].Name); } // Generate a list of parameter name specified by the user param_list = GetCommandNameList(command); for (i = 0;i < param_list->NumTokens;i++) { char *s = param_list->Token[i]; if (StrCmpi(s, "help") == 0 || StrCmpi(s, "?") == 0) { help_mode = true; break; } } tmp = ParseCommand(command, L""); if (tmp != NULL) { if (UniStrCmpi(tmp, L"?") == 0) { help_mode = true; } Free(tmp); } if (help_mode) { // Show the help PrintCmdHelp(c, cmd_name, real_name_list); FreeToken(param_list); FreeToken(real_name_list); return NULL; } for (i = 0;i < param_list->NumTokens;i++) { // Get the corresponding commands for all parameter names which is specified by the user TOKEN_LIST *candidate = GetRealnameCandidate(param_list->Token[i], real_name_list); if (candidate != NULL && candidate->NumTokens >= 1) { if (candidate->NumTokens >= 2) { wchar_t tmp[MAX_SIZE]; // There is more than one candidate UniFormat(tmp, sizeof(tmp), _UU("CON_AMBIGIOUS_PARAM"), param_list->Token[i]); c->Write(c, tmp); UniFormat(tmp, sizeof(tmp), _UU("CON_AMBIGIOUS_PARAM_1"), cmd_name); c->Write(c, tmp); PrintCandidateHelp(c, cmd_name, candidate, 1); c->Write(c, _UU("CON_AMBIGIOUS_PARAM_2")); ok = false; } else { UINT j; char *real_name = candidate->Token[0]; // There is only one candidate for (j = 0;j < num_param;j++) { if (StrCmpi(param[j].Name, real_name) == 0) { param[j].Tmp = param_list->Token[i]; } } } } else { wchar_t tmp[MAX_SIZE]; // No candidate UniFormat(tmp, sizeof(tmp), _UU("CON_INVALID_PARAM"), param_list->Token[i], cmd_name, cmd_name); c->Write(c, tmp); ok = false; } FreeToken(candidate); } if (ok == false) { FreeToken(param_list); FreeToken(real_name_list); return NULL; } // Creating a list o = NewParamValueList(); // Read all the parameters of the specified name in the parameter list for (i = 0;i < num_param;i++) { bool prompt_input_value = false; PARAM *p = ¶m[i]; if (p->Tmp != NULL || p->PromptProc != NULL) { wchar_t *name = CopyStrToUni(p->Name); wchar_t *tmp; wchar_t *str; if (p->Tmp != NULL) { tmp = CopyStrToUni(p->Tmp); } else { tmp = CopyStrToUni(p->Name); } str = ParseCommand(command, tmp); Free(tmp); if (str != NULL) { wchar_t *unistr; bool ret; EVAL_VALUE: // Reading succeeded unistr = str; if (p->EvalProc != NULL) { // Evaluate the value if EvalProc is specified ret = p->EvalProc(c, unistr, p->EvalProcParam); } else { // Accept any value if EvalProc is not specified ret = true; } if (ret == false) { // The specified value is invalid if (p->PromptProc == NULL) { // Cancel ok = false; Free(name); Free(str); break; } else if (c->ProgrammingMode) { // In the programming mode, return the error immediately. ok = false; Free(name); Free(str); break; } else { // Request to re-enter Free(str); str = NULL; goto SHOW_PROMPT; } } else { PARAM_VALUE *v; // Finished loading, add it to the list v = ZeroMalloc(sizeof(PARAM_VALUE)); v->Name = CopyStr(p->Name); v->StrValue = CopyUniToStr(str); v->UniStrValue = CopyUniStr(str); v->IntValue = ToInt(v->StrValue); Insert(o, v); } } else { // Failed to read. The parameter is not specified if (p->PromptProc != NULL) { wchar_t *tmp; SHOW_PROMPT: // Prompt because it is a mandatory parameter tmp = NULL; if (c->ProgrammingMode == false) { tmp = p->PromptProc(c, p->PromptProcParam); } if (tmp == NULL) { // User canceled ok = false; Free(str); Free(name); break; } else { // Entered by the user c->Write(c, L""); str = tmp; prompt_input_value = true; goto EVAL_VALUE; } } } Free(str); Free(name); } } FreeToken(param_list); FreeToken(real_name_list); if (ok) { return o; } else { FreeParamValueList(o); return NULL; } }
// main function int main(int argc, char *argv[]) { wchar_t *s; UINT ret = 0; InitProcessCallOnce(); #ifdef OS_WIN32 SetConsoleTitleA(CEDAR_PRODUCT_STR " VPN Command Line Utility"); #else // For *nix, disable output buffering to allow for interactive use setbuf(stdout,NULL); #endif // OS_WIN32 #if defined(_DEBUG) || defined(DEBUG) // In VC++ compilers, the macro is "_DEBUG", not "DEBUG". // If set memcheck = true, the program will be vitally slow since it will log all malloc() / realloc() / free() calls to find the cause of memory leak. // For normal debug we set memcheck = false. // Please set memcheck = true if you want to test the cause of memory leaks. InitMayaqua(false, true, argc, argv); #else InitMayaqua(false, false, argc, argv); #endif InitCedar(); s = GetCommandLineUniStr(); if (s == NULL) { s = CopyUniStr(L""); } if (UniStrCmpi(s, L"exit") != 0) { UINT size = UniStrSize(s) + 64; wchar_t *tmp; tmp = Malloc(size); UniFormat(tmp, size, L"vpncmd %s", s); ret = CommandMain(tmp); Free(tmp); } #ifdef OS_WIN32 { UINT i; LIST *o = MsGetProcessList(); bool b = false; for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *p = LIST_DATA(o, i); if (EndWith(p->ExeFilename, "\\cmd.exe") || EndWith(p->ExeFilename, "\\command.com")) { b = true; break; } } MsFreeProcessList(o); if (b == false) { if (ret != ERR_NO_ERROR) { SleepThread(1000); } } } #endif // OS_WIN32 Free(s); FreeCedar(); FreeMayaqua(); return ret; }
// Read the string table bool LoadTableMain(wchar_t *filename) { BUF *b; UINT64 t1, t2; UCHAR hash[MD5_SIZE]; // Validate arguments if (filename == NULL) { return false; } if (MayaquaIsMinimalMode()) { return true; } if (UniStrCmpi(old_table_name, filename) == 0) { // Already loaded return true; } t1 = Tick64(); // Open the file b = ReadDumpW(filename); if (b == NULL) { char tmp[MAX_SIZE]; StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (file not found).\r\nPlease check hamcore.se2.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)"); Alert(tmp, NULL); exit(-1); return false; } Hash(hash, b->Buf, b->Size, false); if (LoadUnicodeCache(filename, b->Size, hash) == false) { if (LoadTableFromBuf(b) == false) { FreeBuf(b); return false; } SaveUnicodeCache(filename, b->Size, hash); //Debug("Unicode Source: strtable.stb\n"); } else { //Debug("Unicode Source: unicode_cache\n"); } FreeBuf(b); SetLocale(_UU("DEFAULE_LOCALE")); UniStrCpy(old_table_name, sizeof(old_table_name), filename); t2 = Tick64(); if (StrCmpi(_SS("STRTABLE_ID"), STRTABLE_ID) != 0) { char tmp[MAX_SIZE]; Format(tmp, sizeof(tmp), "Error: Can't read string tables (invalid version: '%s'!='%s').\r\nPlease check hamcore.se2.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)", _SS("STRTABLE_ID"), STRTABLE_ID); Alert(tmp, NULL); exit(-1); return false; } //Debug("Unicode File Read Cost: %u (%u Lines)\n", (UINT)(t2 - t1), LIST_NUM(TableList)); return true; }