]> andersk Git - gssapi-openssh.git/blame - openssh/ssh-globus-usage.c
Added support for reporting usage metrics.
[gssapi-openssh.git] / openssh / ssh-globus-usage.c
CommitLineData
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
32static 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
41typedef 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
54typedef 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
62globus_result_t
63ssh_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
215error:
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
229void
230ssh_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
266static void
267log_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
375void
376ssh_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}
This page took 0.09393 seconds and 5 git commands to generate.