SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-xmltooling.git] / xmltooling / util / ReplayCache.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * ReplayCache.cpp
23  * 
24  * Helper class on top of StorageService for detecting message replay. 
25  */
26
27 #include "internal.h"
28 #include "logging.h"
29 #include "security/SecurityHelper.h"
30 #include "util/ReplayCache.h"
31
32 using namespace xmltooling::logging;
33 using namespace xmltooling;
34 using namespace std;
35
36 ReplayCache::ReplayCache(StorageService* storage)
37     : m_owned(storage==nullptr),
38         m_storage(storage ? storage : XMLToolingConfig::getConfig().StorageServiceManager.newPlugin(MEMORY_STORAGE_SERVICE, nullptr)),
39         m_storageCaps(m_storage->getCapabilities())
40 {
41 }
42
43 ReplayCache::~ReplayCache()
44 {
45     if (m_owned)
46         delete m_storage;
47 }
48
49 bool ReplayCache::check(const char* context, const char* s, time_t expires)
50 {
51     if (strlen(context) > m_storageCaps.getContextSize()) {
52         // This is a design/coding failure.
53         Category::getInstance(XMLTOOLING_LOGCAT ".ReplayCache").error(
54             "context (%s) too long for StorageService (limit %u)", context, m_storageCaps.getContextSize()
55             );
56         return false;
57     }
58     else if (strlen(s) > m_storageCaps.getKeySize()) {
59         // This is something to work around with a hash.
60 #ifndef XMLTOOLING_NO_XMLSEC
61         string h = SecurityHelper::doHash("SHA1", s, strlen(s));
62         // In storage already?
63         if (m_storage->readString(context, h.c_str()))
64             return false;
65         m_storage->createString(context, h.c_str(), "x", expires);
66         return true;
67 #else
68         Category::getInstance(XMLTOOLING_LOGCAT ".ReplayCache").error(
69             "key (%s) too long for StorageService (limit %u)", s, m_storageCaps.getKeySize()
70             );
71         return false;
72 #endif
73     }
74
75     // In storage already?
76     if (m_storage->readString(context, s))
77         return false;
78     m_storage->createString(context, s, "x", expires);
79     return true;
80 }
81
82 bool ReplayCache::check(const char* context, const XMLCh* s, time_t expires)
83 {
84     auto_ptr_char temp(s);
85     return check(context, temp.get(), expires);
86 }