00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <biosphere_module.h>
00036 #include <io.h>
00037 #include <list.h>
00038 #include <str.h>
00039 #include <type.h>
00040
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 #include <unistd.h>
00045 #include <apr_strings.h>
00046 #include <apr_thread_proc.h>
00047 #include <sys/time.h>
00048
00049
00059 bs_module bsmod_symtable;
00060
00064 static FILE *companion;
00065
00069 static apr_pool_t *mempool;
00070
00071
00075 static bs_status bsmod_keystroke_init(void)
00076 {
00077
00078 mempool = NULL;
00079 apr_pool_create(&mempool, NULL);
00080 if (!mempool) return BS_ERROR;
00081
00082
00083 companion = popen("java -cp /usr/local/keystroke/keystroke.jar:/usr/local/weka/weka.jar keystroke.KeystrokeCompanion", "w");
00084 if (!companion) {
00085 printf("Could not open companion program");
00086 return BS_ERROR;
00087 }
00088 setvbuf(companion, NULL, _IONBF, 0);
00089 return BS_OK;
00090 }
00091
00092
00098 static void remove_temp_file(void)
00099 {
00100 unlink("/usr/local/keystroke/answer.tmp");
00101 }
00102
00103
00107 static bs_status bsmod_keystroke_cleanup(void)
00108 {
00109 apr_pool_destroy(mempool);
00110 fprintf(companion, "END\n");
00111 pclose(companion);
00112 return BS_OK;
00113 }
00114
00115
00123 static bs_service_response *create_status_response(
00124 const bs_service_request *request, bs_status status, char *message)
00125 {
00126 bs_service_response *resp;
00127 bs_message_instance *output = NULL;
00128 bs_part_instance *part1 = NULL, *part2 = NULL;
00129 bs_data_type *type1 = NULL, *type2 = NULL;
00130 char *data, *data2;
00131
00132 data = apr_psprintf(mempool, "%u", status);
00133 data2 = apr_psprintf(mempool, "%s", message);
00134 type1 = new_bs_data_type(mempool, "bs_uint32");
00135 if (!type1) return NULL;
00136 type2 = new_bs_data_type(mempool, "bs_string");
00137 if (!type2) return NULL;
00138
00139 part1 = new_bs_part_instance(mempool, "code", type1,
00140 data, strlen(data));
00141 part2 = new_bs_part_instance(mempool, "message", type2,
00142 data2, strlen(data2));
00143 if (!part1 || !part2) return NULL;
00144 output = new_bs_message_instance(mempool, "BSStatusMessage", 2);
00145 if (!output) return NULL;
00146 output->parts[0] = part1;
00147 output->parts[1] = part2;
00148 resp = new_bs_service_response(mempool, request->uuid,
00149 request->service, request->port, request->operation,
00150 output, NULL);
00151
00152 return resp;
00153 }
00154
00155
00160 static bs_service_response *make_answer(const bs_service_request *request)
00161 {
00162 bs_status rv;
00163 char *respbuf;
00164 bs_uint64 len;
00165
00166 rv = read_file_into_buf("/usr/local/keystroke/answer.tmp", &respbuf, &len, mempool);
00167 if (rv != BS_OK || len == 0) {
00168 return create_status_response(request, 1, "Could not read temp file.");
00169 }
00170
00171 remove_temp_file();
00172 return create_status_response(request, atoi(respbuf), respbuf + 2);
00173 }
00174
00175
00179 static void wait_for_answer(void)
00180 {
00181 while (system("test -r /usr/local/keystroke/answer.tmp")) {
00182 apr_thread_yield();
00183 }
00184 }
00185
00186
00191 static bs_status bsmod_keystroke_handle_service(
00192 const bs_service_request *request,
00193 bs_service_response **response, void *extra)
00194 {
00195 struct timeval t;
00196 gettimeofday(&t, 0);
00197 printf("%ld.%06ld,", t.tv_sec, t.tv_usec);
00198
00199 remove_temp_file();
00200
00201
00202 if (streq(request->operation, "enroll")) {
00203 fprintf(companion, "ENROLL %s\n", request->input->parts[0]->data);
00204 }
00205 else if (streq(request->operation, "remove")) {
00206 fprintf(companion, "REMOVE %s\n", request->input->parts[0]->data);
00207 }
00208 else if (streq(request->operation, "addVector")) {
00209 fprintf(companion, "ADD %s %s %s\n",
00210 request->input->parts[0]->data,
00211 request->input->parts[1]->data,
00212 request->input->parts[2]->data);
00213 }
00214 else if (streq(request->operation, "train")) {
00215 fprintf(companion, "TRAIN %s %s\n",
00216 request->input->parts[0]->data,
00217 request->input->parts[1]->data);
00218 }
00219 else if (streq(request->operation, "verify")) {
00220 fprintf(companion, "VERIFY %s %s %s\n",
00221 request->input->parts[0]->data,
00222 request->input->parts[1]->data,
00223 request->input->parts[2]->data);
00224 }
00225 else if (streq(request->operation, "verify_threshold")) {
00226 fprintf(companion, "VERIFYTHRESHOLD %s %s %s\n",
00227 request->input->parts[0]->data,
00228 request->input->parts[1]->data,
00229 request->input->parts[2]->data);
00230 }
00231 else return BS_NO_SERVICE;
00232
00233 wait_for_answer();
00234 *response = make_answer(request);
00235
00236 gettimeofday(&t, 0);
00237 printf("%ld.%06ld,", t.tv_sec, t.tv_usec);
00238 return BS_OK;
00239 }
00240
00241
00242
00243
00244
00245 bs_module bsmod_symtable = {
00246
00247 0,
00248 0,
00249
00250
00251 0,
00252 1,
00253
00254
00255 "keystroke module",
00256 "M.A.Hartman",
00257 "apr 10, 2007",
00258 "(c) 2007, M.A.Hartman. See distributed LICENSE file for more information.",
00259 "A keystroking biometrics module. It implements some basic keystroking "
00260 "methods based mostly on text-dependent input, such as passwords.",
00261
00262
00263 bsmod_keystroke_init,
00264 bsmod_keystroke_cleanup,
00265
00266
00267 bsmod_keystroke_handle_service,
00268 NULL,
00269 "bsmod_keystroke.wsdl"
00270 };
00271