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

lcg_scr.c

Go to the documentation of this file.
00001 
00008 /* lcg_scr.c - Secure copy User Interface to Grid
00009  * ====================================================================
00010  * Copyright (c) Giordano Scuderi, Unico SRL.  All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions
00014  * are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer. 
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright
00020  *    notice, this list of conditions and the following disclaimer in
00021  *    the documentation and/or other materials provided with the
00022  *    distribution.
00023  *
00024  * 3. All advertising materials mentioning features or use of this
00025  *    software must display the following acknowledgment:
00026  *    "This product includes software developed by Giordano Scuderi
00027  *    for Unico SRL"
00028  *
00029  * 4. The names "Secure Storage" must not be used to
00030  *    endorse or promote products derived from this software without
00031  *    prior written permission. For written permission, please contact
00032  *    gscuderi@unicosrl.it.
00033  *
00034  * 5. Products derived from this software may not be called "Secure Storage"
00035  *    nor may "Secure Storage" appear in their names without prior written
00036  *    permission of Giordano Scuderi (Unico SRL).
00037  *
00038  * 6. Redistributions of any form whatsoever must retain the following
00039  *    acknowledgment:
00040  *    "This product includes software developed by Giordano Scuderi
00041  *    for Unico SRL"
00042  *
00043  * THIS SOFTWARE IS PROVIDED BY UNICO SRL ``AS IS'' AND ANY
00044  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00045  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00046  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNICO SRL OR
00047  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00048  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00049  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00050  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00051  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00052  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00053  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00054  * OF THE POSSIBILITY OF SUCH DAMAGE.
00055  * ====================================================================
00056  *
00057  * "This product includes software developed by the OpenSSL Project
00058  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
00059  * 
00060  */
00061 
00062 #ifdef __cplusplus
00063 extern "C" {
00064 #endif
00065 
00066 #include <sys/types.h>
00067 #include <sys/stat.h>
00068 #include <errno.h>
00069 #include <stdio.h>
00070 #include <string.h>
00071 #include <stdlib.h>
00072 #include <fcntl.h>
00073 #if defined(_WIN32)
00074 #include <io.h>
00075 #else
00076 #include <unistd.h>
00077 #endif
00078 #include <sys/mman.h>
00079 #include <dlfcn.h>
00080 #include <gfal_api.h>
00081 #include "lcg_util.h"
00082 #include "ss-util.h"
00083 #include "keystore_client.h"
00084 #include "lcg_scr.h"
00085 
00086 #ifdef __cplusplus
00087 } /* closing brace for extern "C" */
00088 #endif           
00089 
00090 extern int errno;
00091 
00092 /*
00093  * LCG_SCR Function 
00094  *
00095  */
00096 int lcg_scr(char *src_file,char *dest_file,char *guid,char *lfn,char *vo,
00097                 char *conf_file,int insecure,int verbose,char *actual_gid) {
00098         
00099         //VARIABLE DEFINITION
00100         unsigned char hex_key[HEX_KEYSIZE+1];
00101         unsigned char hex_iv[HEX_IVSIZE+1];
00102         AES_KEY ectx;
00103         int cod_ex;
00104         unsigned long nread, len;
00105         size_t inv;
00106         int fdgfal=-1;
00107         int ret=-1;
00108         char *dest_surl;
00109         char *lfn_new;
00110         // Valid character
00111         const char *accept_host=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.-";
00112         const char *accept_vo=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789-";
00113         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
00114         
00115         memset(hex_key,'\0',HEX_KEYSIZE+1);
00116         memset(hex_iv,'\0',HEX_IVSIZE+1);
00117         
00118         // Verify if lfn was specified
00119         if (lfn == NULL) {
00120                 errno = SS_EINVALLFN;
00121                 return (-1);    
00122         }
00123         // Verify length of destination lfn
00124         if (strlen(lfn) + 1 > LCG_MAXPATHLEN) {
00125                 errno = SS_EDESTNAMETOOLONG;
00126                 return (-1);
00127         }
00128         // Verify if --vo flag was specified or exist Environment variable LCG_GFAL_VO
00129         if (vo == NULL){
00130                 vo = getenv(VO);
00131                 if (!vo) {
00132                         errno = SS_EINVALVO;
00133                         return (-1);
00134                 }
00135         }
00136         //Verify if Destination SE was specified
00137         if (dest_file == NULL){
00138                 char *storageelementdest;
00139                 sprintf(storageelementdest, "VO_%s_DEFAULT_SE",vo);
00140                 dest_file = getenv(storageelementdest);
00141                 if (!dest_file) {
00142                         errno = SS_EINVALSE;
00143                         return (-1);
00144                 }
00145         }
00146         
00147         if (guid!=NULL) {
00148                 if (strlen(guid)!=36 ) {
00149                         errno = SS_EINVALGUID;
00150                         return (-1);
00151                 }
00152         }
00153         
00154         // Input parameters filter
00155         inv=0;
00156         inv = strspn(dest_file, accept_host);
00157         if (inv != strlen(dest_file) ) {
00158                 errno = SS_EINVALSE;
00159                 return (-1);
00160         }
00161         inv=0;
00162         inv = strspn(vo, accept_vo);
00163         if (inv != strlen(vo) ) {
00164                 errno = SS_EINVALVO;
00165                 return (-1);
00166         }       
00167         inv=0;
00168         inv = strspn(lfn, accept_lfn);
00169         if (inv != strlen(lfn) ) {
00170                 errno = SS_EINVALLFN;
00171                 return (-1);
00172         }
00173         
00174         // Enable memory lock starting at memory pointed by hex_key
00175         if (lock_memory((char*) hex_key,900000) < 0 ) {
00176                 int errno_save = errno;
00177                 fprintf(stderr, "%s\n", securestorage_error(errno_save));
00178                 fprintf(stderr,"WARNING - Using unsecure memory!\n");
00179         }
00180         
00181         // Add LFC_HOME to LFN
00182         if ( ss_get_lfchome(lfn, &lfn_new) < 0 ) {
00183                 return (-1);                    
00184         }
00185         
00186         int existence = ss_check_lfn ( lfn_new, vo);
00187         int errno_save = errno;
00188         if ( existence < 0 ) {
00189                 free(lfn_new);
00190                 errno = errno_save;
00191                 return (-1);
00192         } else if ( existence == 1 ) {
00193                 free(lfn_new);
00194                 errno = SS_EEXIST;
00195                 return (-1);
00196         }
00197         
00198         // Generate random KEY and IV
00199         if ( ss_rand (HEX_KEYSIZE, hex_key) < 0 ) {
00200                 int errno_save = errno;
00201                 free(lfn_new);
00202                 errno = errno_save;
00203                 return (-1);
00204         }
00205         if ( ss_rand (HEX_IVSIZE, hex_iv ) < 0 ) {
00206                 int errno_save = errno;
00207                 free(lfn_new);
00208                 errno = errno_save;
00209                 return (-1);
00210         }
00211         // Set encrypt key
00212         if ( AES_set_encrypt_key(hex_key, 256, &ectx) < 0 ) {
00213                 free(lfn_new);
00214                 errno = SS_EENCINIT;
00215                 return (-1);
00216         }
00217         if (verbose) {
00218                 printf("AES Cipher initialized.\n");
00219         }
00220         
00221         //SAVE KEY AND IV TO KEYSTORE
00222         if ( ss_send_key (lfn_new, hex_key, hex_iv) < 0 ) {
00223                 int errno_save = errno;
00224                 free(lfn_new);
00225                 errno = errno_save;
00226                 return (-1);
00227         }
00228         
00229         // Open source file and verify if it exist
00230         char *src_file_path;
00231         if (strncmp (src_file, "file:", 5) == 0) {
00232                         src_file_path = src_file;
00233                         src_file_path+=5;
00234                         while ( strncmp (src_file_path, "/", 1) == 0 ) {
00235                                 src_file_path+=1;
00236                         }
00237                         src_file_path-=1;
00238         } else {
00239                 src_file_path = src_file;
00240         }
00241         int fd = open(src_file_path, O_RDONLY);
00242         if (fd < 0) {
00243                 int errno_save = errno;
00244                 // DELETE KEY AND IV FROM KEYSTORE
00245                 if ( ss_delete_key(lfn_new) < 0 ) {
00246                         int errno_tmp = errno;
00247                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00248                 }
00249                 free(lfn_new);
00250                 errno = errno_save;
00251                 return (-1);
00252         }
00253         // Open source file and verify file size
00254         long long size, bytesread = 0;
00255         struct stat st_buf;
00256         int fdstat = fstat(fd, &st_buf);
00257         if (fdstat <0) {
00258                 int errno_save = errno;
00259                 // DELETE KEY AND IV FROM KEYSTORE
00260                 if ( ss_delete_key(lfn_new) < 0 ) {
00261                         int errno_tmp = errno;
00262                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00263                 }
00264                 free(lfn_new);
00265                 errno = errno_save;
00266                 return (-1);
00267         }
00268         size = st_buf.st_size;
00269         close(fd);
00270 
00271         // Reopen source file and verify if it exist
00272         FILE *fdin = fopen(src_file_path, "rb");
00273         if (fdin == NULL) {
00274                 int errno_save = errno;
00275                 // DELETE KEY AND IV FROM KEYSTORE
00276                 if ( ss_delete_key(lfn_new) < 0 ) {
00277                         int errno_tmp = errno;
00278                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00279                 }
00280                 free(lfn_new);
00281                 errno = errno_save;
00282                 return (-1);
00283         }
00284         
00285         // Generate SURL
00286         if ( ss_generate_surl( &dest_surl, dest_file, vo, guid) < 0 ) {
00287                 int errno_save = errno;
00288                 // DELETE KEY AND IV FROM KEYSTORE
00289                 if ( ss_delete_key(lfn_new) < 0 ) {
00290                         int errno_tmp = errno;
00291                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00292                 }
00293                 fclose(fdin);
00294                 free(lfn_new);
00295                 errno = errno_save;
00296                 return (-1);    
00297         }
00298         
00299         // Try opening remote file in write mode
00300         fdgfal = gfal_open(dest_surl, O_WRONLY|O_CREAT, 0644);
00301         if (fdgfal < 0) {
00302                 int errno_save = errno;
00303                 // DELETE KEY AND IV FROM KEYSTORE
00304                 if ( ss_delete_key(lfn_new) < 0 ) {
00305                         int errno_tmp = errno;
00306                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00307                 }
00308                 fclose(fdin);
00309                 free(lfn_new); free(dest_surl);
00310                 errno = errno_save;
00311                 return (-1);
00312         } else if (verbose) {
00313                         fprintf(stdout, "File %s successfully opened\n", dest_surl); 
00314         }
00315         
00316         // Read and Encrypt Data
00317         unsigned char ecount_buf[AES_BLOCK_SIZE];
00318         bzero (ecount_buf, AES_BLOCK_SIZE);
00319         unsigned int *num = calloc (1, sizeof(int));
00320         unsigned char *ivec = (unsigned char *)calloc(1, AES_BLOCK_SIZE);
00321         memcpy(ivec, hex_iv, AES_BLOCK_SIZE);
00322         
00323         while (bytesread < size) {
00324                 // Clean variables
00325                 unsigned char *buffer = (unsigned char *)calloc(1, TRANSFERBLOCKSIZE);
00326                 unsigned char *out = (unsigned char *)calloc(1, TRANSFERBLOCKSIZE);
00327                 nread=0;
00328                 // Read source file
00329                 nread =  fread(buffer, 1, TRANSFERBLOCKSIZE, fdin);
00330                 // Delete KEY and IV and clean environment if an error occured
00331                 if (nread < 0) {
00332                         int errno_save = errno;
00333                         // DELETE KEY AND IV FROM KEYSTORE
00334                         if ( ss_delete_key(lfn_new) < 0 ) {
00335                                 int errno_tmp = errno;
00336                                 fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00337                         }
00338                         fclose(fdin);
00339                         gfal_close(fdgfal);
00340                         free(buffer); free(out); free(ivec); free(lfn_new); free(num); free(dest_surl);
00341                         errno = errno_save;
00342                         return (-1);
00343                 } else if (verbose) {
00344                         fprintf(stdout, "Read %ld byte\n",nread);
00345                 }
00346                 len=nread;
00347                 //Call Encrypt function
00348                 securestorage_AES_ctr(buffer, out, len, &ectx, ivec, ecount_buf, num);
00349                 
00350                 memset(buffer, 0, TRANSFERBLOCKSIZE);
00351                 free(buffer);
00352                 // If verbose convert file size in Mbytes and print it to stdout
00353                 if(verbose) {
00354                         float file_size = len;
00355                         if (file_size > 100000) {
00356                                 fprintf(stdout, "Writing: %10.2lf Mbytes to grid:",file_size/1048576);
00357                         }
00358                         else {
00359                                 fprintf(stdout, "Writing: %10.2lf Kbytes to grid:",file_size/1024);
00360                         }
00361                 }
00362                 /* attempt to write remote file */
00363                 if ((cod_ex = gfal_write(fdgfal, out, nread)) < 0 ) {
00364                         int errno_save = errno;
00365                         // DELETE KEY AND IV FROM KEYSTORE
00366                         if ( ss_delete_key(lfn_new) < 0 ) {
00367                                 int errno_tmp = errno;
00368                                 fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00369                         }
00370                         fclose(fdin); free(out); free(ivec); free(num);
00371                         gfal_close(fdgfal);
00372                         free(lfn_new); free(dest_surl);
00373                         errno = errno_save;
00374                         return (-1); 
00375                 } else if (verbose) {
00376                 // If verbose print to stdout Success for incomplete write of block or Complete for last block
00377                         if(bytesread+nread < size) {
00378                                 fprintf (stdout, "  Success\n");
00379                         } else {
00380                                 fprintf (stdout, "  Complete.\n");
00381                         }
00382                 }
00383                 bytesread += nread;
00384                 memset(out, 0, nread);
00385                 free(out);
00386         } // End While
00387         
00388         // -------------------------------------------------------------------------
00389         // Clean
00390         memset(hex_key, 0, HEX_KEYSIZE);
00391         memset(hex_iv, 0, HEX_IVSIZE);
00392         memset(ivec, 0, HEX_IVSIZE);
00393         memset(ectx.rd_key,0,60);
00394         free(ivec); free(num);
00395         
00396         // Unlock memory
00397         if (munlockall() < 0 ) {
00398                 int errno_save = errno;
00399                 fprintf(stderr, "%s\n", securestorage_error(errno_save));
00400         }
00401         
00402         fclose(fdin);
00403         // Close remote file
00404         if (gfal_close(fdgfal) < 0) {
00405                 int errno_save = errno;
00406                 // Delete orphaned file from storage element
00407                 int aflag=0;
00408                 lcg_delt (dest_surl, aflag, dest_file, vo, conf_file, insecure, verbose, 0);
00409                 // DELETE KEY AND IV FROM KEYSTORE
00410                 if ( ss_delete_key(lfn_new) < 0 ) {
00411                         int errno_tmp = errno;
00412                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00413                 }
00414                 free(lfn_new); free(dest_surl);
00415                 errno = errno_save;
00416                 return (-1);
00417         }
00418         // Register file into catalog
00419         ret = lcg_rf (dest_surl, guid, lfn_new, vo, conf_file, insecure, verbose, actual_gid);
00420         if (ret < 0 ) {
00421                 int errno_save = errno;
00422                 // Delete orphaned file from storage element
00423                 int aflag=0;
00424                 lcg_delt (dest_surl, aflag, dest_file, vo, conf_file, insecure, verbose, 0);
00425                 // DELETE KEY AND IV FROM KEYSTORE
00426                 if ( ss_delete_key(lfn_new) < 0 ) {
00427                         int errno_tmp = errno;
00428                         fprintf(stderr, "%s\n", securestorage_error(errno_tmp));
00429                 }
00430                 free(lfn_new); free(dest_surl);
00431                 errno = errno_save;
00432                 return (-1);
00433         } // End register file into catalog
00434         
00435         // Print GUID
00436         if (!actual_gid)
00437                 fprintf (stdout, "guid:%s\n", actual_gid);
00438         free(lfn_new); free(dest_surl);
00439         return 0;
00440 }

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