Main Page | Data Structures | File List | Data Fields | Globals

securestorage_api.c

Go to the documentation of this file.
00001 
00008 /******************************************************************************
00009  *
00010  *      File:                   securestorage_api.c
00011  *
00012  *      Function:               Secure Storage API source file
00013  *
00014  *      Author(s):              Giordano Scuderi and Nicola Dominante
00015  *
00016  *      Copyright:              Copyright (c) 2007 <Giordano Scuderi - gscuderi@unicosrl.it>
00017  *                                      All Rights Reserved.
00018  *
00019  *
00020  *      Notes:                  Redistributions of any form whatsoever must retain the following
00021  *                              acknowledgment:
00022  *                              "This product includes software developed by Giordano Scuderi
00023  *                              for Unico SRL"
00024  *
00025  * ====================================================================
00026  * Copyright (c) Giordano Scuderi, Unico SRL.  All rights reserved.
00027  *
00028  * Redistribution and use in source and binary forms, with or without
00029  * modification, are permitted provided that the following conditions
00030  * are met:
00031  *
00032  * 1. Redistributions of source code must retain the above copyright
00033  *    notice, this list of conditions and the following disclaimer. 
00034  *
00035  * 2. Redistributions in binary form must reproduce the above copyright
00036  *    notice, this list of conditions and the following disclaimer in
00037  *    the documentation and/or other materials provided with the
00038  *    distribution.
00039  *
00040  * 3. All advertising materials mentioning features or use of this
00041  *    software must display the following acknowledgment:
00042  *    "This product includes software developed by Giordano Scuderi
00043  *    for Unico SRL"
00044  *
00045  * 4. The names "Secure Storage" must not be used to
00046  *    endorse or promote products derived from this software without
00047  *    prior written permission. For written permission, please contact
00048  *    gscuderi@unicosrl.it.
00049  *
00050  * 5. Products derived from this software may not be called "Secure Storage"
00051  *    nor may "Secure Storage" appear in their names without prior written
00052  *    permission of Giordano Scuderi (Unico SRL).
00053  *
00054  * 6. Redistributions of any form whatsoever must retain the following
00055  *    acknowledgment:
00056  *    "This product includes software developed by Giordano Scuderi
00057  *    for Unico SRL"
00058  *
00059  * THIS SOFTWARE IS PROVIDED BY UNICO SRL ``AS IS'' AND ANY
00060  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00061  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00062  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNICO SRL OR
00063  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00064  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00065  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00066  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00067  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00068  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00069  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00070  * OF THE POSSIBILITY OF SUCH DAMAGE.
00071  * ====================================================================
00072  *
00073  * "This product includes software developed by the OpenSSL Project
00074  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
00075  * 
00076  */
00077 
00078 #ifdef __cplusplus
00079 extern "C"
00080 {
00081 #endif
00082 
00083 #include <sys/types.h>
00084 #include <errno.h>
00085 #include <stdio.h>
00086 #include <dirent.h>
00087 #include <fcntl.h>
00088 #include <time.h>
00089 #include <sys/stat.h>
00090 #include <stdlib.h>
00091 #include <string.h>
00092 #include <ctype.h>
00093 #if defined(_WIN32)
00094 #include <io.h>
00095 #else
00096 #include <unistd.h>
00097 #endif
00098 #include <gfal_api.h>
00099 #include "lcg_util.h"
00100 #include "ss-util.h"
00101 #include "keystore_client.h"
00102 #include "securestorage.h"
00103 #include "securestorage_api.h"
00104 
00105 #ifdef __cplusplus
00106 }
00107 #endif
00108 
00109 // Struct that contains some data of open file
00110 static struct ss_state *ss_array[MAX_OPEN_FILES];
00111 
00112 extern int serrno;
00113 extern int errno;
00114 
00115 /******************************************************************************
00116  * Alloc mem on ss_array struct and save file descriptor of open file on
00117  * remote SE
00118  * 
00119  ******************************************************************************/
00120 
00121 static struct ss_state *alloc_ss_state (int fd) {
00122         if (fd >= 0 && fd < MAX_OPEN_FILES && ss_array[fd] == NULL)
00123                return (ss_array[fd] = (struct ss_state *) calloc (1, sizeof(struct ss_state)));
00124         errno = EBADF;
00125         return (NULL);
00126 }
00127 
00128 
00129 /******************************************************************************
00130  * Find correct position on ss_array struct with index (fd)
00131  *
00132  * 
00133  ******************************************************************************/
00134 
00135 static struct ss_state *find_ss_state (int fd)
00136 {
00137         if (fd >= 0 && fd < MAX_OPEN_FILES && ss_array[fd])
00138                 return (ss_array[fd]);
00139         errno = EBADF;
00140         return (NULL);
00141 }
00142 
00143 
00144 /******************************************************************************
00145  * Free mem on ss_array struct
00146  *
00147  * 
00148  ******************************************************************************/
00149 
00150 static int free_ss_state (int fd)
00151 {
00152         if (fd >= 0 && fd < MAX_OPEN_FILES && ss_array[fd]) {
00153                 free (ss_array[fd]);
00154                 ss_array[fd] = NULL;
00155         }
00156         return (0);
00157 }
00158 
00159 
00160 
00161 /******************************************************************************
00162  * Open remote file on SE
00163  * extended version ( user could specify VO, GUID and destination SE
00164  * 
00165  ******************************************************************************/
00166 
00167 int securestorage_open_extended(char *lfn, int flags, mode_t mode, 
00168                                                                         char *vo, char *guid, char *se) {
00169         
00170         // Variable definition
00171         struct ss_state *ss;
00172         unsigned char hex_key[HEX_KEYSIZE+1];
00173         unsigned char hex_iv[HEX_IVSIZE+1];
00174         char *dest_surl;
00175         char *lfn_new;
00176         char *conf_file=NULL;
00177         char actual_gid[37];
00178         int fd;
00179         const char *accept_host=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.-";
00180         const char *accept_vo=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789-";
00181         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
00182         size_t inv;
00183         int insecure=0;
00184         int verbose=0;
00185         
00186         memset(hex_key,'\0',HEX_KEYSIZE+1);
00187         memset(hex_iv,'\0',HEX_IVSIZE+1);
00188         
00189         // Verify if VO was specified
00190         if (!vo) {
00191                 errno = SS_EINVALVO;
00192                 return (-1);
00193         }
00194         // Verify if guid was specified
00195         if (guid) {
00196                 if (strlen(guid)!=36 ) {
00197                         errno = SS_EINVALGUID;
00198                         return (-1);
00199                 }
00200         }
00201         // Input parameters filter
00202         if (se){
00203                 inv=0;
00204                 inv = strspn(se, accept_host);
00205                 if (inv != strlen(se) ) {
00206                         errno = SS_EINVALSE;
00207                         return (-1);
00208                 }
00209         }
00210         inv=0;
00211         inv = strspn(vo, accept_vo);
00212         if (inv != strlen(vo) ) {
00213                 errno = SS_EINVALVO;
00214                 return (-1);
00215         }       
00216         // Add LFC_HOME to LFN
00217         if ( ss_get_lfchome(lfn, &lfn_new) < 0 ) {
00218                 return (-1);
00219         }
00220         inv=0;
00221         inv = strspn(lfn_new, accept_lfn);
00222         if (inv != strlen(lfn_new) ) {
00223                 free(lfn_new);
00224                 errno = SS_EINVALLFN;
00225                 return (-1);
00226         }
00227         // Generate SURL on file creation
00228         if ( (flags == (O_WRONLY|O_CREAT)) || (flags == (O_RDWR|O_CREAT)) ) {
00229                 // Verify if Destination SE was specified
00230                 if (!se) {
00231                         free(lfn_new);
00232                         errno = SS_EINVALSE;
00233                         return (-1);
00234                 }
00235                 int existence = ss_check_lfn ( lfn_new, vo);
00236                 int errno_save = errno;
00237                 if ( existence < 0 ) {
00238                         free(lfn_new);
00239                         errno = errno_save;
00240                         return (-1);
00241                 } else if ( existence == 1 ) {
00242                         free(lfn_new);
00243                         errno = SS_EEXIST;
00244                         return (-1);
00245                 }
00246                 
00247                 if ( ss_generate_surl(&dest_surl, se, vo, guid) < 0 ) {
00248                         int errno_save = errno;
00249                         free(lfn_new);
00250                         errno = errno_save;     
00251                         return (-1);    
00252                 }
00253         } 
00254         else if ( ss_get_surl(lfn_new,&dest_surl,vo,se,0) < 0 ) { // Get the replica SURL
00255                         // No replica found or an error occured
00256                         int errno_save = errno;
00257                         free(lfn_new);
00258                         errno = errno_save;
00259                         return (-1);
00260         }
00261 
00262     // Open remote file
00263     if ((fd = gfal_open (dest_surl, flags, mode)) < 0) {
00264                 int errno_save = errno;
00265                 free(lfn_new); free(dest_surl);
00266                 errno = errno_save;
00267                 return (-1);
00268         } else if ((ss = alloc_ss_state(fd)) == NULL) { // Alloc mem space for struct
00269                 int errno_save = errno;
00270                 free(lfn_new); free(dest_surl);
00271                 errno = errno_save;
00272                 return (-1);    
00273         } else {
00274                 ss->fd = fd; // Save file descriptor
00275         }
00276         
00277         if ( (flags == (O_WRONLY|O_CREAT)) || (flags == (O_RDWR|O_CREAT)) ) {
00278                 // Register file into catalog
00279                 if (lcg_rf(dest_surl, guid, lfn_new, vo, conf_file, insecure, verbose, actual_gid) < 0 ) { 
00280                         int errno_save = errno;
00281                         gfal_close(fd);
00282                         // Delete orphaned file from storage element
00283                         int aflag=0;
00284                         lcg_delt (dest_surl, aflag, se, vo, conf_file, insecure, verbose, 0);
00285                         free(lfn_new); free(dest_surl);
00286                         errno = errno_save;
00287                         return (-1);
00288                 }
00289         }
00290         
00291         // New file creation -> create new encryption key
00292         if ( (flags == (O_WRONLY|O_CREAT)) || (flags == (O_RDWR|O_CREAT)) ) {
00293                 /*********************  GENERATE KEY AND IV  ***************************/
00294 
00295                 if ( ss_rand (HEX_KEYSIZE, hex_key) < 0 ) {
00296                         return (-1);
00297                 }
00298                 if ( ss_rand (HEX_IVSIZE, hex_iv ) < 0 ) {
00299                         return (-1);
00300                 }
00301                 
00302                 //SAVE KEY AND IV TO KEYSTORE
00303                 if ( ss_send_key (lfn_new, hex_key, hex_iv) < 0 ) {
00304                         int errno_save = errno;
00305                         gfal_close(fd);
00306                         // Delete orphaned file from storage element
00307                         int aflag=0;
00308                         lcg_delt (dest_surl, aflag, se, vo, conf_file, insecure, verbose, 0);
00309                         free(lfn_new); free(dest_surl);
00310                         errno = errno_save;
00311                         return (-1);
00312                 }
00313 
00314                 free(lfn_new); 
00315         } 
00316         // To read or write file that exist, read old encrytion key
00317         else if ( (flags == O_WRONLY) || (flags == O_RDONLY) || (flags == O_RDWR) ) {
00318                 
00319                 if ( ss_get_key (lfn_new, hex_key, hex_iv) < 0 ) {
00320                         int errno_save = errno;
00321                         free(lfn_new); free(dest_surl);
00322                         errno = errno_save;
00323                         return (-1);
00324                 }
00325                 free(lfn_new);
00326         }
00327         
00328         // Set encrypt key
00329         if ( AES_set_encrypt_key(hex_key, 256, &ss->ctx) < 0 ) {
00330                 free(dest_surl); 
00331                 errno = SS_EENCINIT;
00332                 return (-1);
00333         }
00334         // Clear KEY
00335         memset(hex_key, 0, HEX_KEYSIZE);
00336         // Set Initialization vector to ss struct
00337         memcpy(ss->hex_iv, hex_iv, HEX_IVSIZE);
00338         memcpy(ss->ivec, hex_iv, HEX_IVSIZE);
00339         // Clear IV
00340         memset(hex_iv, 0, HEX_IVSIZE);
00341         // Initialize ecount_buf and num for aes_ctr encryption/decryption
00342         memset(ss->ecount_buf, 0, AES_BLOCK_SIZE);
00343         // Initialize num for AES encryption
00344         ss->num = 0;
00345         free(dest_surl);
00346         return fd;
00347 }
00348 
00349 /******************************************************************************
00350  * Open remote file on specified SE
00351  *
00352  * 
00353  ******************************************************************************/
00354 
00355 int securestorage_open_se (char *lfn, int flags, mode_t mode, char *se) {
00356         
00357         int fd;
00358         char *guid=NULL;
00359         char *vo;
00360         
00361         if (lfn == NULL) {
00362                 errno = SS_EINVALLFN;
00363                 return (-1);
00364         }
00365         // Get default VO from Environment Variable
00366         vo = getenv(VO);
00367         if (!vo) {
00368                 errno = SS_EINVALVO;
00369                 return (-1);
00370         }
00371         // Input parameters filter
00372         if (!se) {
00373                 errno = SS_EINVALSE;
00374                 return (-1);
00375         }
00376         // Call open_extended with specified SE and default VO
00377         if ((fd = securestorage_open_extended(lfn,flags,mode,vo,guid,se)) < 0 ){
00378                 return (-1);
00379         }
00380         return fd;
00381 }
00382 
00383 
00384 
00385 
00386 /******************************************************************************
00387  * Open remote file on default SE
00388  *
00389  * 
00390  ******************************************************************************/
00391 
00392 int securestorage_open( char *lfn, int flags, mode_t mode ) {
00393         
00394         int fd, i;
00395         char *guid=NULL;
00396         char *storageelementdest, *vo, *se;
00397         
00398         if (lfn == NULL) {
00399                 errno = SS_EINVALLFN;
00400                 return (-1);
00401         }
00402         // Get default VO from Environment Variable
00403         vo = getenv(VO);
00404         if (!vo) {
00405                 errno = SS_EINVALVO;
00406                 return (-1);
00407         }
00408         // Get default SE from Environment Variable
00409         char oo[strlen(vo)+1];
00410         strcpy(oo,vo);
00411         for (i=0; oo[i]!=0; i++)
00412                 oo[i] = toupper(oo[i]);
00413         storageelementdest = calloc(1, (strlen(oo)+strlen("VO_%s_DEFAULT_SE")+1));
00414         sprintf(storageelementdest,"VO_%s_DEFAULT_SE",oo);
00415         se = getenv(storageelementdest);
00416         if (!se) {
00417                 free(storageelementdest);
00418                 errno = SS_EINVALSE;
00419                 return (-1);
00420         }
00421         if ( (fd = securestorage_open_extended(lfn, flags, mode, vo, guid, se) ) < 0 ) {
00422                 int errno_save = errno;
00423                 free(storageelementdest);
00424                 errno = errno_save;
00425                 return (-1);
00426         }
00427         free(storageelementdest);
00428 
00429         return fd;
00430 }
00431 
00432 
00433 
00434 /******************************************************************************
00435  * Close remote file
00436  *
00437  * 
00438  ******************************************************************************/
00439 
00440 int securestorage_close (int fd) {
00441         
00442         // Variable definition
00443         struct ss_state *ss;
00444         if ( (ss=find_ss_state(fd)) == NULL ) {
00445                 return (-1);
00446         }
00447         if (gfal_close(fd) < 0) {
00448                 int errno_save = errno;
00449                 free_ss_state(fd);
00450                 errno = errno_save;
00451                 return (-1);
00452         }
00453         free_ss_state(fd);
00454         
00455         return 0;       
00456 }
00457 
00458 
00459 
00460 /******************************************************************************
00461  * Encrypt and Write a file on remote SE
00462  * writing must be finalized with write_final
00463  * 
00464  ******************************************************************************/
00465 
00466 int securestorage_write (int fd, void *buffer, size_t size ) {
00467         
00468         // Variable definition
00469         struct ss_state *ss;
00470         unsigned char *data, *out;
00471         int cod_ex=0;
00472         size_t len = size;
00473         
00474         // Get ss struct
00475         if ( (ss=find_ss_state(fd)) == NULL ) {
00476                 return (-1);
00477         }
00478         data=buffer;
00479         out = calloc(1, size+1);
00480         
00481         //Do encryption
00482         securestorage_AES_ctr(data, out, len, &ss->ctx, ss->ivec, ss->ecount_buf, &(ss->num));
00483         
00484         if ((cod_ex = gfal_write(fd, out, len)) < 0 ) {
00485                 int errno_save = errno;
00486                 free(out);
00487                 errno = errno_save;
00488                 return (-1); 
00489         } else if ( cod_ex != len ) {
00490                 free(out);
00491                 errno = EIO;
00492                 return (-1); 
00493         }
00494         free(out);
00495         
00496         return len;     
00497 }
00498 
00499 
00500 /******************************************************************************
00501  * Read and decrypt a file from remote SE
00502  * read must be finalized with read_final
00503  * 
00504  ******************************************************************************/
00505 
00506 int securestorage_read ( int fd, void *buffer, size_t size ) {
00507         
00508         // Variable definition
00509         struct ss_state *ss;
00510         unsigned char *data;
00511         unsigned char *in = calloc (1, size+1);
00512         size_t len = 0;
00513         data=buffer;
00514         
00515         if ( (ss=find_ss_state(fd)) == NULL ) {
00516                 int errno_save = errno;
00517                 free(in);
00518                 errno = errno_save;
00519                 return (-1);
00520         }
00521         
00522         // Read source file
00523         if ((len = gfal_read (fd, in, size)) != size) {
00524                 if (len < 0) {
00525                         int errno_save = errno;
00526                         free(in);
00527                         errno = errno_save;
00528                         return (-1);
00529                 }
00530         }
00531         
00532         //Do encryption
00533         securestorage_AES_ctr(in, data, len, &ss->ctx, ss->ivec, ss->ecount_buf, &(ss->num));
00534         
00535         free(in);
00536         
00537         return len;
00538 }
00539 
00540 
00541 /******************************************************************************
00542  * Seek
00543  *
00544  * 
00545  ******************************************************************************/
00546 off_t securestorage_lseek (int fd, off_t offset, int whence) {
00547         
00548         // Variable definition
00549         struct ss_state *ss;
00550         off_t curr_position, old_position, file_size;
00551         int n, old_block_count, curr_block_count, shift, write_bytes;
00552         unsigned char *buffer;
00553         
00554         if ( (ss=find_ss_state(fd)) == NULL ) {
00555                 return (-1);
00556         }
00557         
00558         // Verify if whence was specified correctly
00559         if ( whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END ) {
00560                 errno = SS_EWHENCE;
00561                 return (-1);
00562         } else if ( whence == SEEK_SET && offset < 0 ) {
00563                 errno = SS_ESPIPE;
00564                 return (-1);
00565         } 
00566         
00567         if ( whence == SEEK_END && offset > 0 ) { // Add offset to current file_size
00568                 if ( (curr_position = securestorage_lseek ( fd, 0, SEEK_END)) < 0 ) {
00569                         return (-1);
00570                 }
00571                 buffer = calloc(1, offset);
00572                 write_bytes = 0;
00573                 if ( (write_bytes = securestorage_write( fd, buffer, offset )) < 0 ) {
00574                         int errno_save = errno;
00575                         free(buffer);
00576                         errno = errno_save;
00577                         return (-1);
00578                 }
00579                 curr_position +=  write_bytes;
00580                 free(buffer);
00581                 return curr_position;   
00582         } 
00583         
00584         // Save old position
00585         if ( (old_position = gfal_lseek ( fd, 0, SEEK_CUR)) < 0 ) {
00586                 errno = SS_ESPIPE;
00587                 return (-1);
00588         }
00589 
00590         if ( whence==SEEK_CUR && offset==0 ) {
00591                 return old_position;
00592         } 
00593         
00594         // Workaround to SEEK_END with a negative offset
00595         if ( whence == SEEK_END && offset < 0 ) {
00596                 // Positioning at end of the file
00597                 if ( (curr_position = gfal_lseek ( fd, 0, SEEK_END)) < 0 ) {
00598                         return (-1);
00599                 }
00600                 if ( -offset > curr_position ) {
00601                         errno = SS_EOFFSET;
00602                         return (-1);
00603                 }
00604                 // Moving to negative offset specified using SEEK_CUR ( with SEEK_END it doesn't work )
00605                 if ( (curr_position = gfal_lseek ( fd, offset, SEEK_CUR)) < 0 ) {
00606                         return (-1);
00607                 }
00608         // Verify if offset go out of file from beginning
00609         } else if ( -offset > old_position ) {
00610                 errno = SS_EOFFSET;
00611                 return (-1);
00612         // Normal SEEK offset > 0
00613         } else if ( offset > 0 ) {
00614                 if ( (file_size = securestorage_lseek ( fd, 0, SEEK_END)) < 0 ) {
00615                         return (-1);
00616                 }
00617                 off_t offset_new = (old_position + offset) - file_size;
00618                 
00619                 if ( offset_new == 0 ) {
00620                         return file_size;
00621                 } else if ( offset_new > 0 ) {
00622                         buffer = calloc(1, offset_new);
00623                         write_bytes = 0;
00624                         if ( (write_bytes = securestorage_write( fd, buffer, offset_new )) < 0 ) {
00625                                 int errno_save = errno;
00626                                 free(buffer);
00627                                 errno = errno_save;
00628                                 return (-1);
00629                         }
00630                         file_size +=  write_bytes;
00631                         free(buffer);
00632                         return file_size;
00633                 } else {
00634                         old_position = file_size;
00635                         if ( (curr_position = gfal_lseek ( fd, offset_new, SEEK_CUR)) < 0 ) {
00636                                 return (-1);
00637                         }
00638                 }
00639         // Normal SEEK offset < 0
00640         } else if ( (curr_position = gfal_lseek ( fd, offset, whence)) < 0 ) {
00641                 errno = SS_EOFFSET;
00642                 return (-1);
00643         }
00644         // Calculating local-block position
00645         ss->num = curr_position % AES_BLOCK_SIZE;
00646         //Calculating wide-block position
00647         old_block_count = (int) old_position / AES_BLOCK_SIZE;
00648         curr_block_count = (int) curr_position /AES_BLOCK_SIZE;
00649         //Calculating increase or decrease count for ivec
00650         shift = (( curr_block_count - old_block_count) -1 );
00651         
00652         if ( old_position == 0 ) {
00653                 AES_encrypt(ss->ivec, ss->ecount_buf, &ss->ctx);
00654                 ivec_inc(ss->ivec);
00655         }
00656         
00657         if ( curr_block_count == old_block_count ) {
00658                 if(!ss->num)
00659                         ivec_dec(ss->ivec);
00660         } else {
00661                 if ( curr_block_count > old_block_count ) {
00662                         // Increase ivec
00663                         for (n=shift;n>0;n--)
00664                                 ivec_inc(ss->ivec);
00665                 } else if ( curr_block_count < old_block_count ) {
00666                         // Decrease ivec
00667                         for (n=shift;n<0;n++)
00668                                 ivec_dec(ss->ivec);
00669                 } else if ( curr_block_count == 0 ) {
00670                         // Begin of the file -> initial ivec
00671                         memcpy(ss->ivec, ss->hex_iv, HEX_IVSIZE);
00672                 }
00673                 // Prepare encrypted ecount_buf for read or write functions
00674                 if(ss->num) {
00675                         AES_encrypt(ss->ivec, ss->ecount_buf, &ss->ctx);
00676                         ivec_inc(ss->ivec);
00677                 }
00678         }
00679         
00680         return curr_position;
00681 }
00682 
00683 
00684 /******************************************************************************
00685  * Delete remote file (one replica or all replica) and associated Key from SE
00686  * extended (user could specify vo, conf_file, insecure,verbose and timeout
00687  * 
00688  ******************************************************************************/
00689 
00690 int securestorage_del_extended (char *lfn,int aflag,char *se,char *vo,
00691                                                 char *conf_file,int insecure,int verbose,int timeout) {
00692         
00693         int deletekey=0;
00694         int x;
00695         size_t inv;
00696         char *src_file_new;
00697         // Valid character
00698         const char *accept_host=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.-";
00699         const char *accept_vo=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789-";
00700         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
00701 
00702         if (lfn==NULL) {
00703                 errno = SS_EINVALLFN;
00704                 return (-1);
00705         }
00706         // Verify length of destination lfn
00707         if (strlen (lfn) + 1 > LCG_MAXPATHLEN) {
00708                 errno = SS_ENAMETOOLONG;
00709                 return (-1);
00710         }
00711         if (vo == NULL) {
00712                 vo = getenv(VO);
00713                 if (!vo) {
00714                         errno = SS_EINVALVO;
00715                         return (-1);
00716                 }
00717         }
00718         // Input file must be an LFN
00719         if (strncmp(lfn, "lfn:", 4) != 0) {
00720                 errno = SS_EINVALLFN;
00721                 return (-1);    
00722         }
00723         
00724         if ( aflag ==0 && se == NULL) {
00725                 errno = SS_EINVALSE;
00726                 return (-1);    
00727         }
00728         
00729         // Input parameters filter
00730         inv=0;
00731         inv = strspn(vo, accept_vo);
00732         if (inv != strlen(vo) ) {
00733                 errno = SS_EINVALVO;
00734                 return (-1);
00735         }
00736         inv=0;
00737         inv = strspn(lfn, accept_lfn);
00738         if (inv != strlen(lfn) ) {
00739                 errno = SS_EINVALLFN;
00740                 return (-1);
00741         }
00742         if (se != NULL) {
00743                 inv=0;
00744                 inv = strspn(se, accept_host);
00745                 if (inv != strlen(se) ) {
00746                         errno = SS_EINVALSE;
00747                         return (-1);
00748                 }
00749         }       
00750         // Add LFC_HOME to LFN
00751         if ( ss_get_lfchome(lfn, &src_file_new) < 0 ) {
00752                 int errno_save = errno;
00753                 errno = errno_save;
00754                 return (-1);                    
00755         }
00756         
00757         int existence = ss_check_lfn ( src_file_new, vo);
00758         int errno_save = errno;
00759         if ( existence < 0 ) {
00760                 free(src_file_new);
00761                 errno = errno_save;
00762                 return (-1);
00763         } else if ( existence == 0 ) {
00764                 free(src_file_new);
00765                 errno = SS_ENOENT;
00766                 return (-1);
00767         }
00768         
00769         if (aflag == 0) {
00770         char **pfns;
00771                 if ( lcg_lr(src_file_new, vo, conf_file, insecure, &pfns) < 0) {
00772                         int errno_save = errno;
00773                         free(src_file_new);
00774                         errno = errno_save;
00775                         return (-1);
00776                 }
00777                 // Verify if exist at least one replica
00778                 if (pfns[0] == NULL) {
00779                         free(pfns); free(src_file_new);
00780                         errno = SS_ENOENT;
00781                         return (-1);
00782                 } else if (pfns[1] == NULL) {
00783                         pfns[0]+=6;
00784                         int g = strcspn(se, "\n");
00785                         if (strncmp (pfns[0], se, g) != 0) {
00786                                 pfns[0]-=6;
00787                                 free(pfns[0]); free(pfns); free(src_file_new);
00788                                 errno = SS_ENOREPLICA;
00789                                 return (-1);
00790                         }
00791                         deletekey=1;
00792                         pfns[0]-=6;
00793                 } else {
00794                         int found = 0;
00795                         for (x=0;pfns[x]!=NULL;x++) {
00796                                 pfns[x]+=6;
00797                                 int g = strcspn(se, "\n");
00798                                 if (strncmp (pfns[x], se, g) == 0) {
00799                                         found = 1;
00800                                         pfns[x]-=6;
00801                                         break;
00802                                 }
00803                                 pfns[x]-=6;
00804                         }
00805                         if (!found) {
00806                                 for(x=0;pfns[x]!=NULL;x++) {
00807                                         free(pfns[x]);
00808                                 }
00809                                 free(pfns); free(src_file_new);
00810                                 errno = SS_ENOREPLICA;
00811                                 return (-1);
00812                         }
00813                         
00814                 }               
00815                 
00816         }
00817         if ( aflag == 1 || deletekey == 1) {
00818                 
00819                 // DELETE KEY AND IV FROM KEYSTORE
00820                 if ( ss_delete_key(src_file_new) < 0) {
00821                         int errno_save = errno;
00822                         free(src_file_new);
00823                         errno = errno_save;
00824                         return (-1);
00825                 }       
00826     }
00827     
00828         if (lcg_delt (src_file_new, aflag, se, vo, conf_file, insecure, verbose, timeout) < 0) {
00829                 int errno_save = errno;
00830                 free(src_file_new);
00831                 errno = errno_save;
00832                 return (-1);
00833         }
00834         
00835         free(src_file_new);
00836         
00837         return 0;
00838 }
00839 
00840 
00841 /******************************************************************************
00842  * Delete remote file (one replica or all replica) and associated Key from SE
00843  *
00844  * 
00845  ******************************************************************************/
00846 
00847 int securestorage_del ( char *lfn, int aflag, char *se ) {
00848 
00849         char *vo;
00850         char *storageelementdest;
00851         int i=0;
00852         int insecure=0;
00853         int verbose=0;
00854         int timeout=0;
00855         char *conf_file=NULL;
00856         
00857         vo = getenv(VO);
00858         if (!vo) {
00859                 errno = SS_EINVALVO;
00860                 return (-1);
00861         }
00862         
00863         if (!se){
00864                 // Get default SE from Environment Variable
00865                 char oo[strlen(vo)+1];
00866                 strcpy(oo,vo);
00867                 for (i=0; oo[i]!=0; i++)
00868                         oo[i] = toupper(oo[i]);
00869                 storageelementdest = calloc(1, (strlen(oo)+strlen("VO_%s_DEFAULT_SE")+1));
00870                 sprintf(storageelementdest,"VO_%s_DEFAULT_SE",oo);
00871                 se = getenv(storageelementdest);
00872                 free(storageelementdest);
00873                 if (!se) {
00874                         errno = SS_EINVALSE;
00875                         return (-1);
00876                 }               
00877         }
00878         
00879         if ( securestorage_del_extended(lfn,aflag,se,vo,conf_file,insecure,verbose,timeout) < 0 ){
00880                 return (-1);
00881         }
00882         
00883         return 0;
00884 }
00885 
00886 
00887 /******************************************************************************
00888  * Open directory path specified
00889  *
00890  * 
00891  ******************************************************************************/
00892 
00893 ss_DIR *securestorage_opendir (const char *name) {
00894         
00895         ss_DIR *dp;
00896         const char *accept_host=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.-";
00897         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
00898         size_t inv;
00899         char *name_new;
00900         
00901         if (!name) {
00902                 errno = SS_EINVALLFN;
00903                 return NULL;
00904         }
00905         char *lfc_host;
00906         lfc_host = getenv("LFC_HOST");
00907         if (lfc_host == NULL) {
00908                 errno = SS_EINVAL;
00909                 return NULL;
00910         }
00911         // Input parameters filter
00912         inv=0;
00913         inv = strspn(lfc_host, accept_host);
00914         if (inv != strlen(lfc_host) ) {
00915                 errno = SS_EINVAL;
00916                 return NULL;
00917         }
00918         // Add LFC_HOME to LFN
00919         if ( ss_get_lfchome(name, &name_new) < 0 ) {
00920                 return NULL;
00921         }
00922         inv=0;
00923         inv = strspn(name_new, accept_lfn);
00924         if (inv != strlen(name_new) ) {
00925                 free(name_new);
00926                 errno = SS_EINVALLFN;
00927                 return NULL;
00928         }       
00929         
00930         char *input_lfn_tmp = name_new;
00931         if (strncmp (input_lfn_tmp, "lfn:", 4) == 0) {
00932                         input_lfn_tmp += 4;
00933         }
00934         
00935         if ( (dp = lfc_opendirxg(lfc_host,input_lfn_tmp,NULL)) == NULL ) {
00936                 int errno_save = serrno;
00937                 free(name_new);
00938                 errno = errno_save;
00939                 return NULL;
00940         }
00941         
00942         free(name_new);
00943         return dp;
00944 }
00945 
00946 /******************************************************************************
00947  * List file/directory entry on specified path
00948  *
00949  * 
00950  ******************************************************************************/
00951 
00952 struct dirent *securestorage_readdir (ss_DIR *dp) {
00953         
00954         struct dirent *ep;
00955         
00956         if (!dp) {
00957                 errno = SS_EINVAL;
00958                 return NULL;
00959         }
00960         
00961         if ( (ep = lfc_readdir(dp)) == NULL ) {
00962                 int errno_save = serrno;
00963                 errno = errno_save;
00964                 return NULL;
00965         }
00966         
00967         return ep;
00968 }
00969 
00970 /******************************************************************************
00971  * Close directory 
00972  *
00973  * 
00974  ******************************************************************************/
00975 
00976 int securestorage_closedir (ss_DIR *dp) {
00977         
00978         if (!dp) {
00979                 errno = SS_EINVAL;
00980                 return (-1);
00981         }
00982         
00983         if ( lfc_closedir(dp) < 0 ) {
00984                 int errno_save = serrno;
00985                 errno = errno_save;
00986                 return (-1);
00987         }
00988         
00989         return (0);
00990 }
00991 
00992 
00993 /******************************************************************************
00994  * Make directory 
00995  *
00996  * 
00997  ******************************************************************************/
00998 
00999 int securestorage_mkdir (const char *path, mode_t mode) {
01000         
01001         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
01002         size_t inv;
01003         char *path_new;
01004         
01005         if (!path) {
01006                 errno = SS_EINVALLFN;
01007                 return (-1);
01008         }
01009         if (!mode) {
01010                 errno = SS_EINVAL;
01011                 return (-1);
01012         }
01013         // Add LFC_HOME to LFN
01014         if ( ss_get_lfchome(path, &path_new) < 0 ) {
01015                 return (-1);
01016         }
01017         inv=0;
01018         inv = strspn(path_new, accept_lfn);
01019         if (inv != strlen(path_new) ) {
01020                 free(path_new);
01021                 errno = SS_EINVALLFN;
01022                 return (-1);
01023         }       
01024         
01025         char *input_lfn_tmp = path_new;
01026         if (strncmp (input_lfn_tmp, "lfn:", 4) == 0) {
01027                         input_lfn_tmp += 4;
01028         }
01029         
01030         if ( lfc_mkdir(input_lfn_tmp, mode) < 0 ) {
01031                 int errno_save = serrno;
01032                 free(path_new);
01033                 errno = errno_save;
01034                 return (-1);
01035         }
01036         free(path_new);
01037         return (0);
01038 }
01039 
01040 /******************************************************************************
01041  * Remove directory 
01042  *
01043  * 
01044  ******************************************************************************/
01045 
01046 int securestorage_rmdir (const char *path) {
01047         
01048         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
01049         size_t inv;
01050         char *path_new;
01051         
01052         if (!path) {
01053                 errno = SS_EINVALLFN;
01054                 return (-1);
01055         }
01056         // Add LFC_HOME to LFN
01057         if ( ss_get_lfchome(path, &path_new) < 0 ) {
01058                 return (-1);
01059         }
01060         inv=0;
01061         inv = strspn(path_new, accept_lfn);
01062         if (inv != strlen(path_new) ) {
01063                 free(path_new);
01064                 errno = SS_EINVALLFN;
01065                 return (-1);
01066         }       
01067         
01068         char *input_lfn_tmp = path_new;
01069         if (strncmp (input_lfn_tmp, "lfn:", 4) == 0) {
01070                         input_lfn_tmp += 4;
01071         }
01072         
01073         if ( lfc_rmdir(input_lfn_tmp) < 0 ) {
01074                 int errno_save = serrno;
01075                 free(path_new);
01076                 errno = errno_save;
01077                 return (-1);
01078         }
01079         
01080         free(path_new);
01081         return (0);
01082 }
01083 
01084 
01085 /******************************************************************************
01086  * Get information about a LFC file or directory from LCG File Catalog
01087  *
01088  * 
01089  ******************************************************************************/
01090 
01091 int securestorage_statg (const char *path, const char *guid, 
01092                                                                 struct ss_filestatg *statbuf) {
01093         
01094         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
01095         size_t inv;
01096         char *path_new;
01097         
01098         if (!path || !statbuf) {
01099                 errno = SS_EINVALLFN;
01100                 return (-1);
01101         }
01102         // Add LFC_HOME to LFN
01103         if ( ss_get_lfchome(path, &path_new) < 0 ) {
01104                 return (-1);
01105         }
01106         inv=0;
01107         inv = strspn(path_new, accept_lfn);
01108         if (inv != strlen(path_new) ) {
01109                 free(path_new);
01110                 errno = SS_EINVALLFN;
01111                 return (-1);
01112         }       
01113         
01114         char *input_lfn_tmp = path_new;
01115         if (strncmp (input_lfn_tmp, "lfn:", 4) == 0) {
01116                         input_lfn_tmp += 4;
01117         }
01118         
01119         if ( lfc_statg(input_lfn_tmp, guid, statbuf) < 0 ) {
01120                 int errno_save = serrno;
01121                 free(path_new);
01122                 errno = errno_save;
01123                 return (-1);
01124         }
01125         
01126         free(path_new);
01127         return (0);
01128         
01129 }
01130 

Generated on Wed May 30 09:56:30 2007 for Secure Storage Service by doxygen 1.3.5