Beispiel #1
0
bool CRunSession::HandleResult (CHexeProcess::ERunCodes iRun, CDatum dResult)

//	HandleResult
//
//	Handles the result from a run

	{
	switch (iRun)
		{
		case CHexeProcess::runOK:
		case CHexeProcess::runError:
			SendMessageReply(MSG_REPLY_DATA, dResult);
			//	FALSE means we're done with the session
			return false;

		case CHexeProcess::runAsyncRequest:
			{
			SendMessageCommand(dResult.GetElement(0), 
					dResult.GetElement(1), 
					GenerateAddress(PORT_HEXE_COMMAND),
					dResult.GetElement(2),
					MESSAGE_TIMEOUT);

			m_iState = stateWaitingForHexarcReply;

			return true;
			}

		default:
			//	LATER:
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, CString("LATER"));
			return false;
		}
	}
Beispiel #2
0
CComplexArray::CComplexArray (CDatum dSrc)

//	ComplexArray constructor

	{
	int i;

	if (dSrc.GetBasicType() == CDatum::typeStruct)
		{
		InsertEmpty(1);
		SetElement(0, dSrc);
		}
	else
		{
		int iCount = dSrc.GetCount();

		//	Clone from another complex array

		if (iCount > 0)
			{
			InsertEmpty(iCount);

			for (i = 0; i < iCount; i++)
				SetElement(i, dSrc.GetElement(i));
			}
		}
	}
bool CCryptosaurEngine::ValidateAuthDescCreate (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx, CDatum dAuthDesc)

//	ValidateAuthDescCreate
//
//	Make sure that the authDesc structure has the proper fields for creating
//	a new user (either admin or not).

	{
	if (!strEquals(dAuthDesc.GetElement(FIELD_TYPE), AUTH_TYPE_SHA1))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_INVALID_AUTHDESC_TYPE, dAuthDesc.GetElement(FIELD_TYPE).AsString()), Msg);
		return false;
		}

	if (dAuthDesc.GetElement(FIELD_CREDENTIALS).IsNil())
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_CREDENTIALS_REQUIRED, Msg);
		return false;
		}

	if (dAuthDesc.GetElement(FIELD_ACTUAL).IsNil())
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_ACTUAL_REQUIRED, Msg);
		return false;
		}

	return true;
	}
Beispiel #4
0
int mesage_FieldName(lua_State* L){
	CMessage* msg = cmessage_arg(L, "mesage_Field");
	int i = luaL_checkint(L, 2);
	CDatum* d = msg->GetDatum(i);
	if (!d) return 0;
	lua_pushstring(L, d->id());
	return 1;
}
Beispiel #5
0
int mesage_SaveFieldBinary(lua_State* L) {
	int err = 0;
	char *b = NULL;
	CMessage* msg = cmessage_arg(L, "mesage_AddFieldBinary");
	CString fldName = luaL_checkstring(L, 2);
	CString path = luaL_checkstring(L, 3);
	char *description;
	DWORD l;

	CDatum *d = msg->GetDatum(fldName);
	if (d->GetVarType() != (VT_ARRAY | VT_UI1) ) {
		err = -1;
		description = "Not Binary Data";
		goto err;
	}
	{
		l = d->GetDataSize();
		b = new char[l];


		SAFEARRAY* pArray = d->value().parray;
		ASSERT(pArray->cDims == 1); // check we have 1 dimension array
		ASSERT(l == pArray->rgsabound[0].cElements * pArray->cbElements); // get size of array
		memcpy(b, (BYTE*)pArray->pvData, l);

		int charsLen = ::MultiByteToWideChar(CP_UTF8, 0, path, lstrlen(path), NULL, 0);
		std::wstring characters(charsLen, '\0');
		::MultiByteToWideChar(CP_UTF8, 0, path, lstrlen(path), &characters[0], charsLen);

		int pf;

		err = _wsopen_s(&pf, characters.c_str(), _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _SH_DENYRW, _S_IWRITE);
		if (err) {
			description = "Open File Error";
			goto err;
		}
		if (l != _write(pf, (b), l)) {
			err = -2;
			description = "Write File Error";
			goto err;
		}

		err = _close(pf);
		if (err){
			description = "Close File Error";
			goto err;
		}
	}
err:
	if (b)
		delete[]b;
	lua_pushinteger(L, err);
	if (err)
		lua_pushstring(L, description);
	else
		lua_pushinteger(L, l);
	return 2;
}
Beispiel #6
0
bool IComplexDatum::DeserializeAEONScript (CDatum::ESerializationFormats iFormat, const CString &sTypename, CCharStream *pStream)

//	DeserializeAEONScript
//
//	Deserialize AEONScript

	{
	int i;
	DWORD dwFlags = OnGetSerializeFlags();

	//	If we have an open brace then we've stored everything as a structure.

	if (pStream->GetChar() == '{')
		{
		//	Object must support this

		if (!(dwFlags & FLAG_SERIALIZE_AS_STRUCT))
			return false;

		//	Parse the structure

		CAEONScriptParser Parser(pStream);
		CDatum dData;
		CAEONScriptParser::ETokens iToken = Parser.ParseToken(&dData);
		if (iToken != CAEONScriptParser::tkDatum)
			return false;

		//	Take all the fields in the structure and apply them to our object
		//	(our descendants will do the right thing).

		for (i = 0; i < dData.GetCount(); i++)
			SetElement(dData.GetKey(i), dData.GetElement(i));
		}

	//	Otherwise we expect base64 encoded data

	else
		{
		//	Backup one character because we want the OnDeserialize call to read it.

		pStream->UnreadChar();

		//	Deserialize

		CBase64Decoder Decoder(pStream->GetByteStream());
		if (!OnDeserialize(iFormat, sTypename, Decoder))
			return false;

		//	Read the next character into the stream 

		pStream->RefreshStream();
		pStream->ReadChar();
		}

	return true;
	}
Beispiel #7
0
CDatum CEsperEngine::GetPortStatus (void) const

//	GetPortStatus
//
//	Returns a struct with well-known fields for status.

	{
	CDatum dStatus = CDatum(CDatum::typeStruct);
	dStatus.SetElement(FIELD_CLASS, STR_ESPER_ENGINE);
	dStatus.SetElement(FIELD_STATUS, NULL_STR);

	return dStatus;
	}
Beispiel #8
0
int ExecuteScript (const SOptions &Options)
	{
	int i, j;

	//	Load the script file

	CDatum dScript;
	CString sError;
	if (!CDatum::CreateFromFile(Options.sScriptFile, CDatum::formatAEONScript, &dScript, &sError))
		{
		printf("ERROR: %s\n", (LPSTR)sError);
		return 1;
		}

	//	Get the server to connect to

	CString sServer = dScript.GetElement(FIELD_SERVER);
	if (sServer.IsEmpty())
		sServer = Options.sServer;

	//	Connect

	CSocket theSocket;
	if (!ConnectToArcology(STR_ARC_CONSOLE, sServer, Options, &theSocket))
		return 1;

	//	Run the script

	CDatum dCommands = dScript.GetElement(FIELD_COMMANDS);
	for (i = 0; i < dCommands.GetCount(); i++)
		{
		CDatum dCommand = dCommands.GetElement(i);

		//	Generate a command-line from the command

		CStringBuffer Buffer;
		for (j = 0; j < dCommand.GetCount(); j++)
			{
			if (j != 0)
				Buffer.Write(" ", 1);

			dCommand.Serialize(CDatum::formatAEONScript, Buffer);
			}

		//	Run

		printf("%s\n", (LPSTR)(const CString &)Buffer);
		CString sResult = ExecuteArcologyCommand(theSocket, Buffer);
		PrintUTF8(sResult);
		printf("\n");
		}

	//	Done

	return 0;
	}
Beispiel #9
0
int mesage_FieldType(lua_State* L){
	CString type = luaL_typename(L, 2);
	CMessage* msg = cmessage_arg(L, "mesage_Field");
	CDatum* d;
	if (type == "string")
		d = msg->GetDatum(luaL_checkstring(L, 2));
	else
		d = msg->GetDatum(luaL_checkint(L, 2));

	if (!d) return 0;	 
	lua_pushstring(L, d->GetVarTypeText());
	return 1;

}
Beispiel #10
0
CComplexStruct::CComplexStruct (CDatum dSrc)

//	CComplexStruct constructor

	{
	//	Clone from another complex structure

	for (int i = 0; i < dSrc.GetCount(); i++)
		{
		CString sKey = dSrc.GetKey(i);
		if (!sKey.IsEmpty())
			SetElement(sKey, dSrc.GetElement(i));
		}
	}
Beispiel #11
0
void CComplexStruct::AppendStruct (CDatum dDatum)

//	AppendStruct
//
//	Appends the element of the given structure

	{
	int i;

	if (dDatum.GetBasicType() == CDatum::typeStruct)
		{
		for (i = 0; i < dDatum.GetCount(); i++)
			SetElement(dDatum.GetKey(i), dDatum.GetElement(i));
		}
	}
Beispiel #12
0
void CAeonRowValue::SetValue (CDatum dValue)

//	SetValue
//
//	Sets the value of a 0D row

	{
	CMemoryBuffer Buffer(4096);
	dValue.Serialize(CDatum::formatAEONScript, Buffer);

	//	Allocate a new block

	DWORD dwSizeUp = AlignUp(Buffer.GetLength(), (int)sizeof(DWORD));
	DWORD dwNewFixedBlockAlloc = sizeof(SItemHeader) + sizeof(SItemHeader) + dwSizeUp;
	void *pNewFixedBlock = new char [dwNewFixedBlockAlloc];

	//	Init

	SItemHeader *pHeader = (SItemHeader *)pNewFixedBlock;
	pHeader->dwSize = sizeof(SItemHeader) + dwSizeUp;

	SItemHeader *pItem = (SItemHeader *)&pHeader[1];
	pItem->dwSize = Buffer.GetLength();

	utlMemCopy(Buffer.GetPointer(), &pItem[1], Buffer.GetLength());

	//	Replace

	if (m_pFixedBlock && m_dwFixedBlockAlloc)
		delete m_pFixedBlock;
	m_pFixedBlock = pNewFixedBlock;
	m_dwFixedBlockAlloc = dwNewFixedBlockAlloc;
	}
Beispiel #13
0
void CAeonView::CreateSecondaryData (const CTableDimensions &PrimaryDims, const CRowKey &PrimaryKey, CDatum dFullData, SEQUENCENUMBER RowID, CDatum *retdData)

//	CreateSecondaryData
//
//	Creates the data for a secondary view row.

	{
	int i, j;
	CComplexStruct *pData = new CComplexStruct;

	//	If the list of columns is empty then we just add the primary key

	if (m_Columns.GetCount() == 0)
		pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims));

	//	Otherwise we add all the fields listed in the columns array

	else
		{
		for (i = 0; i < m_Columns.GetCount(); i++)
			{
			//	The special string "primaryKey" means that we insert the 
			//	primary key as a special field.

			if (strEquals(m_Columns[i], FIELD_PRIMARY_KEY))
				pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims));

			//	The special string "*" means that we insert all existing
			//	fields.

			else if (strEquals(m_Columns[i], STR_ALL_COLUMNS))
				{
				for (j = 0; j < dFullData.GetCount(); j++)
					{
					CDatum dKey = dFullData.GetKey(j);
					CDatum dValue = dFullData.GetElement(j);

					if (!dValue.IsNil())
						pData->SetElement(dKey, dValue);
					}
				}

			//	Add the field by name.

			else
				{
				CDatum dColData = dFullData.GetElement(m_Columns[i]);
				if (!dColData.IsNil())
					pData->SetElement(m_Columns[i], dColData);
				}
			}
		}

	//	Done

	*retdData = CDatum(pData);
	}
Beispiel #14
0
void CAeonEngine::MsgCreateTable (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgCreateTable
//
//	Aeon.createTable {tableDesc}
//
//	{tableDesc} = { name:MyTable1 type:standard x:{keyType:utf8} y:{keyType:int32} z:{keyType:dateTime} }

	{
	CString sError;

	//	Get the table desc and table name

	CDatum dTableDesc = Msg.dPayload.GetElement(0);
	const CString &sTable = dTableDesc.GetElement(FIELD_NAME);

	//	Make sure we are allowed access to this table

	if (!ValidateTableAccess(Msg, pSecurityCtx, sTable))
		return;

	//	See if the table descriptor specifies storage volumes; if so, then we
	//	make sure that the calling service has admin rights.

	if (!dTableDesc.GetElement(FIELD_PRIMARY_VOLUME).IsNil()
			|| !dTableDesc.GetElement(FIELD_BACKUP_VOLUMES).IsNil())
		{
		if (!ValidateAdminAccess(Msg, pSecurityCtx))
			return;
		}

	//	Create

	bool bExists;
	if (!CreateTable(dTableDesc, NULL, &bExists, &sError))
		{
		if (bExists)
			SendMessageReplyError(MSG_ERROR_ALREADY_EXISTS, sError, Msg);
		else
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Done

	SendMessageReply(MSG_OK, CDatum(), Msg);
	}
Beispiel #15
0
CDatum CAeonView::ComputeColumns (CHexeProcess &Process, CDatum dRowData)

//	ComputeColumns
//
//	Returns a new row struct containing any computed columns.

	{
	if (m_ComputedColumns.IsNil() || !m_ComputedColumns.CanInvoke())
		return dRowData;

	//	Compute columns. We should get back a struct of all new columns.

	TArray<CDatum> Args;
	Args.Insert(dRowData);

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = Process.Run(m_ComputedColumns, Args, &dResult);

	switch (iRun)
		{
		case CHexeProcess::runOK:
			{
			//	dResult is a struct containing zero or more columns

			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.Append(dResult);
			return dNewRowData;
			}

		case CHexeProcess::runError:
			{
			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.SetElement(FIELD_ERROR, strPattern("ERROR: %s", dResult.AsString()));
			return dNewRowData;
			}

		default:
			{
			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.SetElement(FIELD_ERROR, ERR_COMPUTED_COLUMN);
			return dNewRowData;
			}
		}
	}
Beispiel #16
0
bool CRunSession::OnStartSession (const SArchonMessage &Msg, DWORD dwTicket)

//	OnStartSession
//
//	Start the session

	{
	CDatum dCode = Msg.dPayload.GetElement(0);

	//	Initialize the process

	m_Process.LoadLibrary(LIBRARY_CORE);

	//	Parse into an expression (depending on the type of input)

	CDatum dExpression;
	if (dCode.GetBasicType() == CDatum::typeString)
		{
		CString sError;
		if (!CHexeDocument::ParseLispExpression(dCode, &dExpression, &sError))
			{
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_COMPILER, sError));
			return false;
			}
		}

	//	Otherwise we don't know how to parse the input

	else
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_UNABLE_TO_PARSE_CODE);
		return false;
		}

	//	Run the code

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = m_Process.Run(dExpression, &dResult);

	//	Deal with the result

	return HandleResult(iRun, dResult);
	}
void CCryptosaurEngine::MsgValidateAuthToken (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgValidateAuthToken
//
//	Cryptosaur.validateAuthToken {authToken}

	{
	//	Any service can validate a token

	if (!ValidateMessage(Msg, pSecurityCtx, false))
		return;

	//	Get the key to sign with (the key is guaranteed to exist because we
	//	checked at boot time).

	CIPInteger *pAuthTokenKey = m_Keys.GetAt(KEY_CRYPTOSAUR_AUTH_TOKEN);

	//	Validate

	CDatum dData;
	if (!CCryptosaurInterface::ValidateAuthToken(Msg.dPayload.GetElement(0), *pAuthTokenKey, &dData))
		{
		SendMessageReply(MSG_REPLY_DATA, CDatum(), Msg);
		return;
		}

	//	A sandboxed authtoken is not valid outside of its scope.
	//	(But it is valid in admin services).

	const CString &sScope = dData.GetElement(FIELD_SCOPE);
	if (!sScope.IsEmpty() 
			&& pSecurityCtx
			&& !pSecurityCtx->IsNamespaceAccessible(sScope))
		{
		SendMessageReply(MSG_REPLY_DATA, CDatum(), Msg);
		return;
		}

	//	Return the data in the auth token

	SendMessageReply(MSG_REPLY_DATA, dData, Msg);
	}
void CHexeMarkupEvaluator::OutputDatum (CDatum dValue)

//	OutputDatum
//
//	Outputs a datum to the resulting HTML page. NOTE: We expect the values to be
//	HTML compatible (i.e., caller is responsible for escaping).

	{
	int i;

	if (dValue.GetBasicType() == CDatum::typeArray)
		{
		for (i = 0; i < dValue.GetCount(); i++)
			OutputDatum(dValue.GetElement(i));
		}
	else
		{
		m_Output.Write(dValue.AsString());
		}
	}
Beispiel #19
0
CString ExecuteLispCommand (const CString &sInput)
	{
	CString sOutput;

	CDatum dExpression;
	if (!CHexeDocument::ParseLispExpression(sInput, &dExpression, &sOutput))
		return sOutput;

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = g_Process.Run(dExpression, &dResult);
	switch (iRun)
		{
		case CHexeProcess::runOK:
		case CHexeProcess::runError:
			return dResult.AsString();

		default:
			return CString("Unable to complete run.");
		}
	}
Beispiel #20
0
bool CDatum::IsEqual (CDatum dValue) const

//	IsEqual
//
//	Returns TRUE if the values are equal

	{
	switch (GetBasicType())
		{
		case typeNil:
			return dValue.IsNil();

		case typeTrue:
			return !dValue.IsNil();

		case typeInteger32:
		case typeInteger64:
		case typeIntegerIP:
		case typeDouble:
			return (dValue.IsNumber() && CNumberValue(*this).Compare(dValue) == 0);

		case typeString:
			return (dValue.GetBasicType() == typeString && strEquals(*this, dValue));

		case typeDateTime:
			return (dValue.GetBasicType() == typeDateTime && ((const CDateTime &)*this == (const CDateTime &)dValue));

		//	LATER
		case typeArray:
		case typeBinary:
		case typeStruct:
		case typeSymbol:
			return false;

		default:
			ASSERT(false);
			return false;
		}
	}
void CHexeMarkupEvaluator::AddHeader (const CString &sField, CDatum dValue)

//	AddHeader
//
//	Adds the header

	{
	CHTTPMessage::SHeader *pNewHeader;

	switch (dValue.GetBasicType())
		{
		case CDatum::typeString:
			pNewHeader = m_Headers.Insert();
			pNewHeader->sField = sField;
			pNewHeader->sValue = dValue;
			break;

		default:
			pNewHeader = m_Headers.Insert();
			pNewHeader->sField = sField;
			pNewHeader->sValue = dValue.AsString();
		}
	}
Beispiel #22
0
CDatum CUserInfoSession::CreateSanitizedUserRecord (CDatum dRecord)

//	CreateSanitizedUserRecord
//
//	Creates a user record suitable for returning to clients. In partincular,
//	we remove the authentication information.

	{
	int i;

	//	Create a destination

	CComplexStruct *pDest = new CComplexStruct;

	//	Copy all appropriate fields

	for (i = 0; i < dRecord.GetCount(); i++)
		{
		//	If this is an auth field, then skip it

		if (strEquals(dRecord.GetKey(i), FIELD_AUTH_DESC))
			;

		else if (strEndsWith(dRecord.GetKey(i), FIELD_AUTH_DESC_SUFFIX))
			;
		
		//	Otherwise, copy it

		else
			pDest->SetElement(dRecord.GetKey(i), dRecord.GetElement(i));
		}

	//	Done

	return CDatum(pDest);
	}
Beispiel #23
0
bool CComplexArray::FindElement (CDatum dValue, int *retiIndex) const

//	FindElement
//
//	Finds the given element

	{
	int i;

	for (i = 0; i < m_Array.GetCount(); i++)
		if (dValue.IsEqual(m_Array[i]))
			{
			if (retiIndex)
				*retiIndex = i;
			return true;
			}

	return false;
	}
Beispiel #24
0
int mesage_Field(lua_State* L){
	CString type = luaL_typename(L, 2);
	CMessage* msg = cmessage_arg(L, "mesage_Field");
	CDatum* d;
	if(type == "string")
		d = msg->GetDatum(luaL_checkstring(L, 2));
	else
		d = msg->GetDatum(luaL_checkint(L, 2));

	if (!d) return 0;
	switch (d->GetVarType())
	{
	case VT_R8:
	{
		double i;
		d->GetValueAsDouble(i);
		lua_pushnumber(L, i);
	}
		break;
	case VT_I4:
	{
		long i;
		d->GetValueAsLong(i);
		lua_pushinteger(L, i);
	}
		break;
	case VT_BOOL:
	{
		bool i;
		d->GetValueAsBool(i);
		lua_pushboolean(L, i);
	}
		break;
	case VT_BSTR:
	case VT_DATE:
		lua_pushstring(L, d->GetValueText());
		break;
	default:
		lua_pushnil(L);
	}
	return 1;
}
Beispiel #25
0
int mesage_GetPathValue(lua_State* L)
{
	CString path = luaL_checkstring(L,2);
	CMessage* msg = cmessage_arg(L,"mesage_GetPathValue");
	CDatum* d = msg->GetDatumByPath(path);
	if(!d) return 0;
	switch(d->GetVarType())
	{
	case VT_R8:
		{
			double i;
			d->GetValueAsDouble(i);
			lua_pushnumber(L, i);
		}
		break;
	case VT_I4:
		{
			long i;
			d->GetValueAsLong(i);
			lua_pushinteger(L, i);
		}
		break;
	case VT_BOOL:
		{
			bool i;
			d->GetValueAsBool(i);
			lua_pushboolean(L, i);
		}
		break;
	case VT_BSTR:
	case VT_DATE:
		lua_pushstring(L, d->GetValueText());
		break;
	default:
		lua_pushnil(L);
	}
	return 1;
}
Beispiel #26
0
void CMnemosynthDb::IncorporateDelta (CDatum dPayload)

//	IncorporateDelta
//
//	Incorporates the delta data

	{
	CSmartLock Lock(m_cs);

	int i;

	//	Get various elements

	CDatum dCollections = dPayload.GetElement(STR_COLLECTIONS);
	CDatum dEndpoint = dPayload.GetElement(STR_ENDPOINT);
	CDatum dEntries = dPayload.GetElement(STR_ENTRIES);
	DWORD dwProcessID = dPayload.GetElement(FIELD_PROCESS_ID);

	//	Make sure the endpoint exists

	SEndpoint *pEndpoint = GetOrAddEndpoint(dEndpoint, dwProcessID);

	DWORD dwOriginalSeq = pEndpoint->dwSeqRecv;
	DWORD dwMaxSeq = dwOriginalSeq;

	//	Loop over all entries

	for (i = 0; i < dEntries.GetCount(); i++)
		{
		CDatum dEntry = dEntries.GetElement(i);
		DWORD dwSeq = (DWORD)(int)dEntry.GetElement(3);
		if (dwSeq > dwOriginalSeq)
			{
			//	LATER: Detect and resolve conflicts

			if (dwSeq > dwMaxSeq)
				dwMaxSeq = dwSeq;

			const CString &sCollection = dCollections.GetElement((int)dEntry.GetElement(0));
			const CString &sKey = dEntry.GetElement(1);
			CDatum dValue = dEntry.GetElement(2);

			//	If we're not CentralModule and we get a deletion, then delete
			//	right away. If we're CentralModule then we incorporate because
			//	we will send it out on the next update.

			if (dValue.IsNil() && !m_pProcess->IsCentralModule())
				{
				DeleteEntry(sCollection, sKey);
#ifdef DEBUG_MNEMOSYNTH
				printf("Delete entry: %s/%s\n", (LPSTR)sCollection, (LPSTR)sKey);
#endif
				}

			//	Incorporate

			else
				{
				SEntry *pEntry = GetWriteEntry(sCollection, sKey);
				pEntry->dValue = dValue;
				pEntry->dwOwnerID = pEndpoint->dwID;
				pEntry->dwSequence = dwSeq;

#ifdef DEBUG_MNEMOSYNTH
				printf("Modify entry: %s/%s [owner = %s seq = %d]\n", (LPSTR)sCollection, (LPSTR)sKey, (LPSTR)pEndpoint->sName, dwSeq);
#endif
				}
			}
#ifdef DEBUG_MNEMOSYNTH
		else
			{
			printf("%s: Skipping %s because %d <= %d\n", (LPSTR)m_pProcess->GetModuleName(), (LPSTR)dCollections.GetElement((int)dEntry.GetElement(0)).AsString(), dwSeq, dwOriginalSeq);
			}
#endif
		}

	//	Done

	pEndpoint->dwSeqRecv = dwMaxSeq;
	}
Beispiel #27
0
bool CUserInfoSession::OnProcessMessage (const SArchonMessage &Msg)

//	OnProcessMessage
//
//	We received a reply from Aeon

	{
	int i;

	//	If this is an error, then we return the error back to the client

	if (IsError(Msg))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, Msg.dPayload);
		return false;
		}

	//	If we're waiting for the user record, then see if we can process it now.

	if (m_iState == stateWaitingForUserRecord)
		{
		//	Cryptosaur.getUser

		if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_GET_USER))
			{
			CDatum dUserData = Msg.dPayload;

			//	If the user does not exist, then we return Nil

			if (dUserData.IsNil())
				{
				SendMessageReply(MSG_REPLY_DATA, CDatum());
				return false;
				}

			//	Generate a sanitized user record

			CComplexStruct *pReply = new CComplexStruct;
			pReply->SetElement(FIELD_USERNAME, dUserData.GetElement(FIELD_USERNAME));

			//	Sanitize rights

			CDatum dRights = dUserData.GetElement(FIELD_RIGHTS);
			if (!m_sScope.IsEmpty())
				{
				CComplexArray *pRights = new CComplexArray;

				for (i = 0; i < dRights.GetCount(); i++)
					if (strStartsWith(dRights.GetElement(i), m_sScope))
						pRights->Insert(dRights.GetElement(i));

				pReply->SetElement(FIELD_RIGHTS, CDatum(pRights));
				}
			else
				pReply->SetElement(FIELD_RIGHTS, dRights);

			//	Done

			SendMessageReply(MSG_REPLY_DATA, CDatum(pReply));
			return false;
			}

		//	If we get back nil then the user does not exist.

		else if (Msg.dPayload.IsNil())
			{
			SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, strPattern(ERR_UNKNOWN_USERNAME, m_sUsername));
			return false;
			}

		//	Otherwise, we handle the result based on the original message

		else if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_CHECK_PASSWORD_SHA1))
			{
			//	Get the parameters from the original message

			CDatum dChallenge = GetOriginalMsg().dPayload.GetElement(1);
			CDatum dResponse = GetOriginalMsg().dPayload.GetElement(2);

			//	Get the password has from the response

			CDatum dAuthDesc = Msg.dPayload.GetElement(FIELD_AUTH_DESC);
			CDatum dPasswordHash = dAuthDesc.GetElement(FIELD_CREDENTIALS);

			//	Create a response to the challenge based on the password hash that
			//	we have stored.

			CDatum dCorrect = CAI1Protocol::CreateSHAPasswordChallengeResponse(dPasswordHash, dChallenge);

			//	Compare the correct response to the actual

			if ((const CIPInteger &)dResponse == (const CIPInteger &)dCorrect)
				return UpdateLoginSuccess(stateWaitingForSuccessUpdate);
			else
				return UpdateLoginFailure();
			}

		//	Cryptosaur.hasRights

		else if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_HAS_RIGHTS))
			{
			CDatum dRights = Msg.dPayload.GetElement(FIELD_RIGHTS);
			CDatum dRightsRequired = m_dPayload.GetElement(1);

			//	Get the rights from the user

			CAttributeList Rights;
			dRights.AsAttributeList(&Rights);

			//	Check

			for (i = 0; i < dRightsRequired.GetCount(); i++)
				{
				if (!Rights.HasAttribute(dRightsRequired.GetElement(i)))
					{
					SendMessageReply(MSG_REPLY_DATA, CDatum());
					return false;
					}
				}

			//	We have all rights

			SendMessageReply(MSG_REPLY_DATA, CDatum(CDatum::constTrue));
			return false;
			}

		//	Cryptosaur.loginUser

		else if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_LOGIN_USER))
			{
			//	Get the parameters from the original message

			CDatum dRequestAuthDesc = GetOriginalMsg().dPayload.GetElement(1);
			CDatum dCredentials = dRequestAuthDesc.GetElement(FIELD_CREDENTIALS);
			CDatum dChallengeCredentials = dRequestAuthDesc.GetElement(FIELD_CHALLENGE_CREDENTIALS);
			CDatum dPassword = dRequestAuthDesc.GetElement(FIELD_PASSWORD);
			m_bActual = !dRequestAuthDesc.GetElement(FIELD_ACTUAL).IsNil();

			if (!dRequestAuthDesc.GetElement(FIELD_AUTH_TOKEN_INFINITE).IsNil())
				m_dwAuthTokenLifetime = 0;
			else
				{
				m_dwAuthTokenLifetime = (DWORD)(int)dRequestAuthDesc.GetElement(FIELD_AUTH_TOKEN_LIFETIME);
				if (m_dwAuthTokenLifetime == 0)
					m_dwAuthTokenLifetime = DEFAULT_AUTH_TOKEN_TIMEOUT;
				}

			//	If we're not actual and have no scope, then we can't continue

			if (!m_bActual && m_sScope.IsEmpty())
				{
				SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_SCOPE_REQUIRED);
				return false;
				}

			//	User data

			CDatum dUserData = Msg.dPayload;
			CDatum dAuthDesc;
			if (m_bActual)
				dAuthDesc = dUserData.GetElement(FIELD_AUTH_DESC);
			else
				dAuthDesc = dUserData.GetElement(strPattern("%s%s", m_sScope, FIELD_AUTH_DESC));

			//	If we have no authdesc, then we can't continue. This is likely 
			//	because the client is in a sandbox that the user has not registered
			//	with. We treat it the same as a username/password failure.

			if (dAuthDesc.IsNil())
				{
				SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, ERR_INVALID_USERNAME_OR_PASSWORD);
				return false;
				}

			//	If we've failed more than 5 consecutive times, we may need to delay
			//	the next login attempt.

			if ((int)dUserData.GetElement(FIELD_LOGIN_FAILURE_COUNT) > MAX_LOGIN_ATTEMPTS)
				{
				CDateTime LastLoginFailure = dUserData.GetElement(FIELD_LAST_LOGIN_FAILURE_ON);
				CTimeSpan TimeSinceLastFailure = timeSpan(LastLoginFailure, CDateTime(CDateTime::Now));

				//	If it has not been at least 1 hour, we return an error.

				if (TimeSinceLastFailure.Days() == 0 && TimeSinceLastFailure.Seconds() < LOGIN_TIMEOUT)
					{
					//	Timeout

					SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, ERR_FAILURE_TIMEOUT);
					return false;
					}
				}

			//	If we have straight credentials, then just compare

			bool bSuccess;
			if (!dCredentials.IsNil())
				bSuccess = ((const CIPInteger &)dCredentials == (const CIPInteger &)dAuthDesc.GetElement(FIELD_CREDENTIALS));

			//	Otherwise, we compare against the challenge

			else if (!dChallengeCredentials.IsNil())
				{
				//	Get the challenge. If not provided then we get it from the user
				//	record.

				CDatum dChallenge = GetOriginalMsg().dPayload.GetElement(2);
				if (dChallenge.IsNil())
					{
					//	Get the expiration time of the challenge

					const CDateTime &Expires = dAuthDesc.GetElement(FIELD_CHALLENGE_EXPIRATION);
					if (Expires < CDateTime(CDateTime::Now))
						{
						SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, ERR_INVALID_USERNAME_OR_PASSWORD);
						return false;
						}

					dChallenge = dAuthDesc.GetElement(FIELD_CHALLENGE);
					}

				//	Create a response to the challenge based on the password hash that
				//	we have stored.

				CDatum dCorrectChallenge = CAI1Protocol::CreateSHAPasswordChallengeResponse(
						dAuthDesc.GetElement(FIELD_CREDENTIALS),
						dChallenge
						);

				bSuccess = ((const CIPInteger &)dChallengeCredentials == (const CIPInteger &)dCorrectChallenge);
				}

			//	Otherwise we expect a clear text password

			else if (!dPassword.IsNil())
				{
				//	We have to hash the password to compare with credentials.

				CIPInteger Credentials;
				CCryptosaurInterface::CreateCredentials(dUserData.GetElement(FIELD_USERNAME), dPassword, &Credentials);

				//	Compare

				bSuccess = (Credentials == (const CIPInteger &)dAuthDesc.GetElement(FIELD_CREDENTIALS));
				}
			else
				bSuccess = false;

			//	Success or failure

			if (bSuccess)
				return UpdateLoginSuccess(stateWaitingForCredentials);
			else
				return UpdateLoginFailure();
			}

		//	Can never get here.

		else
			{
			ASSERT(false);
			return false;
			}
		}

	//	Otherwise, if we're waiting for the user record update, then continue

	else if (m_iState == stateWaitingForSuccessUpdate)
		{
		//	Since we succeeded, we send the user sanitized user record back.

		SendMessageReply(MSG_REPLY_DATA, CreateSanitizedUserRecord(Msg.dPayload));
		return false;
		}

	//	If we're waiting for credentials, compose them

	else if (m_iState == stateWaitingForCredentials)
		{
		//	The mutation returns the full record

		CDatum dUserData = Msg.dPayload;

		//	Compute the result

		CComplexStruct *pAuthToken = new CComplexStruct;
		pAuthToken->SetElement(FIELD_USERNAME, dUserData.GetElement(FIELD_USERNAME));
		pAuthToken->SetElement(FIELD_RIGHTS, dUserData.GetElement(FIELD_RIGHTS));
		if (!m_bActual)
			pAuthToken->SetElement(FIELD_SCOPE, m_sScope);

		CDatum dAuthToken = m_pEngine->GenerateAuthToken(CDatum(pAuthToken), m_dwAuthTokenLifetime);

		//	Compose a basic user record

		CComplexStruct *pReply = new CComplexStruct;
		pReply->SetElement(FIELD_AUTH_TOKEN, dAuthToken);
		pReply->SetElement(FIELD_RIGHTS, dUserData.GetElement(FIELD_RIGHTS));
		pReply->SetElement(FIELD_USERNAME, dUserData.GetElement(FIELD_USERNAME));

		//	Send the reply

		SendMessageReply(MSG_REPLY_DATA, CDatum(pReply));

		//	Done

		return false;
		}

	//	Otherwise, failure

	else if (m_iState == stateWaitingForFailureUpdate)
		{
		CDatum dUserData = Msg.dPayload;

		//	If we've exceeded our limit, log it

		int iAttempts = (int)dUserData.GetElement(FIELD_LOGIN_FAILURE_COUNT);
		if (iAttempts > MAX_LOGIN_ATTEMPTS)
			GetProcessCtx()->Log(MSG_LOG_INFO, strPattern(ERR_USERNAME_TIMEOUT, m_sUsername, iAttempts));

		//	Send a failure

		SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, ERR_INVALID_USERNAME_OR_PASSWORD);
		return false;
		}

	//	Can never get here

	else
		{
		ASSERT(false);
		return false;
		}
	}
Beispiel #28
0
CString ExecuteUpgrade (CSocket &theSocket, const CString &sCmd)
	{
	int i;

	CString sRoot = fileGetPath(fileGetExecutableFilespec());

	//	Make a list of all executable files to upgrade

	TArray<CString> FileList;
	if (!fileGetFileList(sRoot, NULL_STR, CString("*.exe"), FFL_FLAG_RELATIVE_FILESPEC, &FileList))
		return CString("ERROR: Unable to obtain a list of executable files to upgrade.");

	//	Prepare a request upgrade command

	CStringBuffer Output;
	Output.Write("requestUpgrade (", 16);

	for (i = 0; i < FileList.GetCount(); i++)
		{
		CString sFilespec = fileAppend(sRoot, FileList[i]);

		//	Version

		SFileVersionInfo Info;
		if (!fileGetVersionInfo(sFilespec, &Info))
			{
			printf("ERROR: Unable to get file version: %s\n", (LPSTR)sFilespec);
			continue;
			}

		CIPInteger Version(Info.dwProductVersion);
		CString sVersion = Version.AsString();

		//	Checksum

		DWORD dwChecksum = fileChecksumAdler32(sFilespec);
		if (dwChecksum == 0)
			{
			printf("ERROR: Unable to get file checksum: %s\n", (LPSTR)sFilespec);
			continue;
			}

		CString sOutput = strPattern("{filename:\"%s\" version:%s checksum:%d} ", FileList[i], sVersion, dwChecksum);
		Output.Write(sOutput);
		}

	Output.Write(")", 1);

	//	Send the command

	CString sSend = CString::CreateFromHandoff(Output);
	CString sResult;
	CDatum dResult;
	ExecuteArcologyCommand(theSocket, sSend, &sResult, &dResult);
	if (strEquals(sResult, CString("ERROR")))
		return dResult.AsString();

	//	Show all the files to upgrade

	CDatum dUpgradeDesc = dResult.GetElement(0).GetElement(FIELD_UPGRADE_DESC);
	for (i = 0; i < dUpgradeDesc.GetCount(); i++)
		{
		CDatum dFileDesc = dUpgradeDesc.GetElement(i);

		printf("Upgrading %s\n", (LPSTR)dFileDesc.GetElement(FIELD_FILENAME).AsString());
		}

	//	Confirm

	CString sConfirm = GetInputLine(CString("\nAre you sure you want to upgrade the arcology? [y/n] : "));
	if (*sConfirm.GetParsePointer() != 'y' && *sConfirm.GetParsePointer() != 'Y')
		return NULL_STR;

	//	Upload the new files.

	for (i = 0; i < dUpgradeDesc.GetCount(); i++)
		{
		CDatum dFileDesc = dUpgradeDesc.GetElement(i);
		const CString &sFilename = dFileDesc.GetElement(FIELD_FILENAME);
		CString sFilespec = fileAppend(sRoot, sFilename);

		CString sResult = UploadFile(theSocket, CMD_UPLOAD_UPGRADE, sFilename, sFilespec);
		printf("%s\n", (LPSTR)sResult);
		}

	//	Complete the upgrade

	return ExecuteArcologyCommand(theSocket, CMD_COMPLETE_UPGRADE);
	}
Beispiel #29
0
void CAeonView::Insert (const CTableDimensions &PrimaryDims, CHexeProcess &Process, const CRowKey &PrimaryKey, CDatum dData, CDatum dOldData, SEQUENCENUMBER RowID, bool *retbRecoveryFailed, CString *retsError)

//	Insert
//
//	Insert a row
//
//	NOTE: We cannot fail here because callers should have called CanInsert
//	(above).

	{
	int i;
	CString sError;
	*retbRecoveryFailed = false;

	//	If this is a primary view then all we have to do is insert the row

	if (!IsSecondaryView())
		{
		m_pRows->Insert(PrimaryKey, dData, RowID);
		if (!m_Recovery.Insert(PrimaryKey, dData, RowID, retsError))
			*retbRecoveryFailed = true;
		}

	//	Otherwise, it's more complicated.

	else
		{
		//	If this view is not yet up to date then we skip insertion (we will
		//	insert all rows later).

		if (!IsUpToDate())
			return;

		//	If we are updating an existing row, then we need to remove the old
		//	value. Note that it is OK if OldKey and NewKey end up being the
		//	same; we just end up overwriting it.

		if (!dOldData.IsNil())
			{
			//	Generate a key for the old value. If all key values are non-nil
			//	then we update the old value.

			TArray<CRowKey> OldKeys;
			if (CreateSecondaryKeys(Process, ComputeColumns(Process, dOldData), RowID, &OldKeys))
				{
				//	Now delete the old value (by writing out Nil)

				for (i = 0; i < OldKeys.GetCount(); i++)
					{
					m_pRows->Insert(OldKeys[i], CDatum(), RowID);
					if (!m_Recovery.Insert(OldKeys[i], CDatum(), RowID, retsError))
						*retbRecoveryFailed = true;
					}
				}
			}

		//	Save the new value (only if not Nil)

		if (!dData.IsNil())
			{
			//	Compute columns

			dData = ComputeColumns(Process, dData);

			//	Generate a key for the new value. If all key values are non-nil
			//	then we insert the row into the secondary view.

			TArray<CRowKey> NewKeys;
			if (CreateSecondaryKeys(Process, dData, RowID, &NewKeys))
				{
				//	Generate data for secondary key

				CDatum dViewData;
				CreateSecondaryData(PrimaryDims, PrimaryKey, dData, RowID, &dViewData);

				//	Insert it

				for (i = 0; i < NewKeys.GetCount(); i++)
					{
					m_pRows->Insert(NewKeys[i], dViewData, RowID);
					if (!m_Recovery.Insert(NewKeys[i], dViewData, RowID, retsError))
						*retbRecoveryFailed = true;
					}
				}
			}
		}
	}
Beispiel #30
0
bool CAeonView::InitAsSecondaryView (CDatum dDesc, CHexeProcess &Process, const CString &sRecoveryFilespec, bool bForceUpdate, CString *retsError)

//	InitAsSecondaryView
//
//	Initializes a secondary view.

	{
	int i;

	ASSERT(m_Dims.GetCount() == 0);

	//	Get the name

	m_sName = dDesc.GetElement(FIELD_NAME);

	m_bUsesListKeys = false;

	//	Parse the x dimension

	CDatum dimDesc = dDesc.GetElement(FIELD_X);
	if (!dimDesc.IsNil())
		{
		SDimensionDesc *pDimDesc = m_Dims.Insert();
		CDatum *pKey = m_Keys.Insert();
		if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
			{
			m_bInvalid = true;
			return false;
			}

		if (pDimDesc->iKeyType == keyListUTF8)
			m_bUsesListKeys = true;

		//	Parse the y dimension

		dimDesc = dDesc.GetElement(FIELD_Y);
		if (!dimDesc.IsNil())
			{
			pDimDesc = m_Dims.Insert();
			pKey = m_Keys.Insert();
			if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
				{
				m_bInvalid = true;
				return false;
				}

			if (pDimDesc->iKeyType == keyListUTF8)
				m_bUsesListKeys = true;

			//	Parse z dimension

			dimDesc = dDesc.GetElement(FIELD_Z);
			if (!dimDesc.IsNil())
				{
				pDimDesc = m_Dims.Insert();
				pKey = m_Keys.Insert();
				if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
					{
					m_bInvalid = true;
					return false;
					}

				if (pDimDesc->iKeyType == keyListUTF8)
					m_bUsesListKeys = true;
				}
			}
		}

	//	If we don't have at least one dimension then this is an error

	else
		{
		*retsError = ERR_DIMENSIONS_REQUIRED;
		m_bInvalid = true;
		return false;
		}

	//	Secondary views always have an extra dimension. We use the rowID as a
	//	way to break ties in the other parts of the key (since secondary keys
	//	need not be unique).

	SDimensionDesc *pDimDesc = m_Dims.Insert();
	pDimDesc->iKeyType = keyInt64;
	pDimDesc->iSort = AscendingSort;

	//	Parse columns

	CDatum dColumns = dDesc.GetElement(FIELD_COLUMNS);
	for (i = 0; i < dColumns.GetCount(); i++)
		{
		const CString &sCol = dColumns.GetElement(i);
		if (!sCol.IsEmpty())
			m_Columns.Insert(sCol);
		}

	//	Computed columns

	m_ComputedColumns = dDesc.GetElement(FIELD_COMPUTED_COLUMNS);

	//	We need to set the global environment because it got loaded under a 
	//	different process.

	if (strEquals(m_ComputedColumns.GetTypename(), TYPENAME_HEXE_FUNCTION))
		m_ComputedColumns.SetElement(FIELD_GLOBAL_ENV, Process.GetGlobalEnv());

	//	Exclude nil?

	m_bExcludeNil = !dDesc.GetElement(FIELD_EXCLUDE_NIL_KEYS).IsNil();

	//	Initialize rows

	if (!InitRows(sRecoveryFilespec, NULL, retsError))
		{
		m_bInvalid = true;
		return false;
		}

	//	Set up update. If we have stored an update sequence number then it means
	//	that we are loading an old view that has not yet been fully updated.
	//
	//	Otherwise we take the updating number passed in.

	m_bUpdateNeeded = (bForceUpdate ? true : !dDesc.GetElement(FIELD_UPDATE_NEEDED).IsNil());

	//	Done

	return true;
	}