Exemple #1
0
// Create new user object
USER *NewUser(char *name, wchar_t *realname, wchar_t *note, UINT authtype, void *authdata)
{
	USER *u;
	// Validate arguments
	if (name == NULL || realname == NULL || note == NULL)
	{
		return NULL;
	}
	if (authtype != AUTHTYPE_ANONYMOUS && authdata == NULL)
	{
		return NULL;
	}

	u = ZeroMalloc(sizeof(USER));
	u->lock = NewLock();
	u->ref = NewRef();
	u->Name = CopyStr(name);
	u->RealName = CopyUniStr(realname);
	u->Note = CopyUniStr(note);
	u->GroupName = NULL;
	u->Group = NULL;
	u->AuthType = authtype;
	u->AuthData = authdata;
	u->CreatedTime = SystemTime64();
	u->UpdatedTime = SystemTime64();

	u->Policy = NULL;
	u->Traffic = NewTraffic();

	return u;
}
Exemple #2
0
CFG_RW *NewCfgRwEx2W(FOLDER **root, wchar_t *cfg_name, bool dont_backup, wchar_t *template_name)
{
	CFG_RW *rw;
	FOLDER *f;
	bool loaded_from_template = false;
	// Validate arguments
	if (cfg_name == NULL || root == NULL)
	{
		return NULL;
	}

	f = CfgReadW(cfg_name);
	if (f == NULL)
	{
		// Load from template
		if (UniIsEmptyStr(template_name) == false)
		{
			f = CfgReadW(template_name);
			if (f != NULL)
			{
				loaded_from_template = true;

				goto LABEL_CONTIUNE;
			}
		}

		rw = ZeroMalloc(sizeof(CFG_RW));
		rw->lock = NewLock();
		rw->FileNameW = CopyUniStr(cfg_name);
		rw->FileName = CopyUniToStr(cfg_name);
		rw->Io = FileCreateW(cfg_name);
		*root = NULL;
		rw->DontBackup = dont_backup;

		return rw;
	}

LABEL_CONTIUNE:
	rw = ZeroMalloc(sizeof(CFG_RW));
	rw->FileNameW = CopyUniStr(cfg_name);
	rw->FileName = CopyUniToStr(cfg_name);
	if (loaded_from_template == false)
	{
		rw->Io = FileOpenW(cfg_name, false);
	}
	else
	{
		rw->Io = FileCreateW(cfg_name);
	}
	rw->lock = NewLock();

	*root = f;

	rw->DontBackup = dont_backup;

	return rw;
}
// Reading a string resource
wchar_t *ViLoadString(HINSTANCE hInst, UINT id)
{
	wchar_t *ret = NULL;

	if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType))
	{
		char *a = ViLoadStringA(hInst, id);
		if (a != NULL)
		{
			ret = CopyStrToUni(a);
			Free(a);
		}
	}
	else
	{
		UINT tmp_size = 60000;
		wchar_t *tmp = Malloc(tmp_size);

		if (LoadStringW(hInst, id, tmp, tmp_size) != 0)
		{
			ret = CopyUniStr(tmp);
		}

		Free(tmp);
	}

	return ret;
}
Exemple #4
0
// Clone authentication data
void *CopyAuthData(void *authdata, UINT authtype)
{
	AUTHPASSWORD *pw = (AUTHPASSWORD *)authdata;
	AUTHUSERCERT *usercert = (AUTHUSERCERT *)authdata;
	AUTHROOTCERT *rootcert = (AUTHROOTCERT *)authdata;
	AUTHRADIUS *radius = (AUTHRADIUS *)authdata;
	AUTHNT *nt = (AUTHNT *)authdata;
	// Validate arguments
	if (authdata == NULL || authtype == AUTHTYPE_ANONYMOUS)
	{
		return NULL;
	}

	switch (authtype)
	{
	case AUTHTYPE_PASSWORD:
		{
			AUTHPASSWORD *ret = ZeroMalloc(sizeof(AUTHPASSWORD));
			Copy(ret, pw, sizeof(AUTHPASSWORD));
			return ret;
		}
		break;

	case AUTHTYPE_USERCERT:
		{
			AUTHUSERCERT *ret = ZeroMalloc(sizeof(AUTHUSERCERT));
			ret->UserX = CloneX(usercert->UserX);
			return ret;
		}
		break;

	case AUTHTYPE_ROOTCERT:
		{
			AUTHROOTCERT *ret = ZeroMalloc(sizeof(AUTHROOTCERT));
			ret->CommonName = CopyUniStr(rootcert->CommonName);
			ret->Serial = CloneXSerial(rootcert->Serial);
			return ret;
		}
		break;

	case AUTHTYPE_RADIUS:
		{
			AUTHRADIUS *ret = ZeroMalloc(sizeof(AUTHRADIUS));
			ret->RadiusUsername = UniCopyStr(radius->RadiusUsername);
			return ret;
		}
		break;

	case AUTHTYPE_NT:
		{
			AUTHNT *ret = ZeroMalloc(sizeof(AUTHNT));
			ret->NtUsername = UniCopyStr(nt->NtUsername);
			return ret;
		}
		break;
	}

	return NULL;
}
Exemple #5
0
// Create a Radius authentication data
void *NewRadiusAuthData(wchar_t *username)
{
	AUTHRADIUS *a;
	// Validate arguments
	a = ZeroMallocEx(sizeof(AUTHRADIUS), true);
	a->RadiusUsername = CopyUniStr(username);

	return a;
}
Exemple #6
0
// Create a NT authentication data
void *NewNTAuthData(wchar_t *username)
{
	AUTHNT *a;
	// Validate arguments
	a = ZeroMallocEx(sizeof(AUTHNT), true);
	a->NtUsername = CopyUniStr(username);

	return a;
}
Exemple #7
0
// Create new group object
USERGROUP *NewGroup(char *name, wchar_t *realname, wchar_t *note)
{
	USERGROUP *g;
	// Validate arguments
	if (name == NULL || realname == NULL || note == NULL)
	{
		return NULL;
	}

	g = ZeroMalloc(sizeof(USERGROUP));
	g->lock = NewLock();
	g->ref = NewRef();
	g->Name = CopyStr(name);
	g->RealName = CopyUniStr(realname);
	g->Note = CopyUniStr(note);
	g->Policy = NULL;
	g->Traffic = NewTraffic();

	return g;
}
wchar_t *FolderDlgInnerW(HWND hWnd, wchar_t *title, wchar_t *default_dir)
{
	BROWSEINFOW info;
	wchar_t display_name[MAX_PATH];
	FOLDER_DLG_INNER_DATA data;
	LPMALLOC pMalloc;
	wchar_t *ret = NULL;
	if (UniIsEmptyStr(title))
	{
		title = NULL;
	}
	if (UniIsEmptyStr(default_dir))
	{
		default_dir = NULL;
	}

	Zero(&data, sizeof(data));
	data.default_dir = default_dir;

	Zero(display_name, sizeof(display_name));
	Zero(&info, sizeof(info));
	info.hwndOwner = hWnd;
	info.pidlRoot = NULL;
	info.pszDisplayName = display_name;
	info.lpszTitle = title;
	info.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_SHAREABLE;
	info.lpfn = FolderDlgInnerCallbackW;
	info.lParam = (LPARAM)&data;

	if (SUCCEEDED(SHGetMalloc(&pMalloc)))
	{
		LPITEMIDLIST pidl;

		pidl = SHBrowseForFolderW(&info);

		if (pidl)
		{
			wchar_t tmp[MAX_PATH];

			if (SHGetPathFromIDListW(pidl, tmp))
			{
				ret = CopyUniStr(tmp);
			}

			pMalloc->Free(pidl);
		}

		pMalloc->Release();
	}

	return ret;
}
Exemple #9
0
// Create a root certification authentication data
void *NewRootCertAuthData(X_SERIAL *serial, wchar_t *common_name)
{
	AUTHROOTCERT *a;

	a = ZeroMallocEx(sizeof(AUTHROOTCERT), true);
	if (common_name != NULL && UniIsEmptyStr(common_name) == false)
	{
		a->CommonName = CopyUniStr(common_name);
	}
	if (serial != NULL && serial->size >= 1)
	{
		a->Serial = CloneXSerial(serial);
	}

	return a;
}
Exemple #10
0
// Plaintext password authentication of user
bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *password, bool ast, UCHAR *mschap_v2_server_response_20, RADIUS_LOGIN_OPTION *opt)
{
	bool b = false;
	wchar_t *name = NULL;
	bool auth_by_nt = false;
	HUB *h;
	// Validate arguments
	if (hub == NULL || c == NULL || username == NULL)
	{
		return false;
	}

	if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
	{
		return false;
	}

	h = hub;

	AddRef(h->ref);

	// Get the user name on authentication system
	AcLock(hub);
	{
		USER *u;
		u = AcGetUser(hub, ast == false ? username : "******");
		if (u)
		{
			Lock(u->lock);
			{
				if (u->AuthType == AUTHTYPE_RADIUS)
				{
					// Radius authentication
					AUTHRADIUS *auth = (AUTHRADIUS *)u->AuthData;
					if (ast || auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
					{
						name = CopyStrToUni(username);
					}
					else
					{
						name = CopyUniStr(auth->RadiusUsername);
					}
					auth_by_nt = false;
				}
				else if (u->AuthType == AUTHTYPE_NT)
				{
					// NT authentication
					AUTHNT *auth = (AUTHNT *)u->AuthData;
					if (ast || auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
					{
						name = CopyStrToUni(username);
					}
					else
					{
						name = CopyUniStr(auth->NtUsername);
					}
					auth_by_nt = true;
				}
			}
			Unlock(u->lock);
			ReleaseUser(u);
		}
	}
	AcUnlock(hub);

	if (name != NULL)
	{
		if (auth_by_nt == false)
		{
			// Radius authentication
			char radius_server_addr[MAX_SIZE];
			UINT radius_server_port;
			char radius_secret[MAX_SIZE];
			char suffix_filter[MAX_SIZE];
			wchar_t suffix_filter_w[MAX_SIZE];
			UINT interval;

			Zero(suffix_filter, sizeof(suffix_filter));
			Zero(suffix_filter_w, sizeof(suffix_filter_w));

			// Get the Radius server information
			if (GetRadiusServerEx2(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, suffix_filter, sizeof(suffix_filter)))
			{
				Unlock(hub->lock);

				StrToUni(suffix_filter_w, sizeof(suffix_filter_w), suffix_filter);

				if (UniIsEmptyStr(suffix_filter_w) || UniEndWith(name, suffix_filter_w))
				{
					// Attempt to login
					b = RadiusLogin(c, radius_server_addr, radius_server_port,
						radius_secret, StrLen(radius_secret),
						name, password, interval, mschap_v2_server_response_20, opt);
				}

				Lock(hub->lock);
			}
			else
			{
				HLog(hub, "LH_NO_RADIUS_SETTING", name);
			}
		}
		else
		{
			// NT authentication (Not available for non-Win32)
#ifdef	OS_WIN32
			IPC_MSCHAP_V2_AUTHINFO mschap;
			Unlock(hub->lock);

			if (ParseAndExtractMsChapV2InfoFromPassword(&mschap, password) == false)
			{
				// Plaintext password authentication
				b = MsCheckLogon(name, password);
			}
			else
			{
				UCHAR challenge8[8];
				UCHAR nt_pw_hash_hash[16];
				char nt_name[MAX_SIZE];

				UniToStr(nt_name, sizeof(nt_name), name);

				// MS-CHAPv2 authentication
				MsChapV2_GenerateChallenge8(challenge8, mschap.MsChapV2_ClientChallenge,
					mschap.MsChapV2_ServerChallenge,
					mschap.MsChapV2_PPPUsername);

				Debug("MsChapV2_PPPUsername = %s, nt_name = %s\n", mschap.MsChapV2_PPPUsername, nt_name);

				b = MsPerformMsChapV2AuthByLsa(nt_name, challenge8, mschap.MsChapV2_ClientResponse, nt_pw_hash_hash);

				if (b)
				{
					if (mschap_v2_server_response_20 != NULL)
					{
						MsChapV2Server_GenerateResponse(mschap_v2_server_response_20, nt_pw_hash_hash,
							mschap.MsChapV2_ClientResponse, challenge8);
					}
				}
			}

			Lock(hub->lock);
#else	// OS_WIN32
			// Nothing to do other than Win32
#endif	// OS_WIN32
		}

		// Memory release
		Free(name);
	}

	ReleaseHub(h);

	return b;
}
Exemple #11
0
// Interpret a line
TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size, LIST *replace_list)
{
	UINT i, len;
	UINT len_name;
	UINT string_start;
	char *name;
	char *name2;
	UINT name2_size;
	wchar_t *unistr;
	char *str;
	UINT unistr_size, str_size;
	TABLE *t;
	// Validate arguments
	if (line == NULL || prefix == NULL)
	{
		return NULL;
	}
	TrimLeft(line);

	// No line
	len = StrLen(line);
	if (len == 0)
	{
		return NULL;
	}

	// Comment
	if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
	{
		return NULL;
	}

	// Search to the end position of the name
	len_name = 0;
	for (i = 0;;i++)
	{
		if (line[i] == 0)
		{
			// There is only one token
			return NULL;
		}
		if (line[i] == ' ' || line[i] == '\t')
		{
			break;
		}
		len_name++;
	}

	name = Malloc(len_name + 1);
	StrCpy(name, len_name + 1, line);

	string_start = len_name;
	for (i = len_name;i < len;i++)
	{
		if (line[i] != ' ' && line[i] != '\t')
		{
			break;
		}
		string_start++;
	}
	if (i == len)
	{
		Free(name);
		return NULL;
	}

	// Unescape
	UnescapeStr(&line[string_start]);

	// Convert to Unicode
	unistr_size = CalcUtf8ToUni(&line[string_start], StrLen(&line[string_start]));
	if (unistr_size == 0)
	{
		Free(name);
		return NULL;
	}
	unistr = Malloc(unistr_size);
	Utf8ToUni(unistr, unistr_size, &line[string_start], StrLen(&line[string_start]));

	if (UniInChar(unistr, L'$'))
	{
		// Replace the replacement string
		wchar_t *tmp;
		UINT tmp_size = (UniStrSize(unistr) + 1024) * 2;
		UINT i;

		tmp = Malloc(tmp_size);

		UniStrCpy(tmp, tmp_size, unistr);

		for (i = 0; i < LIST_NUM(replace_list);i++)
		{
			TABLE *r = LIST_DATA(replace_list, i);

			UniReplaceStrEx(tmp, tmp_size, tmp, (wchar_t *)r->name, r->unistr, false);
		}

		unistr = CopyUniStr(tmp);

		Free(tmp);
	}

	// Convert to ANSI
	str_size = CalcUniToStr(unistr);
	if (str_size == 0)
	{
		str_size = 1;
		str = Malloc(1);
		str[0] = 0;
	}
	else
	{
		str = Malloc(str_size);
		UniToStr(str, str_size, unistr);
	}

	if (StrCmpi(name, "PREFIX") == 0)
	{
		// Prefix is specified
		StrCpy(prefix, prefix_size, str);
		Trim(prefix);

		if (StrCmpi(prefix, "$") == 0 || StrCmpi(prefix, "NULL") == 0)
		{
			prefix[0] = 0;
		}

		Free(name);
		Free(str);
		Free(unistr);

		return NULL;
	}

	name2_size = StrLen(name) + StrLen(prefix) + 2;
	name2 = ZeroMalloc(name2_size);

	if (prefix[0] != 0)
	{
		StrCat(name2, name2_size, prefix);
		StrCat(name2, name2_size, "@");
	}

	StrCat(name2, name2_size, name);

	Free(name);

	// Create a TABLE
	t = Malloc(sizeof(TABLE));
	StrUpper(name2);
	t->name = name2;
	t->str = str;
	t->unistr = unistr;

	return t;
}
bool DispatchNextCmdEx(CONSOLE *c, wchar_t *exec_command, char *prompt, CMD cmd[], UINT num_cmd, void *param)
{
	wchar_t *str;
	wchar_t *tmp;
	char *cmd_name;
	bool b_exit = false;
	wchar_t *cmd_param;
	UINT ret = ERR_NO_ERROR;
	TOKEN_LIST *t;
	TOKEN_LIST *candidate;
	bool no_end_crlf = false;
	UINT i;
	// Validate arguments
	if (c == NULL || (num_cmd >= 1 && cmd == NULL))
	{
		return false;
	}

	if (exec_command == NULL)
	{
		// Show the prompt
RETRY:
		tmp = CopyStrToUni(prompt);

		if (c->ProgrammingMode)
		{
			wchar_t tmp2[MAX_PATH];

			UniFormat(tmp2, sizeof(tmp2), L"[PROMPT:%u:%s]\r\n", c->RetCode, tmp);

			Free(tmp);

			tmp = CopyUniStr(tmp2);
		}

		str = c->ReadLine(c, tmp, false);
		Free(tmp);

		if (str != NULL && IsEmptyUniStr(str))
		{
			Free(str);
			goto RETRY;
		}
	}
	else
	{
		wchar_t tmp[MAX_SIZE];
		// Use exec_command
		if (UniStartWith(exec_command, L"vpncmd") == false)
		{
			if (prompt != NULL)
			{
				if (c->ConsoleType != CONSOLE_CSV)
				{
					UniFormat(tmp, sizeof(tmp), L"%S%s", prompt, exec_command);
					c->Write(c, tmp);
				}
			}
		}
		str = CopyUniStr(exec_command);
	}

	if (str == NULL)
	{
		// User canceled
		return false;
	}

	UniTrimCrlf(str);
	UniTrim(str);

	if (UniIsEmptyStr(str))
	{
		// Do Nothing
		Free(str);
		return true;
	}

	// Divide into command name and parameter
	if (SeparateCommandAndParam(str, &cmd_name, &cmd_param) == false)
	{
		// Do Nothing
		Free(str);
		return true;
	}

	if (StrLen(cmd_name) >= 2 && cmd_name[0] == '?' && cmd_name[1] != '?')
	{
		char tmp[MAX_SIZE];
		wchar_t *s;

		StrCpy(tmp, sizeof(tmp), cmd_name + 1);
		StrCpy(cmd_name, 0, tmp);

		s = UniCopyStr(L"/?");
		Free(cmd_param);

		cmd_param = s;
	}

	if (StrLen(cmd_name) >= 2 && EndWith(cmd_name, "?") && cmd_name[StrLen(cmd_name) - 2] != '?')
	{
		wchar_t *s;

		cmd_name[StrLen(cmd_name) - 1] = 0;

		s = UniCopyStr(L"/?");
		Free(cmd_param);

		cmd_param = s;
	}

	// Get the candidate of command
	t = ZeroMalloc(sizeof(TOKEN_LIST));
	t->NumTokens = num_cmd;
	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
	for (i = 0;i < t->NumTokens;i++)
	{
		t->Token[i] = CopyStr(cmd[i].Name);
	}

	if (IsHelpStr(cmd_name))
	{
		if (UniIsEmptyStr(cmd_param))
		{
			wchar_t tmp[MAX_SIZE];

			// Display the list of commands that can be used
			UniFormat(tmp, sizeof(tmp), _UU("CMD_HELP_1"), t->NumTokens);
			c->Write(c, tmp);

			PrintCandidateHelp(c, NULL, t, 1);

			c->Write(c, L"");
			c->Write(c, _UU("CMD_HELP_2"));
		}
		else
		{
			char *cmd_name;

			// Display the help for the specified command
			if (SeparateCommandAndParam(cmd_param, &cmd_name, NULL))
			{
				bool b = true;

				if (IsHelpStr(cmd_name))
				{
					b = false;
				}

				if (b)
				{
					wchar_t str[MAX_SIZE];

					UniFormat(str, sizeof(str), L"%S /help", cmd_name);
					DispatchNextCmdEx(c, str, NULL, cmd, num_cmd, param);
					no_end_crlf = true;
				}

				Free(cmd_name);
			}
		}
	}
	else if (StrCmpi(cmd_name, "exit") == 0 || StrCmpi(cmd_name, "quit") == 0)
	{
		// Exit
		b_exit = true;
	}
	else
	{
		candidate = GetRealnameCandidate(cmd_name, t);

		if (candidate == NULL || candidate->NumTokens == 0)
		{
			wchar_t tmp[MAX_SIZE];

			// No candidate
			UniFormat(tmp, sizeof(tmp), _UU("CON_UNKNOWN_CMD"), cmd_name);
			c->Write(c, tmp);

			c->RetCode = ERR_BAD_COMMAND_OR_PARAM;
		}
		else if (candidate->NumTokens >= 2)
		{
			wchar_t tmp[MAX_SIZE];

			// There is more than one candidate
			UniFormat(tmp, sizeof(tmp), _UU("CON_AMBIGIOUS_CMD"), cmd_name);
			c->Write(c, tmp);
			c->Write(c, _UU("CON_AMBIGIOUS_CMD_1"));
			PrintCandidateHelp(c, NULL, candidate, 1);
			c->Write(c, _UU("CON_AMBIGIOUS_CMD_2"));

			c->RetCode = ERR_BAD_COMMAND_OR_PARAM;
		}
		else
		{
			char *real_cmd_name;
			UINT i;

			// The candidate was shortlisted to one
			real_cmd_name = candidate->Token[0];

			for (i = 0;i < num_cmd;i++)
			{
				if (StrCmpi(cmd[i].Name, real_cmd_name) == 0)
				{
					if (cmd[i].Proc != NULL)
					{
						// Show the description of the command if it isn't in CSV mode
						if(c->ConsoleType != CONSOLE_CSV)
						{
							wchar_t tmp[256];
							wchar_t *note;

							GetCommandHelpStr(cmd[i].Name, &note, NULL, NULL);
							UniFormat(tmp, sizeof(tmp), _UU("CMD_EXEC_MSG_NAME"), cmd[i].Name, note);
							c->Write(c, tmp);
						}

						// Call the procedure of the command
						ret = cmd[i].Proc(c, cmd[i].Name, cmd_param, param);

						if (ret == INFINITE)
						{
							// Exit command
							b_exit = true;
						}
						else
						{
							c->RetCode = ret;
						}
					}
				}
			}
		}

		FreeToken(candidate);
	}

	FreeToken(t);
	Free(str);
	Free(cmd_name);
	Free(cmd_param);

	if (no_end_crlf == false)
	{
		//c->Write(c, L"");
	}

	if (b_exit)
	{
		return false;
	}

	return true;
}
// Split a string into specified width
UNI_TOKEN_LIST *SeparateStringByWidth(wchar_t *str, UINT width)
{
	UINT wp;
	wchar_t *tmp;
	UINT len, i;
	LIST *o;
	UNI_TOKEN_LIST *ret;
	// Validate arguments
	if (str == NULL)
	{
		return UniNullToken();
	}
	if (width == 0)
	{
		width = 1;
	}

	o = NewListFast(NULL);

	len = UniStrLen(str);
	tmp = ZeroMalloc(sizeof(wchar_t) * (len + 32));
	wp = 0;

	for (i = 0;i < (len + 1);i++)
	{
		wchar_t c = str[i];
		UINT next_word_width;
		UINT remain_width;

		switch (c)
		{
		case 0:
		case L'\r':
		case L'\n':
			if (c == L'\r')
			{
				if (str[i + 1] == L'\n')
				{
					i++;
				}
			}

			tmp[wp++] = 0;
			wp = 0;

			Insert(o, UniCopyStr(tmp));
			break;

		default:
			next_word_width = GetNextWordWidth(&str[i]);
			remain_width = (width - UniStrWidth(tmp));

			if ((remain_width >= 1) && (next_word_width > remain_width) && (next_word_width <= width))
			{
				tmp[wp++] = 0;
				wp = 0;

				Insert(o, UniCopyStr(tmp));
			}

			tmp[wp++] = c;
			tmp[wp] = 0;
			if (UniStrWidth(tmp) >= width)
			{
				tmp[wp++] = 0;
				wp = 0;

				Insert(o, UniCopyStr(tmp));
			}
			break;
		}
	}

	if (LIST_NUM(o) == 0)
	{
		Insert(o, CopyUniStr(L""));
	}

	ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
	ret->NumTokens = LIST_NUM(o);
	ret->Token = ZeroMalloc(sizeof(wchar_t *) * ret->NumTokens);

	for (i = 0;i < LIST_NUM(o);i++)
	{
		wchar_t *s = LIST_DATA(o, i);

		UniTrimLeft(s);

		ret->Token[i] = s;
	}

	ReleaseList(o);
	Free(tmp);

	return ret;
}
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 = &param[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;
	}
}
// Separate the command line into the command and the parameters
bool SeparateCommandAndParam(wchar_t *src, char **cmd, wchar_t **param)
{
	UINT i, len, wp;
	wchar_t *tmp;
	wchar_t *src_tmp;
	// Validate arguments
	if (src == NULL)
	{
		return false;
	}
	if (cmd != NULL)
	{
		*cmd = NULL;
	}
	if (param != NULL)
	{
		*param = NULL;
	}

	src_tmp = UniCopyStr(src);
	UniTrimCrlf(src_tmp);
	UniTrim(src_tmp);

	len = UniStrLen(src_tmp);
	tmp = Malloc(sizeof(wchar_t) * (len + 32));
	wp = 0;

	for (i = 0;i < (len + 1);i++)
	{
		wchar_t c = src_tmp[i];

		switch (c)
		{
		case 0:
		case L' ':
		case L'\t':
			tmp[wp] = 0;
			if (UniIsEmptyStr(tmp))
			{
				Free(tmp);
				Free(src_tmp);
				return false;
			}
			if (cmd != NULL)
			{
				*cmd = CopyUniToStr(tmp);
				Trim(*cmd);
			}
			goto ESCAPE;

		default:
			tmp[wp++] = c;
			break;
		}
	}

ESCAPE:
	if (param != NULL)
	{
		*param = CopyUniStr(&src_tmp[wp]);
		UniTrim(*param);
	}

	Free(tmp);
	Free(src_tmp);

	return true;
}
Exemple #17
0
// 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;
}
Exemple #18
0
// 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;
}
Exemple #19
0
// Read a string table from the buffer
bool LoadTableFromBuf(BUF *b)
{
	char *tmp;
	char prefix[MAX_SIZE];
	LIST *replace_list = NULL;
	UINT i;
	// Validate arguments
	if (b == NULL)
	{
		return false;
	}

	// If the table already exists, delete it
	FreeTable();

	// Create a list
	TableList = NewList(CmpTableName);

	Zero(prefix, sizeof(prefix));

	replace_list = NewListFast(NULL);

	// Read the contents of the buffer line by line
	while (true)
	{
		TABLE *t;
		bool ok = true;

		tmp = CfgReadNextLine(b);
		if (tmp == NULL)
		{
			break;
		}

		if (tmp[0] == '$')
		{
			char key[128];
			char value[MAX_SIZE];
			if (GetKeyAndValue(tmp, key, sizeof(key), value, sizeof(value), " \t"))
			{
				if (StartWith(key, "$") && EndWith(key, "$") && StrLen(key) >= 3)
				{
					TABLE *t;
					wchar_t univalue[MAX_SIZE];
					wchar_t uniname[MAX_SIZE];

					t = ZeroMalloc(sizeof(TABLE));

					Zero(univalue, sizeof(univalue));
					Utf8ToUni(univalue, sizeof(univalue), value, StrLen(value));

					StrToUni(uniname, sizeof(uniname), key);

					t->name = (char *)CopyUniStr(uniname);
					t->unistr = CopyUniStr(univalue);

					Add(replace_list, t);

					// Found a replacement definition
					ok = false;
				}
			}
		}

		if (ok)
		{
			t = ParseTableLine(tmp, prefix, sizeof(prefix), replace_list);
			if (t != NULL)
			{
				// Register
				Insert(TableList, t);
			}
		}

		Free(tmp);
	}

	for (i = 0;i < LIST_NUM(replace_list);i++)
	{
		TABLE *t = LIST_DATA(replace_list, i);

		Free(t->name);
		Free(t->str);
		Free(t->unistr);

		Free(t);
	}

	ReleaseList(replace_list);

	return true;
}