int chksumLocFile( char* _file_name, char* _checksum, const char* _hash_scheme ) { if ( !_file_name || !_checksum || !_hash_scheme ) { rodsLog( LOG_ERROR, "chksumLocFile :: null input param - %p %p %p", _file_name, _checksum, _hash_scheme ); return SYS_INVALID_INPUT_PARAM; } // =-=-=-=-=-=-=- // capture client side configuration rodsEnv env; int status = getRodsEnv( &env ); if ( status < 0 ) { return status; } // =-=-=-=-=-=-=- // capture the configured scheme if it is valid std::string env_scheme( irods::MD5_NAME ); if ( strlen( env.rodsDefaultHashScheme ) > 0 ) { env_scheme = env.rodsDefaultHashScheme; } // =-=-=-=-=-=-=- // capture the configured hash match policy if it is valid std::string env_policy; if ( strlen( env.rodsMatchHashPolicy ) > 0 ) { env_policy = env.rodsMatchHashPolicy; // =-=-=-=-=-=-=- // hash scheme keywords are all lowercase std::transform( env_scheme.begin(), env_scheme.end(), env_scheme.begin(), ::tolower ); } // =-=-=-=-=-=-=- // capture the incoming scheme if it is valid std::string hash_scheme; if ( _hash_scheme && strlen( _hash_scheme ) > 0 && strlen( _hash_scheme ) < NAME_LEN ) { hash_scheme = _hash_scheme; // =-=-=-=-=-=-=- // hash scheme keywords are all lowercase std::transform( hash_scheme.begin(), hash_scheme.end(), hash_scheme.begin(), ::tolower ); } else { hash_scheme = env_scheme; } // =-=-=-=-=-=-=- // hash scheme keywords are all lowercase std::transform( hash_scheme.begin(), hash_scheme.end(), hash_scheme.begin(), ::tolower ); std::transform( env_scheme.begin(), env_scheme.end(), env_scheme.begin(), ::tolower ); // =-=-=-=-=-=-=- // verify checksum scheme against configuration // if requested std::string final_scheme( env_scheme ); if ( !hash_scheme.empty() ) { if ( !env_policy.empty() ) { if ( irods::STRICT_HASH_POLICY == env_policy ) { if ( env_scheme != hash_scheme ) { return USER_HASH_TYPE_MISMATCH; } } } final_scheme = hash_scheme; } // =-=-=-=-=-=-=- // init the hasher object irods::Hasher hasher; irods::error ret = irods::getHasher( final_scheme, hasher ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } // =-=-=-=-=-=-=- // open the local file std::ifstream in_file( _file_name, std::ios::in | std::ios::binary ); if ( !in_file.is_open() ) { status = UNIX_FILE_OPEN_ERR - errno; rodsLogError( LOG_NOTICE, status, "chksumLocFile - fopen failed for %s, status = %d", _file_name, status ); return status; } char buffer_read[ MD5_BUF_SZ ]; std::streamsize bytes_read = in_file.readsome( buffer_read, MD5_BUF_SZ ); while ( bytes_read > 0 ) { hasher.update( std::string( buffer_read, bytes_read ) ); bytes_read = in_file.readsome( buffer_read, MD5_BUF_SZ ); } // =-=-=-=-=-=-=- // capture the digest std::string digest; hasher.digest( digest ); strncpy( _checksum, digest.c_str(), digest.size() + 1 ); return 0; } // chksumLocFile
int fileChksum( rsComm_t* rsComm, char* objPath, char* fileName, char* rescHier, char* orig_chksum, char* chksumStr ) { // =-=-=-=-=-=-=- // capture server hashing settings std::string svr_hash_scheme; irods::server_properties& props = irods::server_properties::getInstance(); irods::error ret = props.get_property< std::string >( DEFAULT_HASH_SCHEME_KW, svr_hash_scheme ); std::string hash_scheme( irods::MD5_NAME ); if ( ret.ok() ) { hash_scheme = svr_hash_scheme; } // make sure the read parameter is lowercased std::transform( hash_scheme.begin(), hash_scheme.end(), hash_scheme.begin(), ::tolower); std::string svr_hash_policy; ret = props.get_property< std::string >( MATCH_HASH_POLICY_KW, svr_hash_policy ); std::string hash_policy; if ( ret.ok() ) { hash_policy = svr_hash_policy; } // =-=-=-=-=-=-=- // extract scheme from checksum string std::string chkstr_scheme; if ( orig_chksum ) { ret = irods::get_hash_scheme_from_checksum( orig_chksum, chkstr_scheme ); if ( !ret.ok() ) { //irods::log( PASS( ret ) ); } } // =-=-=-=-=-=-=- // check the hash scheme against the policy // if necessary std::string final_scheme( hash_scheme ); if ( !chkstr_scheme.empty() ) { if ( !hash_policy.empty() ) { if ( irods::STRICT_HASH_POLICY == hash_policy ) { if ( hash_scheme != chkstr_scheme ) { return USER_HASH_TYPE_MISMATCH; } } } final_scheme = chkstr_scheme; } rodsLog( LOG_DEBUG, "fileChksum :: final_scheme [%s] chkstr_scheme [%s] svr_hash_policy [%s] hash_policy [%s]", final_scheme.c_str(), chkstr_scheme.c_str(), svr_hash_policy.c_str(), hash_policy.c_str() ); // =-=-=-=-=-=-=- // call resource plugin to open file irods::file_object_ptr file_obj( new irods::file_object( rsComm, objPath, fileName, rescHier, -1, 0, O_RDONLY ) ); // FIXME :: hack until this is better abstracted - JMC ret = fileOpen( rsComm, file_obj ); if ( !ret.ok() ) { int status = UNIX_FILE_OPEN_ERR - errno; if ( ret.code() != DIRECT_ARCHIVE_ACCESS ) { std::stringstream msg; msg << "fileOpen failed for ["; msg << fileName; msg << "]"; irods::log( PASSMSG( msg.str(), ret ) ); } else { status = ret.code(); } return status; } // =-=-=-=-=-=-=- // create a hasher object and init given a scheme // if it is unsupported then default to md5 irods::Hasher hasher; ret = irods::getHasher( final_scheme, hasher ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); irods::getHasher( irods::MD5_NAME, hasher ); } // =-=-=-=-=-=-=- // do an inital read of the file char buffer[SVR_MD5_BUF_SZ]; irods::error read_err = fileRead( rsComm, file_obj, buffer, SVR_MD5_BUF_SZ ); int bytes_read = read_err.code(); // =-=-=-=-=-=-=- // loop and update while there are still bytes to be read #ifdef MD5_DEBUG rodsLong_t total_bytes_read = 0; /* XXXX debug */ #endif while ( read_err.ok() && bytes_read > 0 ) { // =-=-=-=-=-=-=- // debug statistics #ifdef MD5_DEBUG total_bytes_read += bytes_read; #endif // =-=-=-=-=-=-=- // update hasher hasher.update( std::string( buffer, bytes_read ) ); // =-=-=-=-=-=-=- // read some more read_err = fileRead( rsComm, file_obj, buffer, SVR_MD5_BUF_SZ ); if ( read_err.ok() ) { bytes_read = read_err.code(); } else { std::stringstream msg; msg << __FUNCTION__; msg << " - Failed to read buffer from file: \""; msg << fileName; msg << "\""; irods::error result = PASSMSG( msg.str(), read_err ); irods::log( result ); return result.code(); } } // while // =-=-=-=-=-=-=- // close out the file ret = fileClose( rsComm, file_obj ); if ( !ret.ok() ) { irods::error err = PASSMSG( "error on close", ret ); irods::log( err ); } // =-=-=-=-=-=-=- // extract the digest from the hasher object // and copy to outgoing string std::string digest; hasher.digest( digest ); strncpy( chksumStr, digest.c_str(), NAME_LEN ); // =-=-=-=-=-=-=- // debug messaging #ifdef MD5_DEBUG rodsLog( LOG_NOTICE, "fileChksum: chksum = %s, total_bytes_read = %lld", chksumStr, total_bytes_read ); #endif return 0; }
int chksumLocFile( char *fileName, char *chksumStr, const char* scheme ) { FILE *file = 0; int len = 0; char buffer[MD5_BUF_SZ]; // =-=-=-=-=-=-=- // capture client side configuration rodsEnv env; int status = getRodsEnv( &env ); if ( status < 0 ) { return status; } // =-=-=-=-=-=-=- // capture the configured scheme if it is valid std::string env_scheme( irods::MD5_NAME ); if ( strlen( env.rodsDefaultHashScheme ) > 0 ) { env_scheme = env.rodsDefaultHashScheme; } // =-=-=-=-=-=-=- // capture the configured hash match policy if it is valid std::string env_policy; if ( strlen( env.rodsMatchHashPolicy ) > 0 ) { env_policy = env.rodsMatchHashPolicy; } // =-=-=-=-=-=-=- // capture the incoming scheme if it is valid std::string hash_scheme; if ( scheme && strlen( scheme ) > 0 && strlen( scheme ) < NAME_LEN ) { hash_scheme = scheme; } // =-=-=-=-=-=-=- // verify checksum scheme against configuration // if requested std::string final_scheme( env_scheme ); if ( !hash_scheme.empty() ) { if ( !env_policy.empty() ) { if ( irods::STRICT_HASH_POLICY == env_policy ) { if ( env_scheme != hash_scheme ) { return USER_HASH_TYPE_MISMATCH; } } } final_scheme = hash_scheme; } // =-=-=-=-=-=-=- // open the local file if ( ( file = fopen( fileName, "rb" ) ) == NULL ) { status = UNIX_FILE_OPEN_ERR - errno; rodsLogError( LOG_NOTICE, status, "chksumFile; fopen failed for %s. status = %d", fileName, status ); return status; } // =-=-=-=-=-=-=- // init the hasher object irods::Hasher hasher; irods::error ret = irods::getHasher( final_scheme, hasher ); while ( ( len = fread( buffer, 1, MD5_BUF_SZ, file ) ) > 0 ) { hasher.update( std::string( buffer, len ) ); } fclose( file ); // =-=-=-=-=-=-=- // capture the digest std::string digest; hasher.digest( digest ); strncpy( chksumStr, digest.c_str(), digest.size() + 1 ); return 0; }