00001
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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifdef __cplusplus
00063 extern "C" {
00064 #endif
00065
00066 #include <sys/mman.h>
00067 #if defined(_WIN32)
00068 #include <io.h>
00069 #else
00070 #include <unistd.h>
00071 #endif
00072 #include <assert.h>
00073 #include <sys/types.h>
00074 #include <sys/stat.h>
00075 #include <errno.h>
00076 #include <stdio.h>
00077 #include <string.h>
00078 #include <stdlib.h>
00079 #include <fcntl.h>
00080 #include <openssl/rand.h>
00081
00082 #include <uuid/uuid.h>
00083
00084 #include "lcg_util.h"
00085 #include "ss-util.h"
00086 #include "keystore_client.h"
00087
00088 #ifdef __cplusplus
00089 }
00090 #endif
00091
00092 int securestorage_nerr = 56;
00093 extern int errno;
00094
00095
00096
00097 void ivec_inc(unsigned char *counter) {
00098 unsigned long c;
00099
00100
00101 c = GETU32(counter + 12);
00102 c++; c &= 0xFFFFFFFF;
00103 PUTU32(counter + 12, c);
00104
00105
00106 if (c)
00107 return;
00108
00109
00110 c = GETU32(counter + 8);
00111 c++; c &= 0xFFFFFFFF;
00112 PUTU32(counter + 8, c);
00113
00114
00115 if (c)
00116 return;
00117
00118
00119 c = GETU32(counter + 4);
00120 c++; c &= 0xFFFFFFFF;
00121 PUTU32(counter + 4, c);
00122
00123
00124 if (c)
00125 return;
00126
00127
00128 c = GETU32(counter + 0);
00129 c++; c &= 0xFFFFFFFF;
00130 PUTU32(counter + 0, c);
00131 }
00132
00133
00134
00135
00136 void ivec_dec(unsigned char *counter) {
00137 unsigned long c;
00138
00139
00140 c = GETU32(counter + 12);
00141 if (!c) {
00142 c--; c &= 0xFFFFFFFF;
00143 PUTU32(counter + 12, c);
00144 } else {
00145 c--; c &= 0xFFFFFFFF;
00146 PUTU32(counter + 12, c);
00147 return;
00148 }
00149
00150
00151 c = GETU32(counter + 8);
00152 if (!c) {
00153 c--; c &= 0xFFFFFFFF;
00154 PUTU32(counter + 8, c);
00155 } else {
00156 c--; c &= 0xFFFFFFFF;
00157 PUTU32(counter + 8, c);
00158 return;
00159 }
00160
00161
00162 c = GETU32(counter + 4);
00163 if (!c) {
00164 c--; c &= 0xFFFFFFFF;
00165 PUTU32(counter + 4, c);
00166 } else {
00167 c--; c &= 0xFFFFFFFF;
00168 PUTU32(counter + 4, c);
00169 return;
00170 }
00171
00172
00173 c = GETU32(counter + 0);
00174 c--; c &= 0xFFFFFFFF;
00175 PUTU32(counter + 0, c);
00176
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 void securestorage_AES_ctr(const unsigned char *in, unsigned char *out,
00194 const unsigned long length, const AES_KEY *key,
00195 unsigned char ivec[AES_BLOCK_SIZE],
00196 unsigned char ecount_buf[AES_BLOCK_SIZE],
00197 unsigned int *num) {
00198
00199 unsigned int n;
00200 unsigned long l=length;
00201
00202 assert(in && out && key && num);
00203 assert(*num < AES_BLOCK_SIZE);
00204
00205 n = *num;
00206
00207 while (l--) {
00208 if (n == 0) {
00209 AES_encrypt(ivec, ecount_buf, key);
00210 ivec_inc(ivec);
00211 }
00212 *(out++) = *(in++) ^ ecount_buf[n];
00213 n = (n+1) % AES_BLOCK_SIZE;
00214 }
00215
00216 *num=n;
00217 }
00218
00219
00220
00221
00222
00223 size_t lock_memory(char *addr, size_t size) {
00224 unsigned long page_offset, page_size;
00225 page_size = sysconf(_SC_PAGE_SIZE);
00226 page_offset = (unsigned long) addr % page_size;
00227 addr -= page_offset;
00228 size += page_offset;
00229 return ( mlock(addr, size) );
00230 }
00231
00232
00233
00234
00235
00236 size_t unlock_memory(char *addr, size_t size) {
00237 unsigned long page_offset, page_size;
00238 page_size = sysconf(_SC_PAGE_SIZE);
00239 page_offset = (unsigned long) addr % page_size;
00240 addr -= page_offset;
00241 size += page_offset;
00242 return ( munlock(addr, size) );
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252 int ss_rand (int size, unsigned char *out) {
00253
00254 int i, c;
00255 unsigned char temp[(size/2)+1];
00256 const char hex[] = "0123456789ABCDEF";
00257
00258 if ( size <= 0 ) {
00259 errno = EINVAL;
00260 return (-2);
00261 }
00262 if (!out) {
00263 errno = EINVAL;
00264 return (-1);
00265 }
00266
00267 if (!RAND_load_file("/dev/urandom", 1)) {
00268 int errno_save = errno;
00269 RAND_cleanup();
00270 errno = errno_save;
00271 return (-3);
00272 }
00273
00274 RAND_bytes((unsigned char *)temp, (size/2));
00275
00276 c = size/2;
00277
00278 for (i = 0; i < c; i++) {
00279 out[i*2] = hex[temp[i] >> 4];
00280 out[i*2+1] = hex[temp[i] & 15];
00281 }
00282
00283 return (0);
00284 }
00285
00286
00287
00288
00289
00290
00291
00292 int ss_generate_surl (char **dest_surl, char *dest_file, char *vo, char *guid) {
00293
00294
00295 char timestr[11];
00296 struct tm *tm;
00297 char *surl;
00298 time_t current_time;
00299 char guid_f[37];
00300 uuid_t uuid;
00301 char dir_path[256];
00302 char *ce_ap, *sa_root, *sa_path;
00303 char *errbuf2=NULL;
00304 int errbufsz2 = 0;
00305 char setype[8];
00306
00307 if (NULL == ( surl = calloc(1, 512+1)) ) {
00308 errno = ENOMEM;
00309 return (-1);
00310 }
00311 if(get_sa_path (dest_file, vo, &sa_path, &sa_root, errbuf2, errbufsz2) < 0) {
00312 int errno_save = errno;
00313 free(surl);
00314 errno = errno_save;
00315 return (-2);
00316 }
00317 if(sa_path != NULL) {
00318 if (strcmp (setype, "disk") == 0) {
00319 sprintf (dir_path, "sfn://%s%s%s", dest_file, *sa_path=='/'?"":"/", sa_path);
00320 }
00321 else {
00322 sprintf (dir_path, "srm://%s%s%s", dest_file, *sa_path=='/'?"":"/", sa_path);
00323 }
00324 }
00325 else {
00326 if (strcmp (setype, "disk") == 0) {
00327 if (get_ce_apx (dest_file, &ce_ap, errbuf2, errbufsz2) < 0) {
00328 int errno_save = errno;
00329 free(surl);
00330 errno = errno_save;
00331 return (-3);
00332 }
00333 sprintf (dir_path, "sfn://%s%s%s%s%s", dest_file,
00334 *ce_ap=='/'?"":"/", ce_ap,
00335 *sa_root=='/'?"":"/", sa_root);
00336 free (ce_ap);
00337 }
00338 else {
00339 sprintf (dir_path, "srm://%s%s%s", dest_file, *sa_root=='/'?"":"/", sa_root); }
00340 }
00341 free (sa_path); free (sa_root);
00342 (void) time (¤t_time);
00343 tm = localtime (¤t_time);
00344 strftime (timestr, 11, "%F", tm);
00345 uuid_generate (uuid);
00346 uuid_unparse (uuid, guid_f);
00347 if (guid == NULL)
00348 sprintf (surl, "%s/generated/%s/file%s", dir_path, timestr, guid_f);
00349 else
00350 sprintf (surl, "%s/generated/%s/file%s", dir_path, timestr, guid);
00351
00352 *dest_surl = surl;
00353 return 0;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 int ss_get_lfchome ( const char *input_lfn, char **lfn_new ) {
00363
00364
00365 char cattype[8];
00366 char *cat_type;
00367 char lfn[LCG_MAXPATHLEN+5];
00368 char *p;
00369 int strip=0;
00370 char *lfn_local;
00371 const char *input_lfn_tmp = input_lfn;
00372
00373 if(get_cat_type (&cat_type) < 0) {
00374 return (-1);
00375 }
00376 strcpy (cattype, cat_type);
00377 free (cat_type);
00378
00379
00380 if(strcmp(cattype , "lfc") == 0) {
00381 if (strncmp (input_lfn_tmp, "lfn:", 4) == 0) {
00382 input_lfn_tmp += 4;
00383
00384 if ( strncmp(input_lfn_tmp,"/",1)==0 ) {
00385 while ( strncmp(input_lfn_tmp,"/",1)==0) {
00386 input_lfn_tmp+=1;
00387 strip++;
00388 }
00389 input_lfn_tmp-=1;
00390 strip--;
00391 }
00392
00393 if (strncmp (input_lfn_tmp, "/grid", 5) == 0 ) {
00394 sprintf (lfn, "lfn:%s", input_lfn_tmp);
00395 lfn_local = calloc(1,strlen(lfn)+1);
00396 strncpy(lfn_local, lfn, strlen(lfn));
00397 *lfn_new = lfn_local;
00398 return 0;
00399 } else if ( (strncmp(input_lfn_tmp,"/",1)==0) && (getenv("LFC_HOME")==NULL) ) {
00400 errno = SS_EINVALLFN;
00401 return (-2);
00402 } else {
00403 p = getenv ("LFC_HOME");
00404 if(p == NULL) {
00405 errno = SS_EINVALLFN;
00406 return (-3);
00407 } else if ( strlen (p) + strlen (input_lfn_tmp) + 1 > LCG_MAXPATHLEN ) {
00408 errno = SS_ENAMETOOLONG;
00409 return (-4);
00410 } else {
00411 if ( strncmp(input_lfn_tmp,"/",1) == 0 )
00412 input_lfn_tmp++;
00413 sprintf (lfn, "lfn:%s/%s", p, input_lfn_tmp);
00414 lfn_local = calloc(1,strlen(lfn)+1);
00415 strncpy(lfn_local, lfn, strlen(lfn));
00416 }
00417 }
00418 } else {
00419 errno = SS_EINVALLFN;
00420 return (-5);
00421 }
00422 } else {
00423 errno = SS_EINVALLFN;
00424 return (-6);
00425 }
00426
00427 *lfn_new = lfn_local;
00428 return 0;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437 int ss_get_surl ( char *lfn, char **surl, char *vo, char *se, int insecure ) {
00438
00439
00440 char **pfns;
00441 int x;
00442
00443
00444 if (strncmp (lfn, "lfn:", 4) == 0) {
00445 if (lcg_lr (lfn, vo, NULL, insecure, &pfns) < 0) {
00446 return (-1);
00447 }
00448
00449 if (pfns[0]== NULL) {
00450 errno = SS_ENOENT;
00451 return (-2);
00452 } else {
00453
00454 if (se == NULL){
00455 *surl = strdup(pfns[0]);
00456 } else {
00457 int g = strcspn(se, "\n");
00458 for (x=0;pfns[x]!=NULL;x++){
00459 pfns[x]+=6;
00460 if (strncmp (pfns[x], se, g) == 0){
00461 pfns[x]-=6;
00462 *surl = strdup(pfns[x]);
00463 break;
00464 }
00465 pfns[x]-=6;
00466 }
00467
00468 if (pfns[x] == NULL){
00469 for(x=0;pfns[x]!=NULL;x++) {
00470 free(pfns[x]);
00471 }
00472 free(pfns);
00473 errno = SS_ENOENT;
00474 return (-1);
00475 }
00476 }
00477 for(x=0;pfns[x]!=NULL;x++) {
00478 free(pfns[x]);
00479 }
00480 free(pfns);
00481 if ( *surl==NULL) {
00482 errno = ENOMEM;
00483 return (-1);
00484 }
00485 }
00486 }
00487 else if ( (strncmp (lfn, "srm:", 4) == 0)) {
00488 errno = SS_EINVALLFN;
00489 return (-1);
00490 } else {
00491 errno = SS_EINVALLFN;
00492 return (-1);
00493 }
00494 return 0;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503 int ss_check_lfn ( char *lfn, char *vo ) {
00504
00505
00506 char **pfns;
00507 int x;
00508 int insecure=0;
00509 int errno_save;
00510
00511
00512 if (strncmp (lfn, "lfn:", 4) == 0) {
00513 if (lcg_lr (lfn, vo, NULL, insecure, &pfns) < 0) {
00514 errno_save = errno;
00515 if (errno_save == ENOENT) {
00516 return (0);
00517 } else {
00518 errno = errno_save;
00519 return(-1);
00520 }
00521 }
00522 if (pfns[0] != NULL) {
00523 for(x=0;pfns[x]!=NULL;x++) {
00524 free(pfns[x]);
00525 }
00526 free(pfns);
00527 }
00528 }
00529 else if ( (strncmp (lfn, "srm:", 4) == 0)) {
00530 errno = SS_EINVALLFN;
00531 return (-1);
00532 } else {
00533 errno = SS_EINVALLFN;
00534 return (-1);
00535 }
00536 return (1);
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546 const char *securestorage_error(int errnum) {
00547
00548 extern char *ss_errlist[];
00549 if (errnum < 10000 && errnum < sys_nerr ) {
00550
00551
00552 return(sys_errlist[errnum]);
00553 }
00554 int errnum_tmp = errnum - 10000;
00555 static char message[] = "Unknown error (100001234567890)";
00556 if (errnum_tmp >= securestorage_nerr) {
00557 snprintf(message, sizeof(message), "Unknown error (%d)", errnum_tmp);
00558 return(message);
00559 } else {
00560 return(ss_errlist[errnum_tmp]);
00561 }
00562 }