1 /****************************************************************************
2 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 * Copyright (C) 2008-2013 Sourcefire, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation. You may not use, modify or
8 * distribute this program under any other version of the GNU General
9 * Public License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 ****************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "stdlib.h"
27 #include "string.h"
28 #include "sf_types.h"
29 #include "sfPolicy.h"
30 #include "sfPolicyUserData.h"
31
32 /** @defgroup sfPolicyConfig Sourcefire policy configuration module
33 *
34 * Create a user policy configuration context. A context provides facility for creating
35 * policy specific data instances. User can create as many policy instances as memory
36 * resources will allow. User can create/delete context, set/clear/get user date for a
37 * specific policy, default policy or current policy. User can also iterate over all instances
38 * user data.
39 *
40 * In current design, preprocessor use this module directly to manage policy specific data
41 * instances. A future enhancement can be to extract policy management code from each processor
42 * and put it in a new policy management module. Policy management module will set a single
43 * pointer to user data before calling appropriate callback function in a preprocessor. As
44 * an example, policy module will iterate over all policies and call CleanExit functions in every
45 * preprocessor for each policy. This will make policy management module will hide policies from
46 * preprocessors and make them policy agnostic.
47 * @{
48 */
49
50 /**Create a user context.
51 * Allocates a new context and return it to user. All transactions within a context are independent from
52 * any other transactions in a different context.
53 *
54 * @returns tSfPolicyUserContextId
55 */
sfPolicyConfigCreate(void)56 tSfPolicyUserContextId sfPolicyConfigCreate(void)
57 {
58 tSfPolicyUserContext *pTmp = NULL;
59
60 pTmp = calloc(1, sizeof(tSfPolicyUserContext));
61
62 return pTmp;
63 }
64
65 /**Delete a user policy data context.
66 * @param pContext
67 */
sfPolicyConfigDelete(tSfPolicyUserContextId pContext)68 void sfPolicyConfigDelete(
69 tSfPolicyUserContextId pContext
70 )
71 {
72 if (pContext == NULL)
73 return;
74
75 if (pContext->userConfig != NULL)
76 free(pContext->userConfig);
77
78 free(pContext);
79 }
80
81 /**Store a pointer to user data.
82 * @param pContext
83 * @param policyId is 0 based.
84 * @param config - pointer to user configuration.
85 */
sfPolicyUserDataSet(tSfPolicyUserContextId pContext,tSfPolicyId policyId,void * config)86 int sfPolicyUserDataSet (
87 tSfPolicyUserContextId pContext,
88 tSfPolicyId policyId,
89 void *config
90 )
91 {
92 void **ppTmp;
93
94 if (policyId >= pContext->numAllocatedPolicies)
95 {
96 //expand the array
97 ppTmp = (void **)calloc(policyId+POLICY_ALLOCATION_CHUNK, sizeof(void *));
98 if (!(ppTmp))
99 {
100 return -1;
101 }
102
103 if (pContext->numAllocatedPolicies)
104 {
105 memcpy(ppTmp, pContext->userConfig, sizeof(void*)*(pContext->numAllocatedPolicies));
106 free(pContext->userConfig);
107 }
108
109 pContext->userConfig = ppTmp;
110 pContext->numAllocatedPolicies = policyId + POLICY_ALLOCATION_CHUNK;
111 }
112
113 if (pContext->userConfig[policyId])
114 {
115 //dont overwrite existing configuration
116 return -1;
117 }
118
119 pContext->userConfig[policyId] = config;
120 pContext->numActivePolicies++;
121
122 return 0;
123 }
124
125 /**user is responsible for freeing any memory.
126 */
sfPolicyUserDataClear(tSfPolicyUserContextId pContext,tSfPolicyId policyId)127 void * sfPolicyUserDataClear (
128 tSfPolicyUserContextId pContext,
129 tSfPolicyId policyId
130 )
131 {
132 void *pTmp = NULL;
133
134 if (policyId < pContext->numAllocatedPolicies)
135 {
136 pTmp = pContext->userConfig[policyId];
137 pContext->userConfig[policyId] = NULL;
138 pContext->numActivePolicies--;
139 }
140
141 return pTmp;
142 }
143
sfPolicyUserDataIterate(struct _SnortConfig * sc,tSfPolicyUserContextId pContext,int (* callback)(struct _SnortConfig * sc,tSfPolicyUserContextId pContext,tSfPolicyId policyId,void * config))144 int sfPolicyUserDataIterate (
145 struct _SnortConfig *sc,
146 tSfPolicyUserContextId pContext,
147 int (*callback)(struct _SnortConfig *sc, tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config)
148 )
149 {
150 tSfPolicyId policyId;
151 int ret = 0;
152
153 //must not use numActivePolicies because the callback may delete a policy
154 for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++)
155 {
156 if (pContext->userConfig[policyId])
157 {
158 ret = callback(sc, pContext, policyId, pContext->userConfig[policyId]);
159 if (ret != 0)
160 break;
161 }
162 }
163
164 return ret;
165 }
166
sfPolicyUserDataFreeIterate(tSfPolicyUserContextId pContext,int (* callback)(tSfPolicyUserContextId pContext,tSfPolicyId policyId,void * config))167 int sfPolicyUserDataFreeIterate (
168 tSfPolicyUserContextId pContext,
169 int (*callback)(tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config)
170 )
171 {
172 tSfPolicyId policyId;
173 int ret = 0;
174
175 //must not use numActivePolicies because the callback may delete a policy
176 for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++)
177 {
178 if (pContext->userConfig[policyId])
179 {
180 ret = callback(pContext, policyId, pContext->userConfig[policyId]);
181 if (ret != 0)
182 break;
183 }
184 }
185
186 return ret;
187 }
188
189 /** @} */ //
190
191