]>
Commit | Line | Data |
---|---|---|
9f2c8cb9 | 1 | /* |
2 | * Copyright 2009 The Board of Trustees of the University | |
3 | * of Illinois. See the LICENSE file for detailed license information. | |
4 | * | |
5 | * Portions, specifically log_usage_stats(), ssh_usage_stats_init(), | |
6 | * ssh_usage_stats_close(), ssh_usage_ent_s, ssh_usage_tag_e and | |
7 | * TAG #defines were based on those from Usage Metrics portions of: | |
8 | * gridftp/server/source/globus_i_gfs_log.c | |
9 | * | |
10 | * Copyright 1999-2006 University of Chicago | |
11 | * | |
12 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
13 | * you may not use this file except in compliance with the License. | |
14 | * You may obtain a copy of the License at | |
15 | * | |
16 | * http://www.apache.org/licenses/LICENSE-2.0 | |
17 | * | |
18 | * Unless required by applicable law or agreed to in writing, software | |
19 | * distributed under the License is distributed on an "AS IS" BASIS, | |
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
21 | * See the License for the specific language governing permissions and | |
22 | * limitations under the License. | |
23 | */ | |
24 | ||
25 | #include <stdarg.h> | |
26 | ||
27 | #include "log.h" | |
28 | #include "ssh-globus-usage.h" | |
29 | ||
30 | #ifdef HAVE_GLOBUS_USAGE | |
31 | ||
32 | static globus_list_t *usage_handle_list = NULL; | |
33 | ||
34 | #define SSH_GLOBUS_USAGE_ID 12 | |
35 | #define SSH_GLOBUS_USAGE_VER 0 | |
36 | ||
37 | #define SSH_GLOBUS_DEFAULT_TAGLIST "VvMm" | |
38 | #define SSH_GLOBUS_ALL_TAGLIST "VvMmIuU" | |
39 | #define SSH_GLOBUS_TAGCOUNT 25 | |
40 | ||
41 | typedef enum ssh_usage_tag_e | |
42 | { | |
43 | SSH_GLOBUS_USAGE_SSH_VER = 'V', | |
44 | SSH_GLOBUS_USAGE_SSL_VER = 'v', | |
45 | SSH_GLOBUS_USAGE_METHOD = 'M', | |
46 | SSH_GLOBUS_USAGE_MECHANISM = 'm', | |
47 | SSH_GLOBUS_USAGE_CLIENTIP = 'I', | |
48 | SSH_GLOBUS_USAGE_USERNAME = 'u', | |
49 | SSH_GLOBUS_USAGE_USERDN = 'U' | |
50 | /* !! ADD to ALL_TAGLIST above and to globus_usage_stats_send() | |
51 | invocation below when adding here */ | |
52 | } ssh_usage_tag_t; | |
53 | ||
54 | typedef struct ssh_usage_ent_s | |
55 | { | |
56 | globus_usage_stats_handle_t handle; | |
57 | char * target; | |
58 | char * taglist; | |
59 | } ssh_usage_ent_t; | |
60 | ||
61 | ||
62 | globus_result_t | |
63 | ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets) | |
64 | { | |
65 | globus_result_t result; | |
66 | char * target_str = NULL; | |
67 | char * ptr = ptr; | |
68 | char * target = NULL; | |
69 | char * entry = NULL; | |
70 | globus_list_t * list = NULL; | |
71 | ssh_usage_ent_t * usage_ent = NULL; | |
72 | ||
73 | if (disable_usage_stats) | |
74 | return GLOBUS_SUCCESS; | |
75 | ||
76 | result = globus_module_activate(GLOBUS_USAGE_MODULE); | |
77 | if (result != GLOBUS_SUCCESS) | |
78 | { | |
79 | error("ERROR: couldn't activate USAGE module"); | |
80 | return result; | |
81 | } | |
82 | ||
83 | if (!usage_stats_targets || | |
84 | !strcasecmp(usage_stats_targets, "default")) | |
85 | target_str = strdup(CILOGON_COLLECTOR); | |
86 | else | |
87 | target_str = strdup(usage_stats_targets); | |
88 | ||
89 | if (target_str == NULL) | |
90 | { | |
91 | error("ERROR: strdup failure for target_str"); | |
92 | goto error; | |
93 | } | |
94 | debug("Processing usage_stats_target (%s)\n", target_str); | |
95 | ||
96 | if(target_str && strchr(target_str, '!')) | |
97 | { | |
98 | target = target_str; | |
99 | ||
100 | do { | |
101 | usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t)); | |
102 | if (usage_ent == NULL) | |
103 | { | |
104 | error("ERROR: couldn't allocate for ssh_usage_ent_t"); | |
105 | goto error; | |
106 | } | |
107 | ||
108 | if ((ptr = strchr(target, ',')) != NULL) | |
109 | *ptr = '\0'; | |
110 | ||
111 | entry = strdup(target); | |
112 | if (entry == NULL) | |
113 | { | |
114 | error("ERROR: strdup failure for target"); | |
115 | goto error; | |
116 | } | |
117 | ||
118 | if (ptr) | |
119 | target = ptr + 1; | |
120 | else | |
121 | target = NULL; | |
122 | ||
123 | if((ptr = strchr(entry, '!')) != NULL) | |
124 | { | |
125 | *ptr = '\0'; | |
126 | usage_ent->taglist = strdup(ptr + 1); | |
127 | if (usage_ent->taglist == NULL) | |
128 | { | |
129 | error("ERROR: strdup failure for taglist"); | |
130 | goto error; | |
131 | } | |
132 | if(strlen(usage_ent->taglist) > SSH_GLOBUS_TAGCOUNT) | |
133 | { | |
134 | usage_ent->taglist[SSH_GLOBUS_TAGCOUNT + 1] = '\0'; | |
135 | } | |
136 | } | |
137 | else | |
138 | { | |
139 | usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); | |
140 | if (usage_ent->taglist == NULL) | |
141 | { | |
142 | error("ERROR: couldn't allocate for taglist"); | |
143 | goto error; | |
144 | } | |
145 | } | |
146 | ||
147 | if(strcasecmp(usage_ent->taglist, "default") == 0) | |
148 | { | |
149 | free(usage_ent->taglist); | |
150 | usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); | |
151 | if (usage_ent->taglist == NULL) | |
152 | { | |
153 | error("ERROR: couldn't allocate for taglist"); | |
154 | goto error; | |
155 | } | |
156 | } | |
157 | else if(strcasecmp(usage_ent->taglist, "all") == 0) | |
158 | { | |
159 | free(usage_ent->taglist); | |
160 | usage_ent->taglist = strdup(SSH_GLOBUS_ALL_TAGLIST); | |
161 | if (usage_ent->taglist == NULL) | |
162 | { | |
163 | error("ERROR: couldn't allocate for taglist"); | |
164 | goto error; | |
165 | } | |
166 | } | |
167 | ||
168 | usage_ent->target = entry; | |
169 | ||
170 | globus_list_insert(&usage_handle_list, usage_ent); | |
171 | } | |
172 | while(target != NULL); | |
173 | ||
174 | free(target_str); | |
175 | } | |
176 | else | |
177 | { | |
178 | usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t)); | |
179 | if (usage_ent == NULL) | |
180 | { | |
181 | error("ERROR: couldn't allocate for usage_ent"); | |
182 | goto error; | |
183 | } | |
184 | ||
185 | usage_ent->target = target_str; | |
186 | usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST); | |
187 | if (usage_ent->taglist == NULL) | |
188 | { | |
189 | error("ERROR: couldn't allocate for taglist"); | |
190 | goto error; | |
191 | } | |
192 | ||
193 | globus_list_insert(&usage_handle_list, usage_ent); | |
194 | } | |
195 | ||
196 | ||
197 | for(list = usage_handle_list; | |
198 | !globus_list_empty(list); | |
199 | list = globus_list_rest(list)) | |
200 | { | |
201 | usage_ent = (ssh_usage_ent_t *) globus_list_first(list); | |
202 | ||
203 | usage_ent->handle = NULL; | |
204 | debug("USAGE: Initializing (%s) (%s)", usage_ent->target?:"NULL", | |
205 | usage_ent->taglist?:"NULL"); | |
206 | result = globus_usage_stats_handle_init( | |
207 | &usage_ent->handle, | |
208 | SSH_GLOBUS_USAGE_ID, | |
209 | SSH_GLOBUS_USAGE_VER, | |
210 | usage_ent->target); | |
211 | } | |
212 | ||
213 | return result; | |
214 | ||
215 | error: | |
216 | if (target_str) | |
217 | { | |
218 | free(target_str); | |
219 | target_str = NULL; | |
220 | } | |
221 | if (entry) | |
222 | { | |
223 | free(target_str); | |
224 | target_str = NULL; | |
225 | } | |
226 | return GLOBUS_FAILURE; | |
227 | } | |
228 | ||
229 | void | |
230 | ssh_usage_stats_close(int disable_usage_stats) | |
231 | { | |
232 | globus_list_t *list; | |
233 | ||
234 | if (disable_usage_stats) | |
235 | return; | |
236 | ||
237 | list = usage_handle_list; | |
238 | ||
239 | while(!globus_list_empty(list)) | |
240 | { | |
241 | ssh_usage_ent_t *usage_ent; | |
242 | ||
243 | usage_ent = (ssh_usage_ent_t *) | |
244 | globus_list_remove(&list, list); | |
245 | ||
246 | if(usage_ent) | |
247 | { | |
248 | if(usage_ent->handle) | |
249 | { | |
250 | globus_usage_stats_handle_destroy(usage_ent->handle); | |
251 | } | |
252 | if(usage_ent->target) | |
253 | { | |
254 | free(usage_ent->target); | |
255 | } | |
256 | if(usage_ent->taglist) | |
257 | { | |
258 | free(usage_ent->taglist); | |
259 | } | |
260 | free(usage_ent); | |
261 | } | |
262 | } | |
263 | usage_handle_list = NULL; | |
264 | } | |
265 | ||
266 | static void | |
267 | log_usage_stats(char *ssh_release, const char *ssl_release, | |
268 | char *method, char *mechanism, const char *clientip, | |
269 | char *username, char *userdn) | |
270 | { | |
271 | globus_result_t result; | |
272 | globus_list_t * list; | |
273 | ssh_usage_ent_t * usage_ent; | |
274 | char * keys[SSH_GLOBUS_TAGCOUNT]; | |
275 | char * values[SSH_GLOBUS_TAGCOUNT]; | |
276 | char * ptr; | |
277 | char * key; | |
278 | char * value; | |
279 | int i = 0; | |
280 | char * save_taglist = NULL; | |
281 | ||
282 | for(list = usage_handle_list; | |
283 | !globus_list_empty(list); | |
284 | list = globus_list_rest(list)) | |
285 | { | |
286 | usage_ent = (ssh_usage_ent_t *) globus_list_first(list); | |
287 | ||
288 | if(!usage_ent || usage_ent->handle == NULL) | |
289 | return; | |
290 | ||
291 | if(save_taglist == NULL || | |
292 | strcmp(save_taglist, usage_ent->taglist) != 0) | |
293 | { | |
294 | save_taglist = usage_ent->taglist; | |
295 | ||
296 | ptr = usage_ent->taglist; | |
297 | i = 0; | |
298 | while(ptr && *ptr) | |
299 | { | |
300 | switch(*ptr) | |
301 | { | |
302 | case SSH_GLOBUS_USAGE_SSH_VER: | |
303 | key = "SSH_VER"; | |
304 | value = ssh_release; | |
305 | break; | |
306 | ||
307 | case SSH_GLOBUS_USAGE_SSL_VER: | |
308 | key = "SSL_VER"; | |
309 | value = (char *) ssl_release; | |
310 | break; | |
311 | ||
312 | case SSH_GLOBUS_USAGE_METHOD: | |
313 | key = "METHOD"; | |
314 | value = method; | |
315 | break; | |
316 | ||
317 | case SSH_GLOBUS_USAGE_MECHANISM: | |
318 | key = "MECH"; | |
319 | value = mechanism?:""; | |
320 | break; | |
321 | ||
322 | case SSH_GLOBUS_USAGE_CLIENTIP: | |
323 | key = "CLIENTIP"; | |
324 | value = (char *) clientip?:""; | |
325 | break; | |
326 | ||
327 | case SSH_GLOBUS_USAGE_USERNAME: | |
328 | key = "USER"; | |
329 | value = username?:""; | |
330 | break; | |
331 | ||
332 | case SSH_GLOBUS_USAGE_USERDN: | |
333 | key = "USERDN"; | |
334 | value = userdn?:""; | |
335 | break; | |
336 | ||
337 | default: | |
338 | key = NULL; | |
339 | value = NULL; | |
340 | break; | |
341 | } | |
342 | ||
343 | if(key != NULL && value != NULL) | |
344 | { | |
345 | keys[i] = key; | |
346 | values[i] = value; | |
347 | i++; | |
348 | } | |
349 | ||
350 | ptr++; | |
351 | } | |
352 | } | |
353 | ||
354 | #ifdef HAVE_GLOBUS_USAGE_SEND_ARRAY | |
355 | result = globus_usage_stats_send_array( | |
356 | usage_ent->handle, i, keys, values); | |
357 | #else | |
358 | if (i) | |
359 | result = globus_usage_stats_send( | |
360 | usage_ent->handle, i, | |
361 | i>0?keys[0]:NULL, i>0?values[0]:NULL, | |
362 | i>1?keys[1]:NULL, i>1?values[1]:NULL, | |
363 | i>2?keys[2]:NULL, i>2?values[2]:NULL, | |
364 | i>3?keys[3]:NULL, i>3?values[3]:NULL, | |
365 | i>4?keys[4]:NULL, i>4?values[4]:NULL, | |
366 | i>5?keys[5]:NULL, i>5?values[5]:NULL, | |
367 | i>6?keys[6]:NULL, i>6?values[6]:NULL); | |
368 | #endif /* HAVE_GLOBUS_USAGE_SEND_ARRAY */ | |
369 | } | |
370 | ||
371 | return; | |
372 | } | |
373 | #endif /* HAVE_GLOBUS_USAGE */ | |
374 | ||
375 | void | |
376 | ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release, | |
377 | char *method, char *mechanism, const char *client_ip, | |
378 | char *username, char *userdn) | |
379 | { | |
380 | #ifdef HAVE_GLOBUS_USAGE | |
381 | ||
382 | log_usage_stats(ssh_release, ssl_release, method, mechanism, | |
383 | client_ip, username, userdn); | |
384 | ||
385 | #endif /* HAVE_GLOBUS_USAGE */ | |
386 | } |