Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
opentxs::UserCommandProcessor Class Reference

#include <UserCommandProcessor.hpp>

Public Member Functions

 UserCommandProcessor (OTServer *server)
 
bool ProcessUserCommand (OTMessage &msgIn, OTMessage &msgOut, ClientConnection *connection, OTPseudonym *nym)
 

Detailed Description

Definition at line 147 of file UserCommandProcessor.hpp.

Constructor & Destructor Documentation

opentxs::UserCommandProcessor::UserCommandProcessor ( OTServer server)

Definition at line 158 of file UserCommandProcessor.cpp.

159  : server_(server)
160 {
161 }

Member Function Documentation

bool opentxs::UserCommandProcessor::ProcessUserCommand ( OTMessage msgIn,
OTMessage msgOut,
ClientConnection connection,
OTPseudonym nym 
)
                         ((false ==

bLoadedSignedNymfile) && (false == bLoadedPublicKey)) // It's like this now so unregistered Nyms

Definition at line 166 of file UserCommandProcessor.cpp.

170 {
171  msgOut.m_strRequestNum.Set(theMessage.m_strRequestNum);
172 
175  0) || // AND (there's no Override Nym ID listed --OR-- the Override
176  // Nym ID doesn't
177  (0 !=
179  (theMessage.m_strNymID.Get()))))) // match the Nym's ID who
180  // sent this message)
181  {
183  0, "UserCommandProcessor::ProcessUserCommand: Nym %s: failed "
184  "attempt to message the server, while server is in "
185  "**LOCK DOWN MODE**.\n",
186  theMessage.m_strNymID.Get());
187  return false;
188  }
189 
190  // Validate the server ID, to keep users from intercepting a valid requst
191  // and sending it to the wrong server.
192  if (!(server_->m_strServerID == theMessage.m_strServerID)) {
193  OTLog::Error("UserCommandProcessor::ProcessUserCommand: Invalid server "
194  "ID sent in "
195  "command request.\n");
196  return false;
197  }
198  else {
199  OTLog::Output(4, "Received valid Server ID with command request.\n");
200  }
201  // NYM WAS PASSED IN
202  //
203  OTPseudonym theNym(theMessage.m_strNymID);
204 
205  if (nullptr == pNym)
206  pNym = &theNym; // If one wasn't passed in, we'll use the one
207  // constructed here. (One line up.)
208  else if (!pNym->CompareID(theNym)) {
209  OTString strTempNymID;
210  pNym->GetIdentifier(strTempNymID);
212  "UserCommandProcessor::ProcessUserCommand: NymID on the optional "
213  "Nym passed in "
214  "(%s) "
215  "does NOT match the NymID on theMessage (%s). (Returning false.)\n",
216  strTempNymID.Get(), theMessage.m_strNymID.Get());
217  return false;
218  }
219  // NYM IS ACTUALLY SERVER
220 
221  // For special cases where the Nym sending the transaction has the same
222  // public key as
223  // the server itself. (IE it IS the server Nym, then we'd want to use the
224  // already-loaded
225  // server nym object instead of loading a fresh one, so the two don't
226  // overwrite each other.)
227  //
228  const bool bNymIsServerNym =
229  (server_->m_strServerUserID.Compare(theMessage.m_strNymID) ? true
230  : false);
231  // OTPseudonym * pNym = &theNym; // this is now done higher up in this
232  // function.
233 
234  if (bNymIsServerNym) pNym = &server_->m_nymServer;
235 
236  // This command is special because the User sent his public key, not just
237  // his ID.
238  // We have to verify the two together.
239  //
240  // At this point the user doesn't even have an account, so there is no
241  // public key
242  // to look up from the database.
243  //
244  // If the ServerID in the reply matches the ID calculated from the Server
245  // Contract,
246  // that means the user, without asking for the server's public key, can just
247  // extract
248  // the public key from the contract from which the serverID was first
249  // calculated. (The
250  // ID is a hash of the contract.)
251  //
252  // In other words, the user reads a contract. It's signed. The signature is
253  // verified
254  // by a public key that is embedded in the contract. If the server, a URL
255  // also embedded in
256  // the contract, acknowledges the ServerID, then the user can encrypt
257  // everything to the
258  // public key in the contract, without asking the server for a copy of that
259  // key.
260  //
261  // Only the private key who signed that contract will be able to read the
262  // communications from
263  // the user.
264  //
265  // I definitely have to build in an option for x509 certs to be used in lieu
266  // of public keys.
267  // Otherwise the key is not ever revokable -- yet it's in a contract! What
268  // is the issuer supposed
269  // to do if that key is stolen? Make a public announcement?
270  //
271  // UPDATE ONE-LINE NOTE: THE TRUE SOLUTION TO THIS WHOLE ISSUE IS: ***
272  // NAMECOIN ***
273  // (Now continuing back to my old comments from 18 months ago...)
274  //
275  // In such a case, the issuer would have to put a "check this URL to make
276  // sure contract still good"
277  // variable into the contract so that the users have the chance to make sure
278  // the contract is still
279  // good and the contract's private key hasn't been stolen. Well guess what?
280  // That's what x509 does.
281  // Therefore the appropriate solution is for the server to support x509s,
282  // and to look up the authority
283  // and verify certs, so that users have recourse in the event their private
284  // key is stolen. (They can
285  // just use their Cert to issue a new public key, which the transaction
286  // server would be smart enough
287  // to use, once the certificate authority signs off on it. (Since the user
288  // uses an x509 from a
289  // specific authority, then I can trust that whatever that authority says,
290  // that user wanted it to say.)
291  // Without knowing the authority itself, I can now trust it because the user
292  // has asked me to trust it.
293  // Fair enough!
294  //
295  // Similarly a user should be able to use his x509 Cert instead of his
296  // public key, and the server
297  // should verify that cert whenever it's used to make sure it's up to date.
298  // This takes the
299  // problem off of the user's hands by way of a trusted authority.
300  //
301  // In fact this transaction server is really just a transaction VERIFIER.
302  // It's just another form
303  // of trusted 3rd party. Just like Verisign is an authority who ceritifies
304  // an identity, so this
305  // server is an authority who certifies a transaction. It's like a
306  // timestamping server. In fact
307  // it should have timestamping built in as one of the functions.
308  //
309  // Transactions do not actually occur on the server, per se. They occur
310  // between the USERS.
311  // All the server does it certify that the numbers are correct. It's like
312  // accounting software.
313  // Ultimately the users are the ones making a transaction, and they are the
314  // ones who are
315  // responsible to back up their promises in real life and potentially in
316  // court. All the software
317  // does is CERTIFY that the users DID make certain agreements at certain
318  // times, and digitally sign
319  // those certifications.
320  //
321  // Thus, this server is very similar to Verisign. It is a trusted 3rd party
322  // who users can trust
323  // to authenticate their transactions. Instead of authenticating
324  // certifications like Verisign does,
325  // it authenticates transactions.
326  //
327  // UPDATE: May not want x509's after all, since it provides an opening for
328  // governments to
329  // serve warrants on the authority site and switch certs whenever they want
330  // to (BAD THING!)
331  //
332  OTString strMsgNymID;
333  pNym->GetIdentifier(strMsgNymID);
334 
335  if (theMessage.m_strCommand.Compare("checkServerID")) {
336  OTLog::vOutput(0,
337  "\n==> Received a checkServerID message. Nym: %s ...\n",
338  strMsgNymID.Get());
340  std::unique_ptr<OTAsymmetricKey> pNymAuthentKey(
342  std::unique_ptr<OTAsymmetricKey> pNymEncryptKey(
344  OT_ASSERT(nullptr != pNymAuthentKey);
345  OT_ASSERT(nullptr != pNymEncryptKey);
346  OTAsymmetricKey& nymAuthentKey = *pNymAuthentKey;
347  OTAsymmetricKey& nymEncryptionKey = *pNymEncryptKey;
348  const bool bIfNymPublicKey =
349  (nymAuthentKey.SetPublicKey(theMessage.m_strNymPublicKey,
350  true /*bEscaped*/) &&
351  nymEncryptionKey.SetPublicKey(theMessage.m_strNymID2,
352  true /*bEscaped*/));
353 
354  if (bIfNymPublicKey) {
355  if (theMessage.VerifyWithKey(nymAuthentKey)) // Not all contracts
356  // are signed with the
357  // authentication key,
358  // but messages are.
359  {
361  3, "Signature verified! The message WAS signed by "
362  "the Private Authentication Key inside the message.\n");
363 
364  // This is only for verified Nyms, (and we're verified in here!)
365  // We do this so that
366  // we have the option later to encrypt the replies back to the
367  // client...(using the
368  // client's public key that we set here.)
369  if (nullptr != pConnection)
370  pConnection->SetPublicKey(
371  theMessage.m_strNymID2); // theMessage.m_strNymID2
372  // contains the public
373  // encryption key for sending
374  // an encrypted reply.
375 
376  UserCmdCheckServerID(*pNym, theMessage, msgOut);
377  return true;
378  }
379  else {
381  0, "checkServerID: Signature verification failed!\n");
382  return false;
383  }
384  }
385  else {
386  OTLog::Error("Failure reading Nym's signing and/or encryption keys "
387  "from message.\n");
388  return false;
389  }
390  }
391 
392  // The below block is now COMPLETE. (For credentials new system.)
393  //
394  // Next, make sure the client side is properly forming the new version of
395  // this message,
396  // and make sure it creates credentials when necessary, if they don't
397  // already exist
398  // (Since this new server version ONLY accepts credentials, and not
399  // old-style public keys.)
400  //
401  // This command is also special because again, the User sent his public key,
402  // not just his ID.
403  // We have to verify the two together.
404  // UPDATE: now the Nym sends not a public key, but a full set of credentials
405  // along with
406  // a list of credential IDs. You load the list of credential IDs as if you
407  // are loading the Nym
408  // from a string. (It's like a nym that only contains the credential parts.)
409  // Then in the process
410  // of loading the Nym, it will load the credentials from the mapOfStrings.
411  //
412  else if (theMessage.m_strCommand.Compare("createUserAccount")) {
414  0, "\n==> Received a createUserAccount message. Nym: %s ...\n",
415  strMsgNymID.Get());
417  if (bNymIsServerNym) {
418  OTLog::Output(0,
419  "**** Sorry, the server Nym is forbidden from using "
420  "the createUserAccount message as a client. "
421  "PLEASE REMOVE THAT NYM FROM YOUR WALLET!! Create a "
422  "fresh Nym to use. ***\n");
423  return false;
424  }
425  // First try to get Credentials, if there are any.
426  //
427  OTASCIIArmor& ascArmor = theMessage.m_ascPayload; // credentialList
428  // (New style!
429  // Credentials.)
430  OTASCIIArmor& ascArmor2 = theMessage.m_ascPayload2; // credentials
431  const bool bHasCredentials = (ascArmor.Exists() && ascArmor2.Exists());
432  if (bHasCredentials) // New style of doing things, for Nym keys.
433  // Credentials!
434  {
435  // credentialList
436  //
437  OTString strCredentialList(ascArmor);
438 
439  if (strCredentialList.Exists()) {
440  std::unique_ptr<OTDB::Storable> pStorable(OTDB::DecodeObject(
441  OTDB::STORED_OBJ_STRING_MAP, ascArmor2.Get()));
442  OTDB::StringMap* pMap =
443  dynamic_cast<OTDB::StringMap*>(pStorable.get());
444  if (nullptr == pMap)
445  OTLog::vOutput(0, "%s: @createUserAccount: Failed decoding "
446  "StringMap object.\n",
447  __FUNCTION__);
448  else {
449  auto& theMap = pMap->the_map;
450  // NOTE: This action may very well be a malicious attacker
451  // saving a false
452  // credential list and a false set of credentials under a
453  // certain Nym ID!
454  // However, a Nym is always verified after loading, before
455  // being used for
456  // anything. (AND MUST BE.) And that includes before being
457  // saved to disk.
458  //
459  // DILEMMA at this point was, I don't want to save the
460  // credentials into the
461  // actual folder locations BEFORE they have been verified...
462  // SO I had to add "LoadFromString" functions to
463  // OTCredential (which I have done.)
464  // So now I should be able to continue here, load the
465  // credentials up from string,
466  // verify them, and if verified, THEN save them to disk...
467  // OTPseudonym::LoadFromString now allows you to load
468  // credentials from the map passed
469  // in (from the message) versus just reading them from local
470  // storage.
471  //
472  if (false ==
473  pNym->LoadFromString(strCredentialList, &theMap)) {
475  "%s: @createUserAccount: Failure loading nym %s "
476  "from credential string.\n",
477  __FUNCTION__, theMessage.m_strNymID.Get());
478  }
479  // Now that the Nym has been loaded up from the message
480  // parameters,
481  // including the list of credential IDs, and the map
482  // containing the
483  // credentials themselves, let's try to Verify the
484  // pseudonym. If we
485  // verify, then we're safe to save the credentials to
486  // storage.
487  //
488  else if (!pNym->VerifyPseudonym()) {
490  "%s: @createUserAccount: Loaded nym %s "
491  "from credentials, but then it failed verifying.\n",
492  __FUNCTION__, theMessage.m_strNymID.Get());
493  }
494  else // Okay, we loaded the Nym up from the credentials in
495  // the message, AND
496  { // verified the Nym (including the credentials.)
497  // So let's save it to local storage...
498  //
499 
500  OTLog::Output(3, "Pseudonym verified!\n");
501  // Okay, now that the Nym is verified, let's verify the
502  // message itself...
503  //
504  if (false ==
505  theMessage.VerifySignature(*pNym)) // FYI, OTMessage
506  // overrides
507  // VerifySignature with
508  // VerifySigAuthent.
509  { // (Because we use authentication keys, not signing
510  // keys, for messages.)
511  OTLog::Output(0, "@createUserAccount: "
512  "Authentication signature -- "
513  "verification failed!\n");
514  return false;
515  }
516  else {
518  3,
519  "Signature verified! The message WAS signed by "
520  "the Nym\'s private authentication key.\n");
521  // SAVE the credentials to local storage, now that
522  // things are verified.
523  //
524  std::string str_nym_id =
525  theMessage.m_strNymID.Get();
526  OTString strFilename;
527  strFilename.Format("%s.cred", str_nym_id.c_str());
528 
529  bool bStoredList = false;
530  OTString strOutput;
531 
532  if (ascArmor.Exists() &&
533  ascArmor.WriteArmoredString(
534  strOutput,
535  "CREDENTIAL LIST") && // bEscaped=false by
536  // default.
537  strOutput.Exists())
538  bStoredList = OTDB::StorePlainString(
539  strOutput.Get(), OTFolders::Pubcred().Get(),
540  strFilename.Get());
541  if (!bStoredList)
542  OTLog::vError("%s: @createUserAccount: Failed "
543  "trying to armor or store: %s\n",
544  __FUNCTION__, strFilename.Get());
545  else // IF the list saved, then we save the
546  // credentials themselves...
547  {
548  OTLog::vOutput(1, "@createUserAccount: Success "
549  "saving public credential "
550  "list for Nym: %s\n",
551  str_nym_id.c_str());
552  for (auto& it : theMap) {
553  std::string str_cred_id = it.first;
554  OTString strCredential(it.second);
555  bool bStoredCredential = false;
556  strOutput.Release();
557  OTASCIIArmor ascLoopArmor(strCredential);
558  if (ascLoopArmor.Exists() &&
559  ascLoopArmor.WriteArmoredString(
560  strOutput,
561  "CREDENTIAL") && // bEscaped=false
562  // by default.
563  strOutput.Exists())
564  bStoredCredential =
566  strOutput.Get(),
568  str_nym_id, str_cred_id);
569  if (!bStoredCredential)
571  "%s: @createUserAccount: Failed "
572  "trying to store credential %s for "
573  "nym %s.\n",
574  __FUNCTION__, str_cred_id.c_str(),
575  str_nym_id.c_str());
576  else
577  OTLog::vOutput(0, "@createUserAccount: "
578  "Success saving "
579  "public credential "
580  "ID: %s\n",
581  str_cred_id.c_str());
582  }
583  } // else (bStoredList)
584  // Make sure we are encrypting the message we send
585  // back, if possible.
586  //
587  OTString strPublicEncrKey, strPublicSignKey;
588  OTAsymmetricKey& thePublicEncrKey =
589  (OTAsymmetricKey&)
590  pNym->GetPublicEncrKey(); // todo cast
591  OTAsymmetricKey& thePublicSignKey =
592  (OTAsymmetricKey&)
593  pNym->GetPublicSignKey(); // todo cast
594 
595  thePublicEncrKey.GetPublicKey(
596  strPublicEncrKey,
597  false); // bEscaped=true by default
598  thePublicSignKey.GetPublicKey(
599  strPublicSignKey,
600  false); // bEscaped=true by default
601 
602  // We also (for now) set the Nym's keypair (which is
603  // being phased out entirely,
604  // and being replaced with credentials.)
605  //
606  if (strPublicSignKey.Exists())
607  pNym->SetPublicKey(
608  strPublicSignKey,
609  false); // bEscaped=true by default
610 
611  // This is only for verified Nyms, (and we're
612  // verified in here!) We do this so that
613  // we have the option later to encrypt the replies
614  // back to the client...(using the
615  // client's public key that we set here.)
616  if (strPublicEncrKey.Exists() &&
617  (nullptr != pConnection))
618  pConnection->SetPublicKey(thePublicEncrKey);
619  // Look up the NymID and see if it's already a valid
620  // user account.
621  //
622  // If it is, then we can't very well create it
623  // twice, can we?
624  //
625  // UPDATE: Actually we should, in such cases, just
626  // return true with
627  // a copy of the Nymfile. Helps prevent sync errors,
628  // and gives people
629  // a way to grab the server's copy of their nymfile,
630  // if they need it.
631  //
633  0, "Verifying account doesn't already exist... "
634  "(IGNORE ANY ERRORS, IMMEDIATELY BELOW, "
635  "ABOUT FAILURE OPENING FILES)\n");
636 
637  // Prepare to send success or failure back to user.
638  // (1) set up member variables
639  msgOut.m_strCommand =
640  "@createUserAccount"; // reply to
641  // createUserAccount
642  msgOut.m_strNymID = theMessage.m_strNymID; // UserID
643  msgOut.m_strServerID =
644  server_->m_strServerID; // ServerID, a hash of
645  // the server
646  // contract.
647  msgOut.m_bSuccess = false;
648 
649  // already done, top of this function.
650  // msgOut.m_strRequestNum.Set(theMessage.m_strRequestNum);
651  // // to prevent replay attacks.
652 
653  // We send the user's message back to him,
654  // ascii-armored,
655  // as part of our response.
656  OTString tempInMessage;
657  theMessage.SaveContractRaw(tempInMessage);
658  msgOut.m_ascInReferenceTo.SetString(tempInMessage);
659 
660  bool bLoadedSignedNymfile =
661  pNym->LoadSignedNymfile(server_->m_nymServer);
662 
663  // He ALREADY exists. We'll set success to true, and
664  // send him a copy of his own nymfile.
665  // (Signature is verified already anyway, by this
666  // point.)
667  //
668  if (bLoadedSignedNymfile &&
669  (false == pNym->IsMarkedForDeletion())) {
671  0,
672  "(Allowed in order to prevent sync issues) "
673  "==> User is registering nym that already "
674  "exists: %s\n",
675  theMessage.m_strNymID.Get());
676 
677  OTString strNymContents;
678  pNym->SavePseudonym(strNymContents);
679  OTIdentifier theNewNymID,
680  SERVER_ID(server_->m_strServerID);
681  pNym->GetIdentifier(theNewNymID);
682  OTLedger theNymbox(theNewNymID, theNewNymID,
683  SERVER_ID);
684  bool bSuccessLoadingNymbox =
685  theNymbox.LoadNymbox();
686 
687  if (true == bSuccessLoadingNymbox)
688  bSuccessLoadingNymbox =
689  (theNymbox.VerifyContractID() &&
690  theNymbox.VerifyAccount(
691  server_->m_nymServer));
692  // bSuccessLoadingNymbox
693  // =
694  // (theNymbox.VerifyAccount(server_->m_nymServer));
695  // //
696  // (No need here to load all the Box Receipts)
697  else {
698  bSuccessLoadingNymbox =
699  theNymbox.GenerateLedger(
700  theNewNymID, SERVER_ID,
702  true); // bGenerateFile=true
703 
704  if (bSuccessLoadingNymbox) {
705  bSuccessLoadingNymbox =
706  theNymbox.SignContract(
707  server_->m_nymServer);
708 
709  if (bSuccessLoadingNymbox) {
710  bSuccessLoadingNymbox =
711  theNymbox.SaveContract();
712 
713  if (bSuccessLoadingNymbox)
714  bSuccessLoadingNymbox =
715  theNymbox.SaveNymbox();
716  }
717  }
718  }
719  // by this point, the nymbox DEFINITELY exists
720  // -- or not. (generation might have failed, or
721  // verification.)
722  //
723  if (!bSuccessLoadingNymbox) {
724  OTLog::vError("Error during user account "
725  "re-registration. Failed "
726  "verifying or generating "
727  "nymbox for user: %s\n",
728  theMessage.m_strNymID.Get());
729  }
730  msgOut.m_ascPayload.SetString(strNymContents);
731  msgOut.m_bSuccess = bSuccessLoadingNymbox;
732  msgOut.SignContract(server_->m_nymServer);
733  msgOut.SaveContract();
734  return true;
735  }
736  else
737  // ((pNym->IsMarkedForDeletion()
738  // && (true == bLoadedPublicKey)) || // We
739  // allow people to resurrect deleted Nyms.
744  // (false ==
745  // bLoadedPublicKey))
746  // // can still buy usage credits.
747  {
748  if (pNym->IsMarkedForDeletion())
749  pNym->MarkAsUndeleted();
750 
751  // Good -- this means the account doesn't
752  // already exist.
753  // Let's create it.
754 
755  msgOut.m_bSuccess = theMessage.SaveContract(
756  OTFolders::UserAcct().Get(),
757  theMessage.m_strNymID.Get());
758 
759  // First we save the createUserAccount message
760  // in the accounts folder...
761  if (msgOut.m_bSuccess) {
762  OTLog::Output(0, "Success saving new user "
763  "account verification "
764  "file.\n");
765 
766  OTIdentifier theNewNymID,
767  SERVER_ID(server_->m_strServerID);
768  pNym->GetIdentifier(theNewNymID);
769  OTLedger theNymbox(theNewNymID, theNewNymID,
770  SERVER_ID);
771  bool bSuccessLoadingNymbox =
772  theNymbox.LoadNymbox();
773 
774  if (true == bSuccessLoadingNymbox) // that's
775  // strange, this
776  // user didn't
777  // exist... but
778  // maybe I allow
779  // people to drop
780  // notes anyway,
781  // so then the
782  // nymbox might
783  // already exist,
784  // with usage
785  // tokens and
786  // messages
787  // inside....
788  bSuccessLoadingNymbox =
789  (theNymbox.VerifyContractID() &&
790  theNymbox.VerifyAccount(
791  server_->m_nymServer));
792  // bSuccessLoadingNymbox
793  // =
794  // (theNymbox.VerifyAccount(server_->m_nymServer));
795  // // (No need here to load all the Box
796  // Receipts)
797  else {
798  bSuccessLoadingNymbox =
799  theNymbox.GenerateLedger(
800  theNewNymID, SERVER_ID,
802  true); // bGenerateFile=true
803  if (bSuccessLoadingNymbox) {
804  bSuccessLoadingNymbox =
805  theNymbox.SignContract(
806  server_->m_nymServer);
807  if (bSuccessLoadingNymbox) {
808  bSuccessLoadingNymbox =
809  theNymbox.SaveContract();
810 
811  if (bSuccessLoadingNymbox)
812  bSuccessLoadingNymbox =
813  theNymbox.SaveNymbox();
814  }
815  }
816  }
817  // by this point, the nymbox DEFINITELY
818  // exists -- or not. (generation might have
819  // failed, or verification.)
820 
821  if (!bSuccessLoadingNymbox) {
823  "Error during user account "
824  "registration. Failed verifying or "
825  "generating nymbox for user: %s\n",
826  theMessage.m_strNymID.Get());
827  }
828  // Either we loaded it up (it already
829  // existed) or we didn't, in which case we
830  // should
831  // save it now (to create it.)
832  //
833  else if (bLoadedSignedNymfile ||
834  pNym->SaveSignedNymfile(
835  server_->m_nymServer)) {
836  OTLog::vOutput(0, "Success creating "
837  "new Nym. (User "
838  "account fully "
839  "created.)\n");
840 
841  OTString strNymContents;
842  pNym->SavePseudonym(strNymContents);
843  msgOut.m_ascPayload.SetString(
844  strNymContents);
845  msgOut.m_bSuccess = true;
846  msgOut.SignContract(
847  server_->m_nymServer);
848  msgOut.SaveContract();
849  return true;
850  }
851  else {
852  msgOut.SignContract(
853  server_->m_nymServer);
854  msgOut.SaveContract();
855  return true;
856  }
857  }
858  else {
859  OTLog::Error("Error saving new user "
860  "account verification "
861  "file.\n");
862  msgOut.SignContract(server_->m_nymServer);
863  msgOut.SaveContract();
864  return true;
865  }
866  }
867  return true;
868  }
869  } // Success loading and verifying the Nym based on his
870  // credentials.
871  } // Success decoding the map of credentials from the message.
872  } // credential list exists, after base64-decoding.
873  } // Has Credentials.
874  }
875  // Look up the NymID and see if it's a valid user account.
876  //
877  // If we didn't receive a public key (above)
878  // Or read one from our files (below)
879  // ... then we'd have no way of validating the requests.
880  //
881  // If it is, then we read the public key from that Pseudonym and use it to
882  // verify any
883  // requests bearing that NymID.
884  if (!bNymIsServerNym &&
885  (false == pNym->LoadPublicKey()) // && // Old style. (Deprecated, but
886  // fine for now since it calls
887  // LoadCredentials.)
888  ) {
889  OTLog::vError("Failure loading public credentials for Nym: %s\n",
890  theMessage.m_strNymID.Get());
891  return false;
892  }
893  if (!bNymIsServerNym && pNym->IsMarkedForDeletion()) {
894  OTLog::vOutput(0,
895  "(Failed) attempt by client to use a deleted Nym: %s\n",
896  theMessage.m_strNymID.Get());
897  return false;
898  }
899  // Okay, the file was read into memory and Public Key was successfully
900  // extracted!
901  // Next, let's use that public key to verify (1) the NymID and (2) the
902  // signature
903  // on the message that we're processing.
904 
905  if (pNym->VerifyPseudonym()) {
906  OTLog::Output(3, "Pseudonym verified!\n");
907 
908  // So far so good. Now let's see if the signature matches...
909  if (theMessage.VerifySignature(*pNym)) {
910  OTLog::Output(3, "Signature verified! The message WAS signed by "
911  "the Nym\'s private key.\n");
912 
913  // Get the public key from pNym, and set it into the connection.
914  // This is only for verified Nyms, (and we're verified in here!) We
915  // do this so that
916  // we have the option later to encrypt the replies back to the
917  // client...(using the
918  // client's public key that we set here.)
919  if (nullptr != pConnection)
920  pConnection->SetPublicKey(pNym->GetPublicEncrKey());
921 
922  // Now we might as well load up the rest of the Nym.
923  // Notice I use the || to only load the nymfile if it's NOT the
924  // server Nym.
925  if (bNymIsServerNym ||
926  pNym->LoadSignedNymfile(server_->m_nymServer)) {
927  OTLog::Output(2, "Successfully loaded Nymfile into memory.\n");
928 
929  // ENTERING THE INNER SANCTUM OF SECURITY. If the user got all
930  // the way to here,
931  // Then he has passed multiple levels of security, and all
932  // commands below will
933  // assume the Nym is secure, validated, and loaded into memory
934  // for use.
935  //
936  // But still need to verify the Request Number for all other
937  // commands except
938  // Get Request Number itself...
939 
940  // Request numbers start at 100 (currently). (Since certain
941  // special messages USE 1 already...
942  // Such as messages that occur before requestnumbers are
943  // possible, like CreateUserAccount.)
944  //
945  int64_t lRequestNumber = 0;
946 
947  if (false ==
948  pNym->GetCurrentRequestNum(server_->m_strServerID,
949  lRequestNumber)) {
950  OTLog::Output(0, "Nym file request number doesn't exist. "
951  "Apparently first-ever request to "
952  "server--but everything checks out. "
953  "(Shouldn't this request number have been "
954  "created already when the NymFile was "
955  "first created???????\n");
956  // FIRST TIME! This account has never before made a single
957  // request to this server.
958  // The above call always succeeds unless the number just
959  // isn't there for that server.
960  // Therefore, since it's the first time, we'll create it
961  // now:
962  pNym->IncrementRequestNum(server_->m_nymServer,
963  server_->m_strServerID);
964 
965  // Call it again so that lRequestNumber is set to 1 also
966  if (pNym->GetCurrentRequestNum(server_->m_strServerID,
967  lRequestNumber)) {
968  OTLog::Output(0, "Created first request number in Nym "
969  "file, apparently first-ever request. "
970  "(Shouldn't this have been created "
971  "already when the NymFile was first "
972  "created???????\n");
973  }
974  else {
975  OTLog::Error("ERROR creating first request number in "
976  "Nym file.\n");
977  return false;
978  }
979  }
980 
981  // At this point, I now have the current request number for this
982  // nym in lRequestNumber
983  // Let's compare it to the one that was sent in the message...
984  // (This prevents attackers
985  // from repeat-sending intercepted messages to the server.)
986  if (false ==
987  theMessage.m_strCommand.Compare(
988  "getRequest")) // IF it's NOT a getRequest CMD,
989  // (therefore requires a request
990  // number)
991  {
992  if (lRequestNumber !=
993  atol(theMessage.m_strRequestNum.Get())) // AND the
994  // request
995  // number
996  // attached does
997  // not match
998  // what we just
999  // read out of
1000  // the file...
1001  {
1002  OTLog::vOutput(0, "Request number sent in this message "
1003  "%ld does not match the one in the "
1004  "file! (%ld)\n",
1005  atol(theMessage.m_strRequestNum.Get()),
1006  lRequestNumber);
1007  return false;
1008  }
1009  else // it's not a getRequest CMD, and the request number
1010  // sent DOES match what we read out of the file!!
1011  {
1012  // USAGE CREDITS...
1013  // Since (just below) we IncrementRequestNum() and
1014  // therefore save the Nym,
1015  // I figured it's a good spot to do our Usage Credits
1016  // code, so we don't have
1017  // to save twice.
1018  // IF (the OT Server is in "require usage credits" mode)
1019  // AND the User isn't magically FREE from
1020  // having to use usage credits (-1 is a
1021  // get-out-of-jail-free-card.)
1022  // AND (there's no Override Nym ID listed
1023  // --OR-- the Override Nym ID doesn't
1024  // match the Nym's ID who sent this message
1026  pNym->GetUsageCredits() >= 0 &&
1027  (ServerSettings::GetOverrideNymID().size() <= 0 ||
1028  (0 !=
1030  (theMessage.m_strNymID.Get()))))) {
1031  const int64_t& lUsageCredits =
1032  pNym->GetUsageCredits();
1033 
1034  if (0 == lUsageCredits) // If the User has ZERO
1035  // USAGE CREDITS LEFT. (Too
1036  // bad, even 1 would have
1037  // squeezed him by here.)
1038  {
1039  OTLog::vOutput(0, "Nym %s: ALL OUT of Usage "
1040  "Credits, while server is in "
1041  "**REQUIRE USAGE CREDITS "
1042  "MODE**!\n",
1043  theMessage.m_strNymID.Get());
1044  return false;
1045  }
1046 
1047  const int64_t lUsageFinal = (lUsageCredits - 1);
1048  pNym->SetUsageCredits(lUsageFinal);
1049  }
1050 
1051  OTLog::vOutput(3, "Request number sent in this message "
1052  "%ld DOES match the one in the "
1053  "file!\n",
1054  lRequestNumber);
1055 
1056  // At this point, it is some OTHER command (besides
1057  // getRequest)
1058  // AND the request number verifies, so we're going to
1059  // increment
1060  // the number, and let the command process.
1061  pNym->IncrementRequestNum(server_->m_nymServer,
1062  server_->m_strServerID);
1063 
1064  // **INSIDE** THE INNER SANCTUM OF SECURITY. If the user
1065  // got all the way to here,
1066  // Then he has passed multiple levels of security, and
1067  // all commands below will
1068  // assume the Nym is secure, validated, and loaded into
1069  // memory for use. They can
1070  // also assume that the request number has been verified
1071  // on this message.
1072  // EVERYTHING checks out.
1073 
1074  // NO RETURN HERE!!!! ON PURPOSE!!!!
1075  }
1076 
1077  }
1078  else // If you entered this else, that means it IS a
1079  // getRequest command
1080  // So we allow it to go through without verifying this step,
1081  // and without incrementing the counter.
1082  {
1083  // pNym->IncrementRequestNum(server_->m_strServerID); //
1084  // commented
1085  // out cause this is the one case where we DON'T increment
1086  // this number.
1087  // We allow the user to get the number, we DON'T increment
1088  // it, and now the user
1089  // can send it on his next request for some other command,
1090  // and it will verify
1091  // properly. This prevents repeat messages.
1092 
1093  // NO RETURN HERE!!!! ON PURPOSE!!!!
1094  }
1095 
1096  // At this point, we KNOW that it is EITHER a GetRequest
1097  // command, which doesn't require a request number,
1098  // OR it was some other command, but the request number they
1099  // sent in the command MATCHES the one that we
1100  // just read out of the file.
1101 
1102  // Therefore, we can process ALL messages below this
1103  // point KNOWING that the Nym is properly verified in all ways.
1104  // No messages need to worry about verifying the Nym, or about
1105  // dealing with the Request Number. It's all handled in here.
1106 
1107  }
1108  else {
1109  OTLog::vError("Error loading Nymfile: %s\n",
1110  theMessage.m_strNymID.Get());
1111  return false;
1112  }
1113  }
1114  else {
1115  OTLog::Output(0, "Signature verification failed!\n");
1116  return false;
1117  }
1118  }
1119  else {
1120  OTLog::Output(
1121  0, "Pseudonym failed to verify. Hash of public key doesn't match "
1122  "Nym ID that was sent.\n");
1123  return false;
1124  }
1125 
1126  // If you made it down this far, that means the Pseudonym verifies! The
1127  // message is legit.
1128  //
1129  // (Server ID was good, NymID is a valid hash of User's public key, and the
1130  // Signature on
1131  // the message was signed by the user's private key.)
1132  //
1133  // Now we can process the message.
1134  //
1135  // All the commands below here, it is assumed that the user account exists
1136  // and is
1137  // referenceable via pNym. (An OTPseudonym object.)
1138  //
1139  // ALL commands below can assume the Nym is real, and that the NymID and
1140  // Public Key are
1141  // available for use -- and that they verify -- without having to check
1142  // again and again.
1143 
1144  // ACKNOWLEDGMENTS OF REPLIES ALREADY RECEIVED (FOR OPTIMIZATION.)
1145 
1146  // On the client side, whenever the client is DEFINITELY made aware of the
1147  // existence of a
1148  // server reply, he adds its request number to this list, which is sent
1149  // along with all client-side
1150  // requests to the server.
1151  // The server reads the list on the incoming client message (and it uses
1152  // these same functions
1153  // to store its own internal list.) If the # already appears on its internal
1154  // list, then it does
1155  // nothing. Otherwise, it loads up the Nymbox and removes the replyNotice,
1156  // and then adds the #
1157  // to its internal list.
1158  // For any numbers on the internal list but NOT on the client's list, the
1159  // server removes from
1160  // the internal list. (The client removed them when it saw the server's
1161  // internal list, which the
1162  // server sends with its replies.)
1163  //
1164  // This entire protocol, densely described, is unnecessary for OT to
1165  // function, but is great for
1166  // optimization, as it enables OT to avoid downloading all Box Receipts
1167  // containing replyNotices,
1168  // as long as the original reply was properly received when the request was
1169  // originally sent (which
1170  // is MOST of the time...)
1171  // Thus we can eliminate most replyNotice downloads, and likely a large % of
1172  // box receipt downloads
1173  // as well.
1174  //
1175 
1176  const OTIdentifier SERVER_ID(server_->m_strServerID);
1177 
1178  // The server reads the list of acknowledged replies from the incoming
1179  // client message...
1180  //
1181  bool bIsDirtyNym = false; // if we add any acknowledged replies to the
1182  // server-side list, we will want to save (at the
1183  // end.)
1184  std::set<int64_t> numlist_ack_reply;
1185  if (theMessage.m_AcknowledgedReplies.Output(
1186  numlist_ack_reply)) // returns false if the numlist was empty.
1187  {
1188  // Load Nymbox
1189  //
1190  OTLedger theNymbox(pNym->GetConstID(), pNym->GetConstID(), SERVER_ID);
1191 
1192  if (theNymbox.LoadNymbox() &&
1193  theNymbox.VerifySignature(server_->m_nymServer)) {
1194  // if we remove any replyNotices from the Nymbox, then we will want
1195  // to save the Nymbox (at the end.)
1196  bool bIsDirtyNymbox = false;
1197 
1198  for (auto& it : numlist_ack_reply) {
1199  const int64_t lRequestNum = it;
1200  // If the # already appears on its internal list, then it does
1201  // nothing. (It must have already done
1202  // whatever it needed to do, since it already has the number
1203  // recorded as acknowledged.)
1204  //
1205  // Otherwise, if the # does NOT already appear on server's
1206  // internal list, then it loads up the
1207  // Nymbox and removes the replyNotice, and then adds the # to
1208  // its internal list for safe-keeping.
1209  //
1210  if (false ==
1211  pNym->VerifyAcknowledgedNum(server_->m_strServerID,
1212  lRequestNum)) {
1213  // Verify whether a replyNotice exists in the Nymbox, with
1214  // that lRequestNum
1215  //
1216  OTTransaction* pReplyNotice =
1217  theNymbox.GetReplyNotice(lRequestNum);
1218 
1219  if (nullptr != pReplyNotice) {
1220  // If so, remove it...
1221  //
1222  const bool bDeleted =
1223  pReplyNotice->DeleteBoxReceipt(theNymbox);
1224  const bool bRemoved = theNymbox.RemoveTransaction(
1225  pReplyNotice->GetTransactionNum()); // deletes
1226  pReplyNotice = nullptr;
1227  // (pReplyNotice is deleted, below this point,
1228  // automatically by the above Remove call.)
1229 
1230  if (!bDeleted || !bRemoved)
1231  OTLog::Error(
1232  "UserCommandProcessor::ProcessUserCommand: "
1233  "Failed trying "
1234  "to delete a box receipt, or "
1235  "while removing its stub from the Nymbox.\n");
1236 
1237  // ...and add lRequestNum to server's acknowledgment
1238  // list. (So this can't happen twice with same #.)
1239  //
1240  if (pNym->AddAcknowledgedNum(
1241  server_->m_strServerID,
1242  lRequestNum)) // doesn't save (here).
1243  bIsDirtyNym = true; // So we don't have to save EACH
1244  // iteration, but instead just
1245  // once at the bottom.
1246 
1247  if (bRemoved)
1248  bIsDirtyNymbox = true; // So we don't have to save
1249  // EACH iteration, but
1250  // instead just once at the
1251  // bottom.
1252  }
1253  } // If server didn't already have a record of this acknowledged
1254  // request #.
1255  }
1256 
1257  if (bIsDirtyNymbox) {
1258  theNymbox.ReleaseSignatures();
1259  theNymbox.SignContract(server_->m_nymServer);
1260  theNymbox.SaveContract();
1261  theNymbox.SaveNymbox();
1262  }
1263  } // If nymbox loaded and verified.
1264  }
1265 
1266  // For any numbers on the server's internal list but NOT on the client's
1267  // list, the server removes from
1268  // the internal list. (Because the client must have seen my acknowledgment
1269  // and thus removed the number
1270  // from its own list, so the server doesn't need to display it anymore.)
1271  //
1272  // Thus: iterate through the server's list of numbers, and see if each is on
1273  // the client's list. If not,
1274  // then remove it from my own (server's) internal list as well.
1275  //
1276  OTNumList numlist_to_remove; // a temp variable where we will put the
1277  // numbers "to be removed" (so we can remove
1278  // them all at once, after the loop.)
1279  const int32_t nAcknowledgedNumCount =
1280  pNym->GetAcknowledgedNumCount(SERVER_ID);
1281 
1282  if (nAcknowledgedNumCount > 0) {
1283  for (int32_t i = 0; i < nAcknowledgedNumCount; i++) {
1284  const int64_t lAcknowledgedNum =
1285  pNym->GetAcknowledgedNum(SERVER_ID, i); // index
1286 
1287  // For any numbers on the server's internal list but NOT on the
1288  // client's list (according
1289  // to the incoming message) the server removes them from its
1290  // internal list. (If the client
1291  // is done with them, then so is the server.)
1292  //
1293  if (false ==
1294  theMessage.m_AcknowledgedReplies.Verify(lAcknowledgedNum)) {
1295  numlist_to_remove.Add(lAcknowledgedNum);
1296  }
1297  } // for
1298  if (numlist_to_remove.Count() > 0) {
1299  std::set<int64_t> set_server_ack;
1300  if (numlist_to_remove.Output(set_server_ack)) {
1301  for (auto& it : set_server_ack) {
1302  const int64_t lRequestNum = it;
1303  if (pNym->RemoveAcknowledgedNum(
1304  server_->m_nymServer, server_->m_strServerID,
1305  lRequestNum, false)) // bSave=false
1306  bIsDirtyNym = true;
1307  }
1308  }
1309  }
1310  } // if there are server-side ack numbers that could potentially be removed,
1311  // if client's message doesn't list them.
1312 
1313  if (bIsDirtyNym) {
1314  pNym->SaveSignedNymfile(server_->m_nymServer); // we save here.
1315  }
1316 
1317  // Note: in the ultimate future, we wouldn't even save the Nym down here,
1318  // but we'll let the entire message process
1319  // and then save the Nym at the end.
1320  // Then again -- you'd still want to know if the Nym was locked, at each
1321  // "save attempt" along the way. Because even
1322  // though the Nym might not actually save at each of those signposts, it
1323  // should still CANCEL OUT IF IT WOULD FAIL TRYING.
1324  // Of course we still only want to save the Nym once, but we still want each
1325  // step along the way -- each vital step that
1326  // would normally have saved each time -- to know whether or not it will
1327  // actually work, and if not, to fail the message
1328  // AT THAT POINT and not somewhere much later, at the bottom, after all
1329  // kinds of other processing has been done.
1330  //
1331  // Therefore in the new version we will probably still "Save" the Nym at
1332  // each critical point, but INTERNALLY, it won't
1333  // actually save until the bottom. BUT, even though it won't actually save,
1334  // it will still know if the TIMESTAMP IS WITHIN
1335  // VALID RANGE (each time), and it will still know that it has definitely
1336  // locked the resource (which happens the first time)
1337  // and it will still want to set the resource as dirty, internally, even
1338  // when it doesn't save it right away, because otherwise
1339  // it wouldn't know to save it later, either.
1340 
1341  msgOut.m_strServerID = server_->m_strServerID;
1342  msgOut.SetAcknowledgments(*pNym); // Must be called AFTER
1343  // msgOut.m_strServerID is already set.
1344  // (It uses it.)
1345 
1346  if (theMessage.m_strCommand.Compare("getRequest")) // This command is
1347  // special because it's
1348  // the only one that
1349  // doesn't require a
1350  // request number.
1351  // All of the other commands, below, will fail above if the proper
1352  // request number isn't included
1353  // in the message. They will already have failed by this point if they
1354  // didn't verify.
1355  {
1356  OTLog::vOutput(0, "\n==> Received a getRequest message. Nym: %s ...\n",
1357  strMsgNymID.Get());
1358 
1360 
1361  UserCmdGetRequest(*pNym, theMessage, msgOut);
1362 
1363  return true;
1364  }
1365  else if (theMessage.m_strCommand.Compare("getTransactionNum")) {
1367  0, "\n==> Received a getTransactionNum message. Nym: %s ...\n",
1368  strMsgNymID.Get());
1369 
1371 
1372  UserCmdGetTransactionNum(*pNym, theMessage, msgOut);
1373 
1374  return true;
1375  }
1376  else if (theMessage.m_strCommand.Compare("checkUser")) {
1377  OTLog::vOutput(0, "\n==> Received a checkUser message. Nym: %s ...\n",
1378  strMsgNymID.Get());
1379 
1381 
1382  UserCmdCheckUser(*pNym, theMessage, msgOut);
1383 
1384  return true;
1385  }
1386  else if (theMessage.m_strCommand.Compare("sendUserMessage")) {
1388  0, "\n==> Received a sendUserMessage message. Nym: %s ...\n",
1389  strMsgNymID.Get());
1390 
1392 
1393  UserCmdSendUserMessage(*pNym, theMessage, msgOut);
1394 
1395  return true;
1396  }
1397  else if (theMessage.m_strCommand.Compare("sendUserInstrument")) {
1399  0, "\n==> Received a sendUserInstrument message. Nym: %s ...\n",
1400  strMsgNymID.Get());
1401 
1403 
1404  UserCmdSendUserInstrument(*pNym, theMessage, msgOut);
1405 
1406  return true;
1407  }
1408  else if (theMessage.m_strCommand.Compare("deleteUserAccount")) {
1410  0, "\n==> Received a deleteUserAccount message. Nym: %s ...\n",
1411  strMsgNymID.Get());
1412 
1414 
1415  UserCmdDeleteUser(*pNym, theMessage, msgOut);
1416 
1417  return true;
1418  }
1419  else if (theMessage.m_strCommand.Compare("deleteAssetAccount")) {
1421  0, "\n==> Received a deleteAssetAccount message. Nym: %s ...\n",
1422  strMsgNymID.Get());
1423 
1425 
1426  UserCmdDeleteAssetAcct(*pNym, theMessage, msgOut);
1427 
1428  return true;
1429  }
1430  else if (theMessage.m_strCommand.Compare("createAccount")) {
1431  OTLog::vOutput(0,
1432  "\n==> Received a createAccount message. Nym: %s ...\n",
1433  strMsgNymID.Get());
1434 
1436 
1437  UserCmdCreateAccount(*pNym, theMessage, msgOut);
1438 
1439  return true;
1440  }
1441  else if (theMessage.m_strCommand.Compare("issueAssetType")) {
1443  0, "\n==> Received an issueAssetType message. Nym: %s ...\n",
1444  strMsgNymID.Get());
1445 
1447 
1448  UserCmdIssueAssetType(*pNym, theMessage, msgOut);
1449 
1450  return true;
1451  }
1452  else if (theMessage.m_strCommand.Compare("issueBasket")) {
1453  OTLog::vOutput(0,
1454  "\n==> Received an issueBasket message. Nym: %s ...\n",
1455  strMsgNymID.Get());
1456 
1458 
1459  UserCmdIssueBasket(*pNym, theMessage, msgOut);
1460 
1461  return true;
1462  }
1463  else if (theMessage.m_strCommand.Compare("notarizeTransactions")) {
1464  OTLog::vOutput(0, "\n==> Received a notarizeTransactions message. "
1465  "Acct: %s Nym: %s ...\n",
1466  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1467 
1469 
1470  UserCmdNotarizeTransactions(*pNym, theMessage, msgOut);
1471 
1472  return true;
1473  }
1474  else if (theMessage.m_strCommand.Compare("getNymbox")) {
1475  OTLog::vOutput(0, "\n==> Received a getNymbox message. Nym: %s ...\n",
1476  strMsgNymID.Get());
1477 
1479 
1480  UserCmdGetNymbox(*pNym, theMessage, msgOut);
1481 
1482  return true;
1483  }
1484  else if (theMessage.m_strCommand.Compare("getBoxReceipt")) {
1485  OTLog::vOutput(0,
1486  "\n==> Received a getBoxReceipt message. Nym: %s ...\n",
1487  strMsgNymID.Get());
1488 
1489  bool bRunIt = true;
1490  if (0 == theMessage.m_lDepth)
1492  else if (1 == theMessage.m_lDepth)
1493  OT_ENFORCE_PERMISSION_MSG(ServerSettings::__cmd_get_inbox)
1494  else if (2 == theMessage.m_lDepth)
1495  OT_ENFORCE_PERMISSION_MSG(ServerSettings::__cmd_get_outbox)
1496  else
1497  bRunIt = false;
1498 
1499  if (bRunIt) UserCmdGetBoxReceipt(*pNym, theMessage, msgOut);
1500 
1501  return true;
1502  }
1503  else if (theMessage.m_strCommand.Compare("getInbox")) {
1505  0, "\n==> Received a getInbox message. Acct: %s Nym: %s ...\n",
1506  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1507 
1509 
1510  UserCmdGetInbox(*pNym, theMessage, msgOut);
1511 
1512  return true;
1513  }
1514  else if (theMessage.m_strCommand.Compare("getOutbox")) {
1516  0, "\n==> Received a getOutbox message. Acct: %s Nym: %s ...\n",
1517  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1518 
1520 
1521  UserCmdGetOutbox(*pNym, theMessage, msgOut);
1522 
1523  return true;
1524  }
1525  else if (theMessage.m_strCommand.Compare("getAccount")) {
1527  0, "\n==> Received a getAccount message. Acct: %s Nym: %s ...\n",
1528  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1529 
1531 
1532  UserCmdGetAccount(*pNym, theMessage, msgOut);
1533 
1534  return true;
1535  }
1536  else if (theMessage.m_strCommand.Compare("getAccountFiles")) {
1537  OTLog::vOutput(0, "\n==> Received a getAccountFiles message. Acct: %s "
1538  "Nym: %s ...\n",
1539  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1540 
1544 
1545  UserCmdGetAccountFiles(*pNym, theMessage, msgOut);
1546 
1547  return true;
1548  }
1549  else if (theMessage.m_strCommand.Compare("processNymbox")) {
1550  OTLog::vOutput(0,
1551  "\n==> Received a processNymbox message. Nym: %s ...\n",
1552  strMsgNymID.Get());
1553 
1555 
1556  UserCmdProcessNymbox(*pNym, theMessage, msgOut);
1557 
1558  return true;
1559  }
1560  else if (theMessage.m_strCommand.Compare("processInbox")) {
1562  0, "\n==> Received a processInbox message. Acct: %s Nym: %s ...\n",
1563  theMessage.m_strAcctID.Get(), strMsgNymID.Get());
1564 
1566 
1567  UserCmdProcessInbox(*pNym, theMessage, msgOut);
1568 
1569  return true;
1570  }
1571  else if (theMessage.m_strCommand.Compare("queryAssetTypes")) {
1573  0, "\n==> Received a queryAssetTypes message. Nym: %s ...\n",
1574  strMsgNymID.Get());
1575 
1577 
1578  UserCmdQueryAssetTypes(*pNym, theMessage, msgOut);
1579 
1580  return true;
1581  }
1582  else if (theMessage.m_strCommand.Compare("getContract")) {
1583  OTLog::vOutput(0, "\n==> Received a getContract message. Nym: %s ...\n",
1584  strMsgNymID.Get());
1585 
1587 
1588  UserCmdGetContract(*pNym, theMessage, msgOut);
1589 
1590  return true;
1591  }
1592  else if (theMessage.m_strCommand.Compare("getMint")) {
1593  OTLog::vOutput(0, "\n==> Received a getMint message. Nym: %s ...\n",
1594  strMsgNymID.Get());
1595 
1597 
1598  UserCmdGetMint(*pNym, theMessage, msgOut);
1599 
1600  return true;
1601  }
1602  else if (theMessage.m_strCommand.Compare("getMarketList")) {
1603  OTLog::vOutput(0,
1604  "\n==> Received a getMarketList message. Nym: %s ...\n",
1605  strMsgNymID.Get());
1606 
1608 
1609  UserCmdGetMarketList(*pNym, theMessage, msgOut);
1610 
1611  return true;
1612  }
1613  else if (theMessage.m_strCommand.Compare("getMarketOffers")) {
1615  0, "\n==> Received a getMarketOffers message. Nym: %s ...\n",
1616  strMsgNymID.Get());
1617 
1619 
1620  UserCmdGetMarketOffers(*pNym, theMessage, msgOut);
1621 
1622  return true;
1623  }
1624  else if (theMessage.m_strCommand.Compare("getMarketRecentTrades")) {
1626  0, "\n==> Received a getMarketRecentTrades message. Nym: %s ...\n",
1627  strMsgNymID.Get());
1628 
1631 
1632  UserCmdGetMarketRecentTrades(*pNym, theMessage, msgOut);
1633 
1634  return true;
1635  }
1636  else if (theMessage.m_strCommand.Compare("getNym_MarketOffers")) {
1638  0, "\n==> Received a getNym_MarketOffers message. Nym: %s ...\n",
1639  strMsgNymID.Get());
1640 
1642 
1643  UserCmdGetNym_MarketOffers(*pNym, theMessage, msgOut);
1644 
1645  return true;
1646  }
1647  else if (theMessage.m_strCommand.Compare("triggerClause")) {
1648  OTLog::vOutput(0,
1649  "\n==> Received a triggerClause message. Nym: %s ...\n",
1650  strMsgNymID.Get());
1651 
1653 
1654  UserCmdTriggerClause(*pNym, theMessage, msgOut);
1655 
1656  return true;
1657  }
1658  else if (theMessage.m_strCommand.Compare("usageCredits")) {
1659  OTLog::vOutput(0,
1660  "\n==> Received a usageCredits message. Nym: %s ...\n",
1661  strMsgNymID.Get());
1662 
1664 
1665  UserCmdUsageCredits(*pNym, theMessage, msgOut);
1666 
1667  return true;
1668  }
1669  else {
1670  OTLog::vError("Unknown command type in the XML, or missing payload, in "
1671  "ProcessMessage.\n");
1672 
1673  OTString strTemp;
1674  strTemp.Format("@%s", theMessage.m_strCommand.Get()); // Todo security.
1675  // Review this.
1676 
1677  msgOut.m_strCommand = strTemp;
1678  msgOut.m_strAcctID = theMessage.m_strAcctID;
1679  msgOut.m_strServerID = theMessage.m_strServerID;
1680  msgOut.m_strNymID = theMessage.m_strNymID;
1681 
1682  msgOut.m_bSuccess = false;
1683 
1684  OTString strRef(theMessage);
1685 
1686  msgOut.m_ascInReferenceTo.SetString(strRef);
1687 
1688  msgOut.SignContract(server_->m_nymServer);
1689  msgOut.SaveContract();
1690 
1691  return false;
1692  }
1693 }
static EXPORT void vError(const char *szError,...)
Definition: OTLog.cpp:800
EXPORT bool StorePlainString(std::string strContents, std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
Definition: OTStorage.cpp:698
static EXPORT OTAsymmetricKey * KeyFactory()
static EXPORT void Output(int32_t nVerbosity, const char *szOutput)
Definition: OTLog.cpp:710
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
static EXPORT const OTString & Pubcred()
Definition: OTFolders.cpp:343
static bool __cmd_create_asset_acct
static const std::string & GetOverrideNymID()
static EXPORT const OTString & UserAcct()
Definition: OTFolders.cpp:379
static EXPORT void Error(const char *szError)
Definition: OTLog.cpp:831
EXPORT bool Compare(const char *compare) const
Definition: OTString.cpp:1102
#define OT_ASSERT(x)
Definition: Assert.hpp:150
static bool __cmd_get_nym_market_offers
EXPORT const char * Get() const
Definition: OTString.cpp:1045
static bool __cmd_create_user_acct
EXPORT Storable * DecodeObject(StoredObjectType theObjectType, std::string strInput)
Definition: OTStorage.cpp:830
#define OT_ENFORCE_PERMISSION_MSG(BOOL_VAR_NAME)
Definition: Macros.hpp:151
static bool __cmd_get_market_offers
static bool __cmd_notarize_transaction
static EXPORT void vOutput(int32_t nVerbosity, const char *szOutput,...)
Definition: OTLog.cpp:768
static bool __cmd_get_market_recent_trades

The documentation for this class was generated from the following files: