00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035
00036 #include <cerrno>
00037 #include <cstring>
00038 #include <sstream>
00039 #include <iostream>
00040
00041 using std::istringstream ;
00042 using std::cout ;
00043 using std::endl ;
00044
00045 #include "BESUtil.h"
00046 #include "BESForbiddenError.h"
00047 #include "BESNotFoundError.h"
00048 #include "config.h"
00049
00050 #define CRLF "\r\n"
00051
00056 void
00057 BESUtil::set_mime_text( ostream &strm )
00058 {
00059 strm << "HTTP/1.0 200 OK" << CRLF ;
00060 strm << "XBES-Server: " << PACKAGE_STRING << CRLF ;
00061
00062 const time_t t = time(0);
00063 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00064 strm << "Last-Modified: " << rfc822_date(t).c_str() << CRLF ;
00065
00066 strm << "Content-Type: text/plain" << CRLF ;
00067
00068 strm << "Content-Description: unknown" << CRLF ;
00069 strm << CRLF ;
00070 }
00071
00076 void
00077 BESUtil::set_mime_html( ostream &strm )
00078 {
00079 strm << "HTTP/1.0 200 OK" << CRLF ;
00080 strm << "XBES-Server: " << PACKAGE_STRING << CRLF ;
00081
00082 const time_t t = time(0);
00083 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00084 strm << "Last-Modified: " << rfc822_date(t).c_str() << CRLF ;
00085
00086 strm << "Content-type: text/html" << CRLF ;
00087
00088 strm << "Content-Description: unknown" << CRLF ;
00089 strm << CRLF ;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 static const char *days[]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
00125 static const char *months[]={"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
00126 "Aug", "Sep", "Oct", "Nov", "Dec"};
00127
00137 string
00138 BESUtil::rfc822_date(const time_t t)
00139 {
00140 struct tm *stm = gmtime(&t);
00141 char d[256];
00142
00143 snprintf(d, 255, "%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm->tm_wday],
00144 stm->tm_mday, months[stm->tm_mon],
00145 1900 + stm->tm_year,
00146 stm->tm_hour, stm->tm_min, stm->tm_sec);
00147 d[255] = '\0';
00148 return string(d);
00149 }
00150
00151 string
00152 BESUtil::unhexstring( string s )
00153 {
00154 int val;
00155 istringstream ss( s ) ;
00156 ss >> std::hex >> val;
00157 char tmp_str[2];
00158 tmp_str[0] = static_cast<char>(val);
00159 tmp_str[1] = '\0';
00160 return string(tmp_str);
00161 }
00162
00163 string
00164 BESUtil::www2id(const string &in, const string &escape, const string &except)
00165 {
00166 string::size_type i = 0;
00167 string res = in;
00168 while ((i = res.find_first_of(escape, i)) != string::npos) {
00169 if (res.substr(i, 3) == except) {
00170 i += 3;
00171 continue;
00172 }
00173 res.replace(i, 3, unhexstring(res.substr(i + 1, 2)));
00174 }
00175
00176 return res;
00177 }
00178
00179 string
00180 BESUtil::lowercase( const string &s )
00181 {
00182 string return_string = s ;
00183 for( int j = 0; j < return_string.length(); j++ )
00184 {
00185 return_string[j] = (char)tolower( return_string[j] ) ;
00186 }
00187
00188 return return_string ;
00189 }
00190
00191 string
00192 BESUtil::unescape( const string &s )
00193 {
00194 bool done = false ;
00195 string::size_type index = 0 ;
00196 string::size_type new_index = 0 ;
00197 string new_str ;
00198 while( !done )
00199 {
00200 string::size_type bs = s.find( '\\', index ) ;
00201 if( bs == string::npos )
00202 {
00203 new_str += s.substr( index, s.length() - index ) ;
00204 done = true ;
00205 }
00206 else
00207 {
00208 new_str += s.substr( index, bs - index ) ;
00209 new_str += s[bs+1] ;
00210 index = bs+2 ;
00211 }
00212 }
00213
00214 return new_str ;
00215 }
00216
00238 void
00239 BESUtil::check_path( const string &path,
00240 const string &root,
00241 bool follow_sym_links )
00242 {
00243
00244
00245 if( path == "" )
00246 return ;
00247
00248
00249
00250 string::size_type dotdot = path.find( ".." ) ;
00251 if( dotdot != string::npos )
00252 {
00253 string s = (string)"You are not allowed to access the node " + path;
00254 throw BESForbiddenError( s, __FILE__, __LINE__ ) ;
00255 }
00256
00257
00258
00259
00260 bool done = false ;
00261
00262
00263 string rem = path ;
00264 if( rem[0] == '/' )
00265 rem = rem.substr( 1, rem.length() - 1 ) ;
00266 if( rem[rem.length()-1] == '/' )
00267 rem = rem.substr( 0, rem.length() - 1 ) ;
00268
00269
00270 string fullpath = root ;
00271 if( fullpath[fullpath.length()-1] == '/' )
00272 {
00273 fullpath = fullpath.substr( 0, fullpath.length() - 1 ) ;
00274 }
00275
00276
00277 string checked ;
00278
00279 while( !done )
00280 {
00281 size_t slash = rem.find( '/' ) ;
00282 if( slash == string::npos )
00283 {
00284 fullpath = fullpath + "/" + rem ;
00285 checked = checked + "/" + rem ;
00286 done = true ;
00287 }
00288 else
00289 {
00290 fullpath = fullpath + "/" + rem.substr( 0, slash ) ;
00291 checked = checked + "/" + rem.substr( 0, slash ) ;
00292 rem = rem.substr( slash + 1, rem.length() - slash ) ;
00293 }
00294
00295 if( !follow_sym_links )
00296 {
00297 struct stat buf;
00298 int statret = lstat( fullpath.c_str(), &buf ) ;
00299 if( statret == -1 )
00300 {
00301 int errsv = errno ;
00302
00303
00304 char *s_err = strerror( errsv ) ;
00305 string error = "Unable to access node " + checked + ": " ;
00306 if( s_err )
00307 {
00308 error = error + s_err ;
00309 }
00310 else
00311 {
00312 error = error + "unknow access error" ;
00313 }
00314
00315
00316 if( errsv == ENOENT )
00317 {
00318 throw BESNotFoundError( error, __FILE__, __LINE__ ) ;
00319 }
00320 else
00321 {
00322 throw BESForbiddenError( error, __FILE__, __LINE__ ) ;
00323 }
00324 }
00325 else
00326 {
00327
00328 if( S_ISLNK( buf.st_mode ) )
00329 {
00330 string error = "You do not have permission to access "
00331 + checked ;
00332 throw BESForbiddenError( error, __FILE__, __LINE__ ) ;
00333 }
00334 }
00335 }
00336 else
00337 {
00338
00339
00340 struct stat buf ;
00341 int statret = stat( fullpath.c_str(), &buf ) ;
00342 if( statret == -1 )
00343 {
00344 int errsv = errno ;
00345
00346
00347 char *s_err = strerror( errsv ) ;
00348 string error = "Unable to access node " + checked + ": " ;
00349 if( s_err )
00350 {
00351 error = error + s_err ;
00352 }
00353 else
00354 {
00355 error = error + "unknow access error" ;
00356 }
00357
00358
00359 if( errsv == ENOENT )
00360 {
00361 throw BESNotFoundError( error, __FILE__, __LINE__ ) ;
00362 }
00363 else
00364 {
00365 throw BESForbiddenError( error, __FILE__, __LINE__ ) ;
00366 }
00367 }
00368 }
00369 }
00370 }
00371