espcontext.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning( disable : 4786 )
  14. #include "esphttp.hpp"
  15. #include "jliball.hpp"
  16. #include "espcontext.hpp"
  17. #include "txsummary.hpp"
  18. #include "http/platform/httptransport.ipp"
  19. #include "sechandler.hpp"
  20. #include "espprotocol.hpp"
  21. #include "espsecurecontext.hpp"
  22. #include "ldapsecurity.ipp"
  23. #include "dasds.hpp"
  24. class CEspContext : public CInterface, implements IEspContext
  25. {
  26. private:
  27. StringAttr m_userid;
  28. StringAttr m_password;
  29. StringAttr m_realm;
  30. StringAttr m_path;
  31. StringAttr m_peer;
  32. StringAttr m_useragent;
  33. StringAttr m_acceptLanguage;
  34. StringAttr httpMethod;
  35. StringAttr servMethod;
  36. StringAttr esdlBindingID;
  37. StringBuffer m_servName;
  38. StringBuffer m_servHost;
  39. short m_servPort;
  40. Owned<ISecUser> m_user;
  41. Owned<ISecResourceList> m_resources;
  42. Owned<ISecManager> m_secmgr;
  43. Owned<IAuthMap> m_feature_authmap;
  44. Owned<ISecPropertyList> m_sec_settings;
  45. void *m_bindingValue;
  46. void *m_serviceValue;
  47. bool m_toBeAuthenticated;
  48. double m_clientVer;
  49. Owned<IProperties> m_queryparams;
  50. Owned<IProperties> xslParameters;
  51. Owned<IMapInfo> m_mapinfo;
  52. StringArray m_custom_headers;
  53. unsigned options;
  54. SecHandler m_SecurityHandler;
  55. BoolHash m_optGroups;
  56. Owned<CTxSummary> m_txSummary;
  57. unsigned m_active;
  58. unsigned m_creationTime;
  59. unsigned m_processingTime;
  60. unsigned m_exceptionTime;
  61. bool m_hasException;
  62. int m_exceptionCode;
  63. StringAttr respMsg;
  64. StringAttr authStatus = AUTH_STATUS_NA;
  65. StringAttr authenticationMethod;
  66. AuthType domainAuthType = AuthPerRequestOnly;
  67. AuthError authError = EspAuthErrorNone;
  68. ESPSerializationFormat respSerializationFormat;
  69. Owned<IEspSecureContext> m_secureContext;
  70. StringAttr m_transactionID;
  71. StringBuffer m_globalId;
  72. StringBuffer m_localId;
  73. StringBuffer m_callerId;
  74. IHttpMessage* m_request;
  75. public:
  76. IMPLEMENT_IINTERFACE;
  77. CEspContext(IEspSecureContext* secureContext)
  78. : m_servPort(0)
  79. , m_bindingValue(0)
  80. , m_serviceValue(0)
  81. , m_toBeAuthenticated(false)
  82. , m_clientVer(-1)
  83. , options(0)
  84. , m_active(ActiveRequests::getCount())
  85. , m_creationTime(msTick())
  86. , m_processingTime(0)
  87. , m_exceptionTime(0)
  88. , m_hasException(false)
  89. , m_exceptionCode(0)
  90. , respSerializationFormat(ESPSerializationANY)
  91. {
  92. m_txSummary.setown(new CTxSummary(m_creationTime));
  93. updateTraceSummaryHeader();
  94. m_secureContext.setown(secureContext);
  95. m_SecurityHandler.setSecureContext(secureContext);
  96. appendGloballyUniqueId(m_localId);
  97. // use localId as globalId unless we receive another
  98. m_globalId.set(m_localId);
  99. }
  100. ~CEspContext()
  101. {
  102. flushTraceSummary();
  103. if (m_txSummary)
  104. {
  105. m_txSummary->tailor(this);
  106. m_txSummary->log(getTxSummaryLevel(), getTxSummaryGroup(), getTxSummaryStyle());
  107. }
  108. }
  109. virtual void addOptions(unsigned opts){options|=opts;}
  110. virtual void removeOptions(unsigned opts){opts&=~opts;}
  111. virtual unsigned queryOptions(){return options;}
  112. // versioning
  113. virtual double getClientVersion(){return m_clientVer;}
  114. virtual void setClientVersion(double ver){m_clientVer=ver;}
  115. virtual bool checkMinVer(double minVer) { return m_clientVer<0 || m_clientVer >= minVer; }
  116. virtual bool checkMaxVer(double maxVer) { return m_clientVer<0 || m_clientVer <= maxVer; }
  117. virtual bool checkMinMaxVer(double minVer, double maxVer) { return m_clientVer<0 || m_clientVer>= minVer || m_clientVer <= maxVer; }
  118. virtual bool checkOptional(const char* option)
  119. {
  120. if (option && *option == '!')
  121. return !m_queryparams.get() || !m_queryparams->hasProp(option+1);
  122. else
  123. return m_queryparams.get() && m_queryparams->hasProp(option);
  124. }
  125. virtual bool isMethodAllowed(double version, const char* optional, const char* security, double maxver, double minver);
  126. virtual IMapInfo& queryMapInfo()
  127. {
  128. if (!m_mapinfo.get())
  129. m_mapinfo.setown(createMapInfo());
  130. return *m_mapinfo.get();
  131. }
  132. virtual bool suppressed(const char* structName, const char* fieldName);
  133. virtual void addOptGroup(const char* optGroup) { if (optGroup) m_optGroups.setValue(optGroup,true); }
  134. virtual BoolHash& queryOptGroups() { return m_optGroups; }
  135. virtual void setUserID(const char* userid)
  136. {
  137. m_userid.set(userid);
  138. }
  139. virtual StringBuffer& getUserID(StringBuffer& userid)
  140. {
  141. userid.append(m_userid.get());
  142. return userid;
  143. }
  144. virtual const char * queryUserId()
  145. {
  146. return m_userid.get();
  147. }
  148. virtual void setPassword(const char* password)
  149. {
  150. m_password.set(password);
  151. }
  152. virtual StringBuffer& getPassword(StringBuffer& password)
  153. {
  154. password.append(m_password.get());
  155. return password;
  156. }
  157. virtual const char * queryPassword()
  158. {
  159. return m_password.get();
  160. }
  161. virtual void setSessionToken(unsigned token)
  162. {
  163. if (m_user)
  164. m_user->credentials().setSessionToken(token);
  165. }
  166. virtual unsigned querySessionToken()
  167. {
  168. return m_user ? m_user->credentials().getSessionToken() : 0;
  169. }
  170. virtual void setSignature(const char * signature)
  171. {
  172. if (m_user)
  173. m_user->credentials().setSignature(signature);
  174. }
  175. virtual const char * querySignature()
  176. {
  177. return m_user ? m_user->credentials().getSignature() : nullptr;
  178. }
  179. virtual void setRealm(const char* realm)
  180. {
  181. m_realm.set(realm);
  182. }
  183. virtual StringBuffer& getRealm(StringBuffer& realm)
  184. {
  185. realm.append(m_realm.get());
  186. return realm;
  187. }
  188. virtual const char * queryRealm()
  189. {
  190. return m_realm.get();
  191. }
  192. virtual void setContextPath(const char* path)
  193. {
  194. m_path.set(path);
  195. }
  196. virtual const char * getContextPath()
  197. {
  198. return m_path.get();
  199. }
  200. virtual void setUser(ISecUser* user)
  201. {
  202. m_user.setown(user);
  203. m_SecurityHandler.setUser(user);
  204. }
  205. virtual ISecUser* queryUser()
  206. {
  207. return m_user.get();
  208. }
  209. virtual void setServiceName(const char *name)
  210. {
  211. m_servName.clear().append(name).toLowerCase();
  212. }
  213. virtual const char * queryServiceName(const char *name)
  214. {
  215. return m_servName.str();
  216. }
  217. virtual const unsigned queryCreationTime()
  218. {
  219. return m_creationTime;
  220. }
  221. virtual void setProcessingTime()
  222. {
  223. m_processingTime = msTick() - m_creationTime;
  224. }
  225. virtual const unsigned queryProcessingTime()
  226. {
  227. return m_processingTime;
  228. }
  229. virtual void setException(int exceptionCode)
  230. {
  231. m_hasException = true;
  232. m_exceptionCode = exceptionCode;
  233. m_exceptionTime = msTick() - m_creationTime;
  234. }
  235. virtual const bool queryException(int& exceptionCode, unsigned& exceptionTime)
  236. {
  237. if (m_hasException)
  238. {
  239. exceptionCode = m_exceptionCode;
  240. exceptionTime = m_exceptionTime;
  241. }
  242. return m_hasException;
  243. }
  244. virtual const bool queryHasException()
  245. {
  246. return m_hasException;
  247. }
  248. virtual void setResources(ISecResourceList* rlist)
  249. {
  250. m_resources.setown(rlist);
  251. m_SecurityHandler.setResources(rlist);
  252. }
  253. virtual ISecResourceList* queryResources()
  254. {
  255. return m_resources.get();
  256. }
  257. virtual void setSecManger(ISecManager* mgr)
  258. {
  259. m_secmgr.setown(mgr);
  260. m_SecurityHandler.setSecManger(mgr);
  261. }
  262. virtual ISecManager* querySecManager()
  263. {
  264. return m_secmgr.get();
  265. }
  266. virtual void setBindingValue(void * value)
  267. {
  268. m_bindingValue=value;
  269. }
  270. virtual void * getBindingValue()
  271. {
  272. return m_bindingValue;
  273. }
  274. virtual void setServiceValue(void * value)
  275. {
  276. m_serviceValue=value;
  277. }
  278. virtual void * getServiceValue()
  279. {
  280. return m_serviceValue;
  281. }
  282. virtual void setToBeAuthenticated(bool val)
  283. {
  284. m_toBeAuthenticated = val;
  285. }
  286. virtual bool toBeAuthenticated()
  287. {
  288. return m_toBeAuthenticated;
  289. }
  290. virtual void setPeer(const char* peer)
  291. {
  292. m_peer.set(peer);
  293. }
  294. virtual StringBuffer& getPeer(StringBuffer& peer)
  295. {
  296. peer.append(m_peer.get());
  297. return peer;
  298. }
  299. virtual void setUseragent(const char* useragent)
  300. {
  301. if(useragent && *useragent)
  302. m_useragent.set(useragent);
  303. }
  304. virtual StringBuffer& getUseragent(StringBuffer& useragent)
  305. {
  306. const char* agent = m_useragent.get();
  307. if(agent && *agent)
  308. useragent.append(m_useragent.get());
  309. return useragent;
  310. }
  311. virtual void setAcceptLanguage(const char* acceptLanguage)
  312. {
  313. if(acceptLanguage && *acceptLanguage)
  314. m_acceptLanguage.set(acceptLanguage);
  315. }
  316. virtual StringBuffer& getAcceptLanguage(StringBuffer& acceptLanguage)
  317. {
  318. const char* acceptLang = m_acceptLanguage.get();
  319. if(acceptLang && *acceptLang)
  320. acceptLanguage.set(m_acceptLanguage.get());
  321. return acceptLanguage;
  322. }
  323. virtual IProperties * queryRequestParameters()
  324. {
  325. if (!m_queryparams)
  326. m_queryparams.setown(createProperties(false));
  327. return m_queryparams.get();
  328. }
  329. virtual void setRequestParameters(IProperties * Parameters)
  330. {
  331. m_queryparams.set(Parameters);
  332. }
  333. virtual void setServAddress(const char * host, short port)
  334. {
  335. m_servHost.clear().append(host);
  336. m_servPort = port;
  337. }
  338. virtual void getServAddress(StringBuffer & host, short & port)
  339. {
  340. host.append(m_servHost);
  341. port = m_servPort;
  342. }
  343. virtual void setFeatureAuthMap(IAuthMap * map)
  344. {
  345. if(map != NULL)
  346. {
  347. m_feature_authmap.setown(map);
  348. m_SecurityHandler.setFeatureAuthMap(map);
  349. }
  350. }
  351. virtual IAuthMap * queryAuthMap()
  352. {
  353. return m_feature_authmap.get();
  354. }
  355. virtual void setSecuritySettings(ISecPropertyList* slist)
  356. {
  357. m_sec_settings.setown(slist);
  358. }
  359. virtual ISecPropertyList* querySecuritySettings()
  360. {
  361. return m_sec_settings.get();
  362. }
  363. virtual bool authorizeFeatures(StringArray & features, IEspStringIntMap & pmap)
  364. {
  365. return m_SecurityHandler.authorizeSecReqFeatures(features, pmap, NULL);
  366. }
  367. virtual bool authorizeFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access)
  368. {
  369. SecUserStatus user_status;
  370. return m_SecurityHandler.authorizeSecFeature(pszFeatureUrl, UserID, CompanyID, access,false,0, user_status);
  371. }
  372. virtual bool authorizeFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access,bool bCheckTrial,int DebitUnits, SecUserStatus& user_status)
  373. {
  374. return m_SecurityHandler.authorizeSecFeature(pszFeatureUrl, UserID, CompanyID, access,bCheckTrial, DebitUnits, user_status);
  375. }
  376. virtual bool authorizeFeature(const char* pszFeatureUrl, SecAccessFlags& access)
  377. {
  378. return m_SecurityHandler.authorizeSecFeature(pszFeatureUrl, access);
  379. }
  380. virtual bool validateFeaturesAccess(MapStringTo<SecAccessFlags> & pmap, bool throwExcpt)
  381. {
  382. return m_SecurityHandler.validateSecFeaturesAccess(pmap, throwExcpt);
  383. }
  384. virtual bool validateFeatureAccess(const char* pszFeatureUrl, unsigned required, bool throwExcpt)
  385. {
  386. return m_SecurityHandler.validateSecFeatureAccess(pszFeatureUrl, required, throwExcpt);
  387. }
  388. virtual void ensureFeatureAccess(const char* pszFeatureUrl, unsigned required, unsigned excCode, const char* excMsg)
  389. {
  390. if (!validateFeatureAccess(pszFeatureUrl, required, false))
  391. {
  392. setAuthStatus(AUTH_STATUS_NOACCESS);
  393. throw MakeStringException(excCode, "Resource %s : %s", pszFeatureUrl, excMsg);
  394. }
  395. }
  396. virtual void ensureSuperUser(unsigned excCode, const char* excMsg)
  397. {
  398. #ifdef _USE_OPENLDAP
  399. CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(m_secmgr.get());
  400. if (secmgr && !secmgr->isSuperUser(m_user.get()))
  401. {
  402. setAuthStatus(AUTH_STATUS_NOACCESS);
  403. throw makeStringException(excCode, excMsg);
  404. }
  405. #endif
  406. }
  407. void AuditMessage(AuditType type, const char *filterType, const char *title, const char *parms, ...) __attribute__((format(printf, 5, 6)));
  408. void AuditMessage(AuditType type, const char *filterType, const char *title);
  409. IProperties * queryXslParameters()
  410. {
  411. if (!xslParameters)
  412. xslParameters.setown(createProperties(false));
  413. return xslParameters.get();
  414. }
  415. StringArray& queryCustomHeaders()
  416. {
  417. return m_custom_headers;
  418. }
  419. void addCustomerHeader(const char* name, const char* val)
  420. {
  421. if(!name || !*name)
  422. throw MakeStringException(-1, "Header name can't be empty");
  423. m_custom_headers.append(StringBuffer(name).appendf(": %s", val?val:"").str());
  424. }
  425. virtual void setHTTPMethod(const char *method)
  426. {
  427. httpMethod.set(method);
  428. }
  429. virtual void setServiceMethod(const char *method)
  430. {
  431. servMethod.set(method);
  432. }
  433. virtual void setESDLBindingID(const char *id)
  434. {
  435. esdlBindingID.set(id);
  436. }
  437. virtual const char* queryESDLBindingID()
  438. {
  439. return esdlBindingID.get();
  440. }
  441. virtual CTxSummary* queryTxSummary()
  442. {
  443. return m_txSummary.get();
  444. }
  445. virtual void addTraceSummaryValue(LogLevel logLevel, const char *name, const char *value, const unsigned int group = TXSUMMARY_GRP_CORE)
  446. {
  447. if (m_txSummary && !isEmptyString(name))
  448. m_txSummary->append(name, value, logLevel, group);
  449. }
  450. virtual void addTraceSummaryValue(LogLevel logLevel, const char *name, __int64 value, const unsigned int group = TXSUMMARY_GRP_CORE)
  451. {
  452. if (m_txSummary && !isEmptyString(name))
  453. m_txSummary->append(name, value, logLevel, group);
  454. }
  455. virtual void addTraceSummaryDoubleValue(LogLevel logLevel, const char *name, double value, const unsigned int group = TXSUMMARY_GRP_CORE)
  456. {
  457. if (m_txSummary && !isEmptyString(name))
  458. m_txSummary->append(name, value, logLevel, group);
  459. }
  460. virtual void addTraceSummaryTimeStamp(LogLevel logLevel, const char *name, const unsigned int group = TXSUMMARY_GRP_CORE)
  461. {
  462. if (m_txSummary && !isEmptyString(name))
  463. m_txSummary->append(name, m_txSummary->getElapsedTime(), logLevel, group, "ms");
  464. }
  465. virtual void flushTraceSummary()
  466. {
  467. updateTraceSummaryHeader();
  468. if (m_txSummary)
  469. {
  470. m_txSummary->set("auth", authStatus.get(), LogMin, TXSUMMARY_GRP_CORE|TXSUMMARY_GRP_ENTERPRISE);
  471. m_txSummary->append("total", m_processingTime, LogMin, TXSUMMARY_GRP_CORE|TXSUMMARY_GRP_ENTERPRISE, "ms");
  472. }
  473. }
  474. virtual void addTraceSummaryCumulativeTime(LogLevel logLevel, const char* name, unsigned __int64 time, const unsigned int group = TXSUMMARY_GRP_CORE)
  475. {
  476. if (m_txSummary && !isEmptyString(name))
  477. m_txSummary->updateTimer(name, time, logLevel, group);
  478. }
  479. virtual CumulativeTimer* queryTraceSummaryCumulativeTimer(LogLevel logLevel, const char *name, const unsigned int group = TXSUMMARY_GRP_CORE)
  480. {
  481. return (m_txSummary ? m_txSummary->queryTimer(name, logLevel, group) : NULL);
  482. }
  483. virtual void cancelTxSummary()
  484. {
  485. if (!m_txSummary)
  486. return;
  487. m_txSummary->clear();
  488. m_txSummary.clear();
  489. }
  490. virtual void setAuthStatus(const char* status)
  491. {
  492. authStatus.set(status);
  493. }
  494. virtual const char* queryAuthStatus()
  495. {
  496. return authStatus.str();
  497. }
  498. virtual void setAuthenticationMethod(const char* method)
  499. {
  500. authenticationMethod.set(method);
  501. }
  502. virtual const char * getAuthenticationMethod()
  503. {
  504. return authenticationMethod.get();
  505. }
  506. virtual void setDomainAuthType(AuthType type) { domainAuthType = type; }
  507. virtual AuthType getDomainAuthType(){ return domainAuthType; }
  508. virtual void setAuthError(AuthError error) { authError = error; }
  509. virtual AuthError getAuthError(){ return authError; }
  510. virtual void setRespMsg(const char* msg)
  511. {
  512. respMsg.set(msg);
  513. }
  514. virtual const char* getRespMsg()
  515. {
  516. return respMsg.get();
  517. }
  518. virtual ESPSerializationFormat getResponseFormat(){return respSerializationFormat;}
  519. virtual void setResponseFormat(ESPSerializationFormat fmt){respSerializationFormat = fmt;}
  520. void updateTraceSummaryHeader();
  521. IEspSecureContext* querySecureContext() override
  522. {
  523. return m_secureContext.get();
  524. }
  525. virtual void setTransactionID(const char * trxid)
  526. {
  527. m_transactionID.set(trxid);
  528. }
  529. virtual const char * queryTransactionID()
  530. {
  531. return m_transactionID.get();
  532. }
  533. virtual void setRequest(IHttpMessage* req)
  534. {
  535. m_request = req;
  536. }
  537. virtual IHttpMessage* queryRequest()
  538. {
  539. return m_request;
  540. }
  541. virtual void setGlobalId(const char* id)
  542. {
  543. m_globalId.set(id);
  544. }
  545. virtual const char* getGlobalId()
  546. {
  547. return m_globalId.str();
  548. }
  549. virtual void setCallerId(const char* id)
  550. {
  551. m_callerId.set(id);
  552. }
  553. virtual const char* getCallerId()
  554. {
  555. return m_callerId.str();
  556. }
  557. // No setLocalId() - it should be set once only when constructed
  558. virtual const char* getLocalId()
  559. {
  560. return m_localId.str();
  561. }
  562. };
  563. //---------------------------------------------------------
  564. // implementations
  565. void CEspContext::AuditMessage(AuditType type, const char *filterType, const char *title, const char *parms, ...)
  566. {
  567. va_list args;
  568. va_start(args, parms);
  569. StringBuffer msg(title);
  570. msg.appendf("\n\tProcess: esp\n\tService: %s\n\tUser: %s", m_servName.str(), queryUserId());
  571. if (parms)
  572. msg.append("\n\t").valist_appendf(parms, args);
  573. va_end(args);
  574. AUDIT(type, msg.str());
  575. }
  576. void CEspContext::AuditMessage(AuditType type, const char *filterType, const char *title)
  577. {
  578. VStringBuffer msg("%s\n\tProcess: esp\n\tService: %s\n\tUser: %s", title, m_servName.str(), queryUserId());
  579. AUDIT(type, msg.str());
  580. }
  581. bool CEspContext::suppressed(const char* structName, const char* fieldName)
  582. {
  583. if (!m_mapinfo)
  584. return false;
  585. double ver = getClientVersion();
  586. double minver = m_mapinfo->getMinVersion(structName,fieldName);
  587. if (minver>0 && ver<minver)
  588. return true;
  589. double deprver = m_mapinfo->getDeprVersion(structName,fieldName);
  590. if (deprver>0)
  591. {
  592. if (ver>=deprver)
  593. return true;
  594. }
  595. else
  596. {
  597. double maxver = m_mapinfo->getMaxVersion(structName,fieldName);
  598. if (maxver>0 && ver>maxver)
  599. return true;
  600. }
  601. const char* optional = m_mapinfo->getOptional(structName,fieldName);
  602. if (optional)
  603. return !queryRequestParameters()->hasProp(optional);
  604. return false;
  605. }
  606. bool CEspContext::isMethodAllowed(double version, const char* optional, const char* security, double minver, double maxver)
  607. {
  608. if (optional)
  609. {
  610. IProperties *props = queryRequestParameters();
  611. if (props && !props->hasProp(optional))
  612. return false;
  613. }
  614. if (security)
  615. {
  616. SecAccessFlags acc;
  617. if (!authorizeFeature(security, acc) || (acc==SecAccess_None))
  618. return false;
  619. }
  620. if (minver>0 && version<minver)
  621. return false;
  622. if (maxver>0 && version>maxver)
  623. return false;
  624. return true;
  625. }
  626. void CEspContext::updateTraceSummaryHeader()
  627. {
  628. if (m_txSummary)
  629. {
  630. m_txSummary->set("activeReqs", m_active, LogMin, TXSUMMARY_GRP_CORE|TXSUMMARY_GRP_ENTERPRISE);
  631. VStringBuffer user("%s%s%s", (queryUserId() ? queryUserId() : ""), (m_peer.length() ? "@" : ""), m_peer.str());
  632. if (!user.isEmpty())
  633. m_txSummary->set("user", user.str(), LogMin);
  634. VStringBuffer reqSummary("%s", httpMethod.isEmpty() ? "" : httpMethod.get());
  635. if (!m_servName.isEmpty() || !servMethod.isEmpty())
  636. {
  637. if (!reqSummary.isEmpty())
  638. reqSummary.append(" ");
  639. if (!m_servName.isEmpty())
  640. reqSummary.append(m_servName.str());
  641. if (!servMethod.isEmpty())
  642. reqSummary.append(".").append(servMethod.str());
  643. }
  644. if (m_clientVer > 0)
  645. {
  646. if (!reqSummary.isEmpty())
  647. reqSummary.append(" ");
  648. reqSummary.append("v").append(m_clientVer);
  649. }
  650. if (!reqSummary.isEmpty())
  651. m_txSummary->set("req", reqSummary.str(), LogMin, TXSUMMARY_GRP_CORE);
  652. if (m_hasException)
  653. {
  654. m_txSummary->set("excepttime", m_exceptionTime, LogMin, TXSUMMARY_GRP_CORE);
  655. m_txSummary->set("exceptcode", m_exceptionCode, LogMin, TXSUMMARY_GRP_CORE);
  656. }
  657. }
  658. }
  659. IEspContext* createEspContext(IEspSecureContext* secureContext)
  660. {
  661. return new CEspContext(secureContext);
  662. }
  663. bool getUrlParams(IProperties *props, StringBuffer& params)
  664. {
  665. bool hasVersion = false;
  666. if (props) {
  667. Owned<IPropertyIterator> it = props->getIterator();
  668. for (it->first(); it->isValid(); it->next()) {
  669. const char* key = it->getPropKey();
  670. if (!key || !*key || stricmp(key,"form")==0 || stricmp(key,"__querystring")==0)
  671. continue;
  672. if (params.length()==0)
  673. params.append("?");
  674. else
  675. params.append("&");
  676. params.append(key);
  677. if (stricmp(key,"ver_")==0)
  678. hasVersion = true;
  679. const char* v = props->queryProp(key);
  680. if (v && *v)
  681. params.appendf("=%s",v);
  682. }
  683. }
  684. return hasVersion;
  685. }
  686. void getEspUrlParams(IEspContext& ctx, StringBuffer& params, const char* excludeParams[])
  687. {
  688. bool hasVersion = false, addAmpersand = false;
  689. int excludes = 0;
  690. if (excludeParams)
  691. while (excludeParams[excludes]) excludes++;
  692. IProperties* props = ctx.queryRequestParameters();
  693. if (props)
  694. {
  695. const char* querystr = props->queryProp("__querystring");
  696. if (querystr)
  697. {
  698. StringArray ps;
  699. ps.appendListUniq(querystr, "&");
  700. for (unsigned int i=0; i<ps.ordinality(); i++)
  701. {
  702. const char* item = ps.item(i);
  703. const char* eq = strchr(item,'=');
  704. StringAttr key;
  705. if (eq)
  706. key.set(item, eq-item);
  707. else
  708. key.set(item);
  709. bool excluded = false;
  710. if (*key.get()=='.')
  711. excluded = true;
  712. else for (int i=0; i<excludes; i++)
  713. {
  714. if (stricmp(excludeParams[i],key.get())==0)
  715. {
  716. excluded = true;
  717. break;
  718. }
  719. }
  720. if (!excluded)
  721. {
  722. if (addAmpersand)
  723. params.append('&');
  724. else
  725. addAmpersand = true;
  726. params.append(item);
  727. }
  728. if (stricmp(key,"ver_")==0)
  729. hasVersion = true;
  730. }
  731. }
  732. }
  733. if (!hasVersion)
  734. params.appendf("%sver_=%g", addAmpersand?"&":"", ctx.getClientVersion());
  735. }
  736. void addEspNativeArray(StringBuffer& schema, const char* xsdType, const char* arrayType)
  737. {
  738. schema.appendf("<xsd:complexType name=\"%s\">"
  739. "<xsd:sequence>"
  740. "<xsd:element name=\"Item\" type=\"xsd:%s\" minOccurs=\"0\" maxOccurs=\"unbounded\" />"
  741. "</xsd:sequence>"
  742. "</xsd:complexType>\n", arrayType, xsdType);
  743. }
  744. void checkRequest(IEspContext& ctx)
  745. {
  746. #ifdef ENABLE_NEW_SECURITY
  747. ISecUser* user = ctx.queryUser();
  748. if (user && user->getStatus()!=SecUserStatus_Unknown) // no user means security is not configured
  749. {
  750. BoolHash& groups = ctx.queryOptGroups();
  751. if (groups.find("internal"))
  752. {
  753. if(user->getStatus()!=SecUserStatus_Inhouse)
  754. {
  755. OWARNLOG("User %s trying to access unauthorized feature: internal", user->getName() ? user->getName() : ctx.queryUserId());
  756. throw MakeStringException(400,"Bad request");
  757. }
  758. }
  759. }
  760. #elif !defined(DISABLE_NEW_SECURITY)
  761. #error Please include esphttp.hpp in this file.
  762. #endif
  763. }
  764. //--------------------------------
  765. // log level
  766. static IEspContainer*& getContainer()
  767. {
  768. static IEspContainer* gContainer = NULL;
  769. // printf("Container: %p\n", gContainer);
  770. return gContainer;
  771. }
  772. LogRequest readLogRequest(char const* req)
  773. {
  774. if (isEmptyString(req))
  775. return LogRequestsNever;
  776. if (strieq(req, "all"))
  777. return LogRequestsAlways;
  778. if (strieq(req, "never"))
  779. return LogRequestsNever;
  780. if (strieq(req, "only-ones-with-issues"))
  781. return LogRequestsWithIssuesOnly;
  782. if (strToBool(req))
  783. return LogRequestsAlways;
  784. return LogRequestsNever;
  785. }
  786. StringBuffer& getLogRequestString(LogRequest req, StringBuffer& out)
  787. {
  788. if (req == LogRequestsAlways)
  789. out.append("all");
  790. else if (req == LogRequestsWithIssuesOnly)
  791. out.append("only-ones-with-issues");
  792. else
  793. out.append("never");
  794. return out;
  795. }
  796. LogLevel getEspLogLevel() { return getEspLogLevel(NULL); }
  797. LogLevel getEspLogLevel(IEspContext* ctx)
  798. {
  799. if (ctx)
  800. {
  801. ISecPropertyList* properties = ctx->querySecuritySettings();
  802. if (properties)
  803. {
  804. ISecProperty* sec = properties->findProperty("DebugMode");
  805. if (sec)
  806. {
  807. const char* mode = sec->getValue();
  808. if ( mode && (streq(mode,"1") || streq(mode, "true")) )
  809. return LogMax;
  810. }
  811. }
  812. }
  813. if (getContainer())
  814. return getContainer()->getLogLevel();
  815. return LogMin;
  816. }
  817. LogLevel getTxSummaryLevel()
  818. {
  819. if (getContainer())
  820. return getContainer()->getTxSummaryLevel();
  821. return LogMin;
  822. }
  823. const unsigned int readTxSummaryStyle(char const* style)
  824. {
  825. if (isEmptyString(style))
  826. return TXSUMMARY_OUT_TEXT;
  827. if (strieq(style, "text"))
  828. return TXSUMMARY_OUT_TEXT;
  829. if (strieq(style, "json"))
  830. return TXSUMMARY_OUT_JSON;
  831. if (strieq(style, "all"))
  832. return TXSUMMARY_OUT_TEXT | TXSUMMARY_OUT_JSON;
  833. return TXSUMMARY_OUT_TEXT;
  834. }
  835. const unsigned int readTxSummaryGroup(char const* group)
  836. {
  837. if (isEmptyString(group))
  838. return TXSUMMARY_GRP_CORE;
  839. if (strieq(group, "core"))
  840. return TXSUMMARY_GRP_CORE;
  841. if (strieq(group, "enterprise"))
  842. return TXSUMMARY_GRP_ENTERPRISE;
  843. if (strieq(group, "all"))
  844. return TXSUMMARY_GRP_CORE | TXSUMMARY_GRP_ENTERPRISE;
  845. return TXSUMMARY_GRP_CORE;
  846. }
  847. const unsigned int getTxSummaryStyle()
  848. {
  849. if (getContainer())
  850. return getContainer()->getTxSummaryStyle();
  851. return TXSUMMARY_OUT_TEXT;
  852. }
  853. const unsigned int getTxSummaryGroup()
  854. {
  855. if (getContainer())
  856. return getContainer()->getTxSummaryGroup();
  857. return TXSUMMARY_GRP_CORE;
  858. }
  859. bool getTxSummaryResourceReq()
  860. {
  861. if (getContainer())
  862. return getContainer()->getTxSummaryResourceReq();
  863. return false;
  864. }
  865. LogRequest getEspLogRequests()
  866. {
  867. if (getContainer())
  868. return getContainer()->getLogRequests();
  869. return LogRequestsNever;
  870. }
  871. bool getEspLogResponses()
  872. {
  873. if (getContainer())
  874. return getContainer()->getLogResponses();
  875. return false;
  876. }
  877. unsigned getSlowProcessingTime()
  878. {
  879. if (getContainer())
  880. return getContainer()->getSlowProcessingTime();
  881. return false;
  882. }
  883. void ESPLOG(LogLevel level, const char* fmt, ...)
  884. {
  885. if (getEspLogLevel(NULL)>=level)
  886. {
  887. va_list args;
  888. va_start(args,fmt);
  889. VALOG(MCdebugInfo, unknownJob, fmt, args);
  890. va_end(args);
  891. }
  892. }
  893. void ESPLOG(IEspContext* ctx, LogLevel level, const char* fmt, ...)
  894. {
  895. if (getEspLogLevel(ctx)>=level)
  896. {
  897. va_list args;
  898. va_start(args,fmt);
  899. VALOG(MCdebugInfo, unknownJob, fmt, args);
  900. va_end(args);
  901. }
  902. }
  903. void setEspContainer(IEspContainer* container)
  904. {
  905. getContainer() = container;
  906. }
  907. IEspContainer* getESPContainer()
  908. {
  909. return getContainer();
  910. }
  911. static StringBuffer g_cfd;
  912. void setCFD(const char* cfd)
  913. {
  914. g_cfd.clear();
  915. if(cfd&&*cfd)
  916. g_cfd.append(cfd);
  917. g_cfd.trim();
  918. if (g_cfd.length())
  919. makeAbsolutePath(g_cfd, true);
  920. if (g_cfd.length())
  921. {
  922. char lastChar = g_cfd.charAt(g_cfd.length() - 1);
  923. if(lastChar != PATHSEPCHAR && lastChar != '/')
  924. g_cfd.append(PATHSEPCHAR);
  925. }
  926. }
  927. const char* getCFD()
  928. {
  929. return g_cfd.str();
  930. }
  931. static StringBuffer g_buildVersion;
  932. void setBuildVersion(const char* buildVersion)
  933. {
  934. g_buildVersion.clear();
  935. if(buildVersion&&*buildVersion)
  936. g_buildVersion.append(buildVersion);
  937. g_buildVersion.trim();
  938. }
  939. const char* getBuildVersion()
  940. {
  941. return g_buildVersion.str();
  942. }
  943. IEspServer* queryEspServer()
  944. {
  945. return dynamic_cast<IEspServer*>(getESPContainer());
  946. }
  947. IRemoteConnection* getSDSConnectionWithRetry(const char* xpath, unsigned mode, unsigned timeoutMs)
  948. {
  949. CTimeMon timer(timeoutMs);
  950. unsigned remaining;
  951. while (!timer.timedout(&remaining))
  952. {
  953. try
  954. {
  955. unsigned connTimeoutMs = remaining > SESSION_SDS_LOCK_TIMEOUT ? SESSION_SDS_LOCK_TIMEOUT : remaining;
  956. Owned<IRemoteConnection> conn = querySDS().connect(xpath, myProcessSession(), mode, connTimeoutMs);
  957. if (!conn)
  958. throw MakeStringException(-1, "getSDSConnectionWithRetry() : unabled to establish connection to : %s", xpath);
  959. return conn.getClear();
  960. }
  961. catch (ISDSException* e)
  962. {
  963. if (SDSExcpt_LockTimeout != e->errorCode())
  964. throw;
  965. IERRLOG(e, "getSDSConnectionWithRetry()");
  966. e->Release();
  967. }
  968. }
  969. return nullptr;
  970. }