SessionCache.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright (c) 2002-2009 Moxie Marlinspike
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. * USA
  18. */
  19. #include "SessionCache.hpp"
  20. #include "Logger.hpp"
  21. SessionCache* SessionCache::sessionCache = NULL;
  22. boost::mutex SessionCache::singletonLock;
  23. SessionCache* SessionCache::getInstance() {
  24. boost::mutex::scoped_lock lock(singletonLock);
  25. if (sessionCache == NULL)
  26. sessionCache = new SessionCache();
  27. return sessionCache;
  28. }
  29. SessionCache::SessionCache() {
  30. bzero((void*)&cache, sizeof(SessionCacheBlock));
  31. }
  32. void SessionCache::removeSessionId(unsigned char* id, int idLength) {
  33. int i;
  34. for (i=0;i<CACHE_SIZE;i++) {
  35. if (memcmp(cache.sessions[i].id, id, idLength) == 0) {
  36. bzero(cache.sessions[i].id, idLength);
  37. }
  38. }
  39. }
  40. int SessionCache::setNewSessionId(SSL *s, SSL_SESSION *session) {
  41. return setNewSessionId(s, session, session->session_id, session->session_id_length);
  42. }
  43. int SessionCache::setNewSessionId(SSL *s, SSL_SESSION *session,
  44. unsigned char *id, int idLength)
  45. {
  46. int encodedLength = i2d_SSL_SESSION(session, NULL);
  47. unsigned char* b;
  48. int current;
  49. if (encodedLength > MAX_ENCODING_SIZE) {
  50. std::stringstream errorStream;
  51. errorStream << "Encoded Length: " << encodedLength << " too big for session cache, skipping...";
  52. std::string error = errorStream.str();
  53. Logger::logError(error);
  54. return 1;
  55. }
  56. if (idLength > MAX_ID_SIZE) {
  57. std::stringstream errorStream;
  58. errorStream << "ID Length: " << idLength << " too big for session cache, skipping...";
  59. std::string error = errorStream.str();
  60. Logger::logError(error);
  61. return 1;
  62. }
  63. boost::mutex::scoped_lock lock(cacheLock);
  64. removeSessionId(id, idLength);
  65. current = cache.current;
  66. b = cache.sessions[current].encoding;
  67. i2d_SSL_SESSION(session, &b);
  68. memcpy(cache.sessions[current].id, id, idLength);
  69. cache.sessions[current].encodingLength = encodedLength;
  70. cache.sessions[current].idLength = idLength;
  71. cache.current = (current + 1) % CACHE_SIZE;
  72. return 1;
  73. }
  74. SSL_SESSION * SessionCache::getSessionId(SSL *s, unsigned char *id, int idLength, int *ref) {
  75. int i;
  76. unsigned char *b;
  77. *ref = 0;
  78. boost::mutex::scoped_lock lock(cacheLock);
  79. for (i=0;i<CACHE_SIZE;i++) {
  80. if (memcmp(cache.sessions[i].id, id, idLength) == 0) {
  81. b = (unsigned char*)malloc(cache.sessions[i].encodingLength);
  82. memcpy(b, cache.sessions[i].encoding, cache.sessions[i].encodingLength);
  83. return d2i_SSL_SESSION(NULL, (const unsigned char **)&b,
  84. cache.sessions[i].encodingLength);
  85. }
  86. }
  87. return NULL;
  88. }
  89. // Trampoline Functions. Yay C.
  90. SSL_SESSION * SessionCache::getSessionIdTramp(SSL *s, unsigned char *id, int idLength, int *ref) {
  91. return SessionCache::getInstance()->getSessionId(s, id, idLength, ref);
  92. }
  93. int SessionCache::setNewSessionIdTramp(SSL *s, SSL_SESSION *session) {
  94. return SessionCache::getInstance()->setNewSessionId(s, session);
  95. }