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; } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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)); } }
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)); } }
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; }
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); }
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); }
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; } } }
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()); } }
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."); } }
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(); } }
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); }
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; }
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; }
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; }
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; }
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; } }
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); }
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; } } } } }
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; }