olestream-unwrap.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005 #include <errno.h>
00006 
00007 #include "logger.h"
00008 #include "pldstr.h"
00009 
00010 #include "bytedecoders.h"
00011 #include "olestream-unwrap.h"
00012 
00013 #define DUW if (oleuw->debug)
00014 
00015 #include "MALLOC.h"
00016 
00017 struct OLE10_header{
00018         unsigned char data[6];
00019         char *attach_name;
00020         unsigned char data2[8];
00021         char *fname_1;
00022         char *fname_2;
00023         size_t attach_size;
00024         size_t attach_size_1;
00025         size_t attach_start_offset;
00026 };
00027 
00028 #ifdef _MSC_VER
00029         #define strdup _strdup
00030 #endif
00031 
00032 /*-----------------------------------------------------------------\
00033  Function Name  : OLEUNWRAP_init
00034  Returns Type   : int
00035         ----Parameter List
00036         1. struct OLEUNWRAP_object *oleuw , 
00037         ------------------
00038  Exit Codes     : 
00039  Side Effects   : 
00040 --------------------------------------------------------------------
00041  Comments:
00042  
00043 --------------------------------------------------------------------
00044  Changes:
00045  
00046 \------------------------------------------------------------------*/
00047 int OLEUNWRAP_init( struct OLEUNWRAP_object *oleuw )
00048 {
00049         oleuw->debug = 0;
00050         oleuw->verbose = 0;
00051         oleuw->filename_report_fn = NULL;
00052 
00053         return OLEUW_OK;
00054 }
00055 
00056 /*-----------------------------------------------------------------\
00057  Function Name  : OLEUNWRAP_set_debug
00058  Returns Type   : int
00059         ----Parameter List
00060         1. struct OLEUNWRAP_object *oleuw, 
00061         2.  int level , 
00062         ------------------
00063  Exit Codes     : 
00064  Side Effects   : 
00065 --------------------------------------------------------------------
00066  Comments:
00067  
00068 --------------------------------------------------------------------
00069  Changes:
00070  
00071 \------------------------------------------------------------------*/
00072 int OLEUNWRAP_set_debug( struct OLEUNWRAP_object *oleuw, int level )
00073 {
00074         oleuw->debug = level;
00075         return OLEUW_OK;
00076 }
00077 
00078 /*-----------------------------------------------------------------\
00079  Function Name  : OLEUNWRAP_set_verbose
00080  Returns Type   : int
00081         ----Parameter List
00082         1. struct OLEUNWRAP_object *oleuw, 
00083         2.  int level , 
00084         ------------------
00085  Exit Codes     : 
00086  Side Effects   : 
00087 --------------------------------------------------------------------
00088  Comments:
00089  
00090 --------------------------------------------------------------------
00091  Changes:
00092  
00093 \------------------------------------------------------------------*/
00094 int OLEUNWRAP_set_verbose( struct OLEUNWRAP_object *oleuw, int level )
00095 {
00096         oleuw->verbose = level;
00097         return OLEUW_OK;
00098 }
00099 
00100 /*-----------------------------------------------------------------\
00101  Function Name  : OLEUNWRAP_set_save_unknown_streams
00102  Returns Type   : int
00103         ----Parameter List
00104         1. struct OLEUNWRAP_object *oleuw, 
00105         2.  int level , 
00106         ------------------
00107  Exit Codes     : 
00108  Side Effects   : 
00109 --------------------------------------------------------------------
00110  Comments:
00111  
00112 --------------------------------------------------------------------
00113  Changes:
00114  
00115 \------------------------------------------------------------------*/
00116 int OLEUNWRAP_set_save_unknown_streams( struct OLEUNWRAP_object *oleuw, int level )
00117 {
00118         oleuw->save_unknown_streams = level;
00119         return OLEUW_OK;
00120 }
00121 
00122 
00123 /*-----------------------------------------------------------------\
00124  Function Name  : OLEUNWRAP_save_stream
00125  Returns Type   : int
00126         ----Parameter List
00127         1. char *fname, 
00128         2.  char *stream, 
00129         3.  size_t bytes , 
00130         ------------------
00131  Exit Codes     : 
00132  Side Effects   : 
00133 --------------------------------------------------------------------
00134  Comments:
00135  
00136 --------------------------------------------------------------------
00137  Changes:
00138  
00139 \------------------------------------------------------------------*/
00140 int OLEUNWRAP_save_stream( struct OLEUNWRAP_object *oleuw, char *fname, char *decode_path, char *stream, size_t bytes )
00141 {
00142         char *full_name;
00143         FILE *f;
00144         int result = 0;
00145 
00146         DUW LOGGER_log("%s:%d:OLEUNWRAP_save_stream:DEBUG: fname=%s, decodepath=%s, size=%ld"
00147                         ,FL
00148                         ,fname
00149                         ,decode_path
00150                         ,bytes
00151                         );
00152 
00153         full_name = PLD_dprintf("%s/%s", decode_path, fname );
00154         if (full_name == NULL)
00155         {
00156                 LOGGER_log("%s:%d:OLEUNWRAP_save_stream:ERROR: Unable to create filename string from '%s' and '%s'",FL,fname,decode_path);
00157                 return -1;
00158         }
00159 
00160         f = fopen(full_name,"wb");
00161         if (f != NULL)
00162         {
00163                 size_t write_count;
00164 
00165                 write_count = fwrite( stream, 1, bytes, f );
00166                 if (write_count != bytes)
00167                 {
00168                         LOGGER_log("%s:%d:OLEUNWRAP_save_stream:WARNING: Only wrote %d of %d bytes to file %s\n",FL, write_count, bytes, full_name );
00169                 }
00170 
00171                 fclose(f);
00172 
00173 
00174         } else {
00175                 LOGGER_log("%s:%d:OLEUNWRAP_save_stream:ERROR: Unable to open %s for writing (%s)\n",FL,full_name, strerror(errno));
00176                 result = -1;
00177         }
00178 
00179         if (full_name) FREE(full_name);
00180 
00181         DUW LOGGER_log("%s:%d:OLEUNWRAP_save_stream:DEBUG: Done saving '%s'",FL, fname);
00182 
00183         return result;
00184 }
00185 
00186 /*-----------------------------------------------------------------\
00187  Function Name  : OLEUNWRAP_sanitize_filename
00188  Returns Type   : int
00189         ----Parameter List
00190         1. char *fname , 
00191         ------------------
00192  Exit Codes     : 
00193  Side Effects   : 
00194 --------------------------------------------------------------------
00195  Comments:
00196  
00197 --------------------------------------------------------------------
00198  Changes:
00199  
00200 \------------------------------------------------------------------*/
00201 int OLEUNWRAP_sanitize_filename( char *fname )
00202 {
00203                 while (*fname)
00204                 {
00205                         if( !isalnum((int)*fname) && (*fname != '.') ) *fname='_';
00206                         if( (*fname < ' ')||(*fname > '~') ) *fname='_';
00207                         fname++;
00208                 }
00209                 return 0;
00210 }
00211 
00212 /*-----------------------------------------------------------------\
00213  Function Name  : OLEUNWRAP_decode_attachment
00214  Returns Type   : int
00215         ----Parameter List
00216         1. char *stream , 
00217         ------------------
00218  Exit Codes     : 
00219  Side Effects   : 
00220 --------------------------------------------------------------------
00221  Comments:
00222  
00223 --------------------------------------------------------------------
00224  Changes:
00225  
00226 \------------------------------------------------------------------*/
00227 int OLEUNWRAP_decode_attachment( struct OLEUNWRAP_object *oleuw, char *stream, size_t stream_size, char *decode_path )
00228 {
00229         struct OLE10_header oh;
00230         char *sp = stream;
00231         char *data_start_point = stream;
00232         int result = OLEUW_OK;
00233 
00234         /* Get the data size*/
00235         oh.attach_size_1 = (size_t)get_4byte_value( sp );
00236         sp += 4;
00237 
00238         DUW LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: attachsize = %d, stream length = %d\n", FL, oh.attach_size_1, stream_size );
00239 
00240         oh.attach_start_offset = (stream_size -oh.attach_size_1);
00241         data_start_point = stream +oh.attach_start_offset;
00242 
00243         /*if (oh.attach_start_offset == 4)*/
00244         if (oh.attach_start_offset < 4)
00245         {
00246           /* If we only had the stream byte-lenght in our header*/
00247           /*            then we know we don't have a complex header.*/
00248                 oh.attach_name = PLD_dprintf("unknown-%ld",oh.attach_size_1);
00249                 oh.attach_size = oh.attach_size_1;
00250         } else {
00251 
00252                 DUW LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: Decoding file information header",FL);
00253                 /* Unknown memory segment*/
00254                 memcpy( oh.data, sp, 2 );
00255                 sp += 2;
00256                 
00257                 /* Full attachment string*/
00258                 oh.attach_name = strdup( sp );
00259                 sp = sp + strlen(oh.attach_name) +1;
00260 
00261                 /* Attachment full path*/
00262                 oh.fname_1 = strdup( sp );
00263                 sp += strlen(oh.fname_1) +1;
00264 
00265                 /* Unknown memory segment*/
00266                 memcpy( oh.data2, sp, 8 );
00267                 sp = sp +8;
00268 
00269                 /* Attachment full path*/
00270                 oh.fname_2 = strdup( sp );
00271                 sp += strlen(oh.fname_2) +1;
00272 
00273                 oh.attach_size = (size_t)get_4byte_value( sp );
00274                 sp += 4;
00275 
00276                 if (oh.attach_size > stream_size) oh.attach_size = stream_size;
00277                 
00278                 data_start_point = sp;
00279         } 
00280 
00281         DUW LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: Attachment %s:%s:%s size = %d\n",FL, oh.attach_name, oh.fname_1, oh.fname_2, oh.attach_size );
00282 
00283 
00286         OLEUNWRAP_sanitize_filename(oh.attach_name);
00287         OLEUNWRAP_sanitize_filename(oh.fname_1);
00288         OLEUNWRAP_sanitize_filename(oh.fname_2);
00289 
00290         result = OLEUNWRAP_save_stream( oleuw, oh.attach_name, decode_path, data_start_point, oh.attach_size );
00291         if (result == OLEUW_OK)
00292         {
00293                 if (oleuw->debug > 0) LOGGER_log("%s:%d:OLEUNWRAP_decode_attachment:DEBUG: Calling reporter for the filename",FL);
00294                 if ((oleuw->verbose > 0)&&(oleuw->filename_report_fn != NULL))
00295                 {
00296                         oleuw->filename_report_fn(oh.attach_name);
00297                 }
00298                 /* Do call back to reporting function*/
00299         }
00300 
00301         /* Clean up our previously allocated data*/
00302         if (oh.fname_1 != NULL) FREE(oh.fname_1);
00303         if (oh.attach_name != NULL) FREE(oh.attach_name);
00304         if (oh.fname_2 != NULL) FREE(oh.fname_2);
00305         
00306         return OLEUW_OK;
00307 }
00308 
00309 /*-----------------------------------------------------------------\
00310  Function Name  : OLEUNWRAP_decodestream
00311  Returns Type   : int
00312         ----Parameter List
00313         1. char *element_string, 
00314         2.  char *stream , 
00315         ------------------
00316  Exit Codes     : 
00317  Side Effects   : 
00318 --------------------------------------------------------------------
00319  Comments:
00320  
00321 --------------------------------------------------------------------
00322  Changes:
00323  
00324 \------------------------------------------------------------------*/
00325 int OLEUNWRAP_decodestream( struct OLEUNWRAP_object *oleuw, char *element_string, char *stream, size_t stream_size, char *decode_path )
00326 {
00327         int result = OLEUW_OK;
00328 
00329         if (strstr(element_string, OLEUW_ELEMENT_10NATIVE_STRING) != NULL) 
00330         {
00331                 OLEUNWRAP_decode_attachment( oleuw, stream, stream_size, decode_path );
00332 
00333         } else {
00334                 if (oleuw->debug) LOGGER_log("Unable to decode stream with element string '%s'\n", element_string);
00335                 result = OLEUW_STREAM_NOT_DECODED;
00336         }
00337 
00338         return result;
00339 }
00340 
00341 
00342 /*-----------------------------------------------------------------\
00343  Function Name  : OLEUNWRAP_set_filename_report_fn
00344  Returns Type   : int
00345         ----Parameter List
00346         1. struct OLEUNWRAP_object *oleuw, 
00347         2.  int (*ptr_to_fn)(char *) , 
00348         ------------------
00349  Exit Codes     : 
00350  Side Effects   : 
00351 --------------------------------------------------------------------
00352  Comments:
00353  
00354 --------------------------------------------------------------------
00355  Changes:
00356  
00357 \------------------------------------------------------------------*/
00358 int OLEUNWRAP_set_filename_report_fn( struct OLEUNWRAP_object *oleuw, int (*ptr_to_fn)(char *) )
00359 {
00360 
00361         oleuw->filename_report_fn = ptr_to_fn;
00362 
00363         return 0;
00364 }
00365 

Generated on Sun Mar 4 15:03:49 2007 for Scilab [trunk] by  doxygen 1.5.1