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

lcg_scp.c

Go to the documentation of this file.
00001 
00008 /* lcg_scp.c - Secure copy from Grid to User Interface
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 <getopt.h>
00072 #include <stdlib.h>
00073 #include <fcntl.h>
00074 #if defined(_WIN32)
00075 #include <io.h>
00076 #else
00077 #include <unistd.h>
00078 #endif
00079 #include <sys/mman.h>
00080 #include <dlfcn.h>
00081 //require e2fsprogs-devel
00082 #include <uuid/uuid.h>
00083 //end require
00084 #include <gfal_api.h>
00085 #include "lcg_util.h"
00086 #include "lcg_scp.h"
00087 #include "ss-util.h"
00088 #include "keystore_client.h"
00089 
00090 #ifdef __cplusplus
00091 } /* closing brace for extern "C" */
00092 #endif
00093 
00094 extern int errno;
00095  
00096 /* LCG_SCP */
00097 int lcg_scp(char *src_file,char *dest_file,char *vo,char *conf_file,
00098                                 int insecure,int verbose) {
00099         
00100         // Valid character
00101         const char *accept_vo=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789-";
00102         const char *accept_lfn=" abcdefghilmnopqrstuvzwyxkjABCDEFGHILMNOPQRSTUVZWYXKJ0123456789.:_/-";
00103         char *srm_source;
00104         char *dest_surl;
00105         char *src_file_new;
00106         unsigned char hex_key[HEX_KEYSIZE+1];
00107         unsigned char hex_iv[HEX_IVSIZE+1];
00108         int nread, fdgfal, cod_ex, len;
00109         size_t inv;
00110         
00111         // Verify if --vo flag was specified or exist Environment variable LCG_GFAL_VO
00112         if (vo == NULL){
00113                 vo = getenv(VO);
00114                 if (!vo) {
00115                         errno = SS_EINVALVO;
00116                         return (-1);
00117                 }
00118         }
00119         
00120         if (src_file==NULL) {
00121                 errno = SS_EINVALLFN;
00122                 return (-1);
00123         }
00124         if(dest_file==NULL) {
00125                 errno = SS_EINVALDEST;
00126                 return (-1);
00127         }
00128         // Verify length of destination lfn
00129         if (strlen (src_file) + 1 > LCG_MAXPATHLEN) {
00130                 errno = SS_ESOURCENAMETOOLONG;
00131                 return (-1);
00132         }
00133         // Input parameters filter
00134         inv=0;
00135         inv = strspn(vo, accept_vo);
00136         if (inv != strlen(vo) ) {
00137                 errno = SS_EINVALVO;
00138                 return (-1);
00139         }       
00140         inv=0;
00141         inv = strspn(src_file, accept_lfn);
00142         if (inv != strlen(src_file) ) {
00143                 errno = SS_EINVALLFN;
00144                 return (-1);
00145         }       
00146         
00147         // Enable memory lock for 900 Kb starting at memory pointed by hex_key
00148         if (lock_memory(hex_key,900000) < 0 ) {
00149                 int errno_save = errno;
00150                 fprintf(stderr, "%s\n", securestorage_error(errno_save));
00151                 fprintf(stderr,"WARNING - Using unsecure memory!\n");
00152         }
00153         
00154         // Add LFC_HOME to LFN
00155         if ( ss_get_lfchome(src_file, &src_file_new) < 0 ) {
00156                 int errno_save = errno;
00157                 errno = errno_save;
00158                 return (-1);
00159         }
00160         
00161         if ( ss_get_key (src_file_new, hex_key, hex_iv) < 0 ) {
00162                 int errno_save = errno;
00163                 free(src_file_new);
00164                 errno = errno_save;
00165                 return (-1);
00166         }
00167         // If verbose print Key
00168         if (verbose) {
00169                 fprintf(stdout, "Key: %s\n", hex_key);
00170                 fprintf(stdout, "IV : %s\n", hex_iv);
00171         }
00172         
00173         /* 
00174         *    AES Decrypt initialize
00175         */
00176         AES_KEY dctx;
00177         if ( AES_set_encrypt_key(hex_key, 256, &dctx) < 0 ) {
00178                 free(src_file_new);
00179                 errno = SS_EENCINIT;
00180                 return (-1);
00181         }
00182         if (verbose) {
00183                 printf("AES Cipher initialized.\n");
00184         }
00185         
00186         // Get the replica SURL
00187         if ( ss_get_surl(src_file_new,&dest_surl,vo,NULL,insecure) < 0 ) {
00188                 int errno_save = errno;
00189                 free(src_file_new);
00190                 errno = errno_save;
00191                 return (-1);
00192         }
00193         srm_source=dest_surl;
00194         // GFAL
00195         // Open source file
00196         if ((fdgfal = gfal_open(srm_source, O_RDONLY, 0644)) < 0) {
00197                 int errno_save = errno;
00198                 free(src_file_new);
00199                 errno = errno_save;
00200                 return (-1);
00201         }
00202         if (verbose){
00203         printf ("open successful, fdgfal = %d\n", fdgfal);
00204         }
00205     long long size;
00206         long long bytesread = 0;
00207         struct stat st_buf;
00208         // Verify file size
00209         cod_ex = gfal_stat(srm_source, &st_buf);
00210         if ( cod_ex < 0) {
00211                 int errno_save = errno;
00212         gfal_close(fdgfal);
00213                 free(src_file_new);
00214                 errno = errno_save;
00215         return (-1);    
00216         }
00217         size = st_buf.st_size;
00218         // END GFAL
00219         
00220         // If verbose print file size
00221         if (verbose) {
00222                 fprintf(stdout, "Source file size is: %lld\n", size);
00223         }
00224         // Write of output file
00225         char *dest_f;
00226         if (strncmp (dest_file, "file:", 5) == 0) {
00227                         dest_f=dest_file;
00228                         dest_f+=5;
00229                         while ( strncmp (dest_f, "/", 1) == 0 ) {
00230                                 dest_f+=1;
00231                         }
00232                         dest_f-=1;
00233         } else {
00234                 dest_f=dest_file;       
00235         }
00236         FILE *fdout;
00237         if ((fdout = fopen(dest_f, "rb"))) {
00238                 gfal_close(fdgfal);
00239                 free(src_file_new);
00240                 errno = SS_EEXIST;
00241                 return (-1);
00242         }
00243         if ( (fdout = fopen(dest_f, "wb")) < 0 ) {
00244                 gfal_close(fdgfal);
00245                 free(src_file_new);
00246                 errno = SS_EACCES;
00247                 return (-1);
00248         }
00249         
00250         // Read and Encrypt Data
00251         unsigned char ecount_buf[AES_BLOCK_SIZE];
00252         bzero (ecount_buf, AES_BLOCK_SIZE);
00253         unsigned int *num = calloc (1, sizeof(int));
00254         
00255         unsigned char *ivec = (unsigned char *)calloc(1, AES_BLOCK_SIZE);
00256         memcpy(ivec, hex_iv, AES_BLOCK_SIZE);
00257         while (bytesread < size) {
00258                 nread=0;
00259                 unsigned char *buffer = (unsigned char *)calloc(1, TRANSFERBLOCKSIZE);
00260                 unsigned char *out = (unsigned char *)calloc(1, TRANSFERBLOCKSIZE);
00261                 // If verbose convert file size in Mbytes and print it to stdout
00262                 if (verbose) {
00263                         float file_size;
00264                         if (size >1048576){
00265                                 long long remain = size - bytesread;
00266                                 if (remain > TRANSFERBLOCKSIZE) {
00267                                         file_size = TRANSFERBLOCKSIZE;
00268                                         fprintf(stdout, "Reading:         %10.2lf Mbytes from grid:",file_size/1048576  );
00269                                 } else {
00270                                         file_size = remain;
00271                                         fprintf(stdout, "Reading:         %10.2lf Mbytes from grid:",file_size/1048576  );
00272                                 }
00273                         }
00274                         else {
00275                                 file_size = size;
00276                                 fprintf(stdout, "Reading:         %10.2lf Kbytes from grid:",file_size/1024  ); 
00277                         }
00278                 }
00279                 // Read source file
00280                 // GFAL
00281                 if ((nread = gfal_read (fdgfal, buffer, TRANSFERBLOCKSIZE)) != TRANSFERBLOCKSIZE) {
00282                         if (nread < 0) {
00283                                 int errno_save = errno;
00284                 fclose(fdout);
00285                                 gfal_close(fdgfal);
00286                                 free(buffer); free(out); free(ivec); free(src_file_new); free(num);
00287                                 errno = errno_save;
00288                                 return (-1);
00289                         }
00290                 } // END GFAL
00291                 // If verbose print to stdout Success for incomplete read of block or Complete for last block
00292                 if (verbose) {
00293                         if(bytesread+nread < size) {
00294                                 fprintf (stdout, "  Success\n");        
00295                         } else {
00296                                 fprintf (stdout, "  Complete.\n");
00297                         }
00298                 }
00299                 len = nread;
00300                 //Call decrypt function
00301                 securestorage_AES_ctr(buffer, out, len, &dctx, ivec, ecount_buf, num);
00302                 
00303                 // Clean buffer
00304                 memset(buffer, 0, TRANSFERBLOCKSIZE);
00305                 free(buffer);
00306                 
00307                 if (verbose) {
00308                         fprintf(stdout, "Attempt to write %d bytes\n", len);    
00309                 }
00310                 /* attempt to write it */
00311                 int nwrite = fwrite(out, 1, len, fdout);
00312                 if (nwrite < 0) {
00313                         int errno_save = errno;
00314             fclose(fdout); gfal_close(fdgfal);
00315                         free(out); free(ivec); free(src_file_new); free(num);
00316                         errno = errno_save;
00317                         return (-1);
00318                 }
00319                 // Clean out
00320                 memset(out, 0, len);
00321                 free(out);
00322                 bytesread += nread;
00323         } // End While
00324         
00325         // Close output file
00326         fclose(fdout);
00327         // GFAL
00328         if ((cod_ex = gfal_close (fdgfal)) < 0) {
00329                 int errno_save = errno;
00330         free(ivec); free(src_file_new); free(num);
00331         errno = errno_save;
00332         return (-1);
00333     } // END GFAL
00334     if (verbose) {
00335         printf ("Source file close successful\n");
00336     }
00337     // Clear variables
00338     memset(hex_key, 0, HEX_KEYSIZE);
00339         memset(hex_iv, 0, HEX_IVSIZE);
00340         memset(ivec, 0, HEX_IVSIZE);
00341         memset(dctx.rd_key, 0, 60); 
00342     free(ivec); free(src_file_new); free(num);
00343         
00344     // Unlock memory
00345         if (munlockall() < 0 ) {
00346                 int errno_save = errno;
00347                 fprintf(stderr, "%s\n", securestorage_error(errno_save));
00348         }
00349         
00350         return 0;
00351 }
00352 

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