예제 #1
0
int CompareFileHashes(const char *file1, const char *file2, struct stat *sstat, struct stat *dstat, FileCopy fc, AgentConnection *conn)
{
    unsigned char digest1[EVP_MAX_MD_SIZE + 1] = { 0 }, digest2[EVP_MAX_MD_SIZE + 1] = { 0 };
    int i;

    if (sstat->st_size != dstat->st_size)
    {
        Log(LOG_LEVEL_DEBUG, "File sizes differ, no need to compute checksum");
        return true;
    }

    if (conn == NULL)
    {
        HashFile(file1, digest1, CF_DEFAULT_DIGEST);
        HashFile(file2, digest2, CF_DEFAULT_DIGEST);

        for (i = 0; i < EVP_MAX_MD_SIZE; i++)
        {
            if (digest1[i] != digest2[i])
            {
                return true;
            }
        }

        Log(LOG_LEVEL_DEBUG, "Files were identical");
        return false;           /* only if files are identical */
    }
    else
    {
        assert(fc.servers && strcmp(RlistScalarValue(fc.servers), "localhost"));
        return CompareHashNet(file1, file2, fc.encrypt, conn);  /* client.c */
    }
}
예제 #2
0
int CompareFileHashes(char *file1, char *file2, struct stat *sstat, struct stat *dstat, Attributes attr, Promise *pp)
{
    unsigned char digest1[EVP_MAX_MD_SIZE + 1] = { 0 }, digest2[EVP_MAX_MD_SIZE + 1] = { 0 };
    int i;

    CfDebug("CompareFileHashes(%s,%s)\n", file1, file2);

    if (sstat->st_size != dstat->st_size)
    {
        CfDebug("File sizes differ, no need to compute checksum\n");
        return true;
    }

    if ((attr.copy.servers == NULL) || (strcmp(attr.copy.servers->item, "localhost") == 0))
    {
        HashFile(file1, digest1, CF_DEFAULT_DIGEST);
        HashFile(file2, digest2, CF_DEFAULT_DIGEST);

        for (i = 0; i < EVP_MAX_MD_SIZE; i++)
        {
            if (digest1[i] != digest2[i])
            {
                return true;
            }
        }

        CfDebug("Files were identical\n");
        return false;           /* only if files are identical */
    }
    else
    {
        return CompareHashNet(file1, file2, attr, pp);  /* client.c */
    }
}
예제 #3
0
파일: pkcs7.cpp 프로젝트: mingpen/OpenNT
HRESULT CPkcs7::VerifyRawFile(HANDLE hFile, LPCWSTR wszFile, HCRYPTPROV hprov, ALG_ID algidHash)
// The twin to HashAndSetRawFile. 
//
// Verify that a) this SignedData contains
// an IndirectDataContent of type 'raw file', and b) the hash found inside
// said IndirectDataContent matches the hash of the file indicated here as
// EITHER wszFileName OR hFile.
//
// Note that we do NOT compare the link info in the IndirectDataContent 
// to wszFileName in any way. Note also that this does not do signature
// checking; that instead is done on SignerInfos found in this SignedData. 
//
// So, the actual verification process is two step: a) verify that the hash of the 
// current file is what is expected (call this function); and b) verify that
// the signature holds (call IAmSigned::Verify in a SignerInfo).
//
//
// Return values:
//	
//		S_OK			It all matched
//
//		E_FAIL			Content isn't an IndirectDataContent of type raw file
//
//		NTE_BAD_SIGNATURE
//						The hash did not match
	{
	PKCS7_FILEDATA rf;
	m_pworld->Init(rf);
	HRESULT hr = get_ContentRawFile(&rf);
	if (hr == S_OK)
		{
		if (algidHash == 0)
			{
			algidHash = rf.digest.algid;
			}
		DIGESTINFO digest;
		if (hFile != INVALID_HANDLE_VALUE)
			hr = HashFile(hFile, hprov, algidHash, digest);
		else
			hr = HashFile(wszFile, hprov, algidHash, digest);
		if (hr == S_OK)
			{
			if (IsEqual(digest, rf.digest))
				hr = S_OK;
			else
				hr = NTE_BAD_SIGNATURE;
			}
		FreeTaskMem(rf);
		}
	else
		hr = E_FAIL;
	return hr;
	}
예제 #4
0
bool CryptManager::Verify( RageFileBasic &file, RString sSignature, RString sPublicKey )
{
	RSAKeyWrapper key;
	RString sError;
	if( !key.Load(sPublicKey, sError) )
	{
		LOG->Warn( "Error loading RSA key: %s", sError.c_str() );
		return false;
	}

	int iHash = register_hash( &sha1_desc );
	ASSERT( iHash >= 0 );

	unsigned char buf_hash[20];
	HashFile( file, buf_hash, iHash );

	int iMatch;
	int iRet = rsa_verify_hash_ex( (const unsigned char *) sSignature.data(), sSignature.size(),
			buf_hash, sizeof(buf_hash),
			LTC_PKCS_1_EMSA, iHash, 0, &iMatch, &key.m_Key );

	if( iRet != CRYPT_OK )
	{
		LOG->Warn( "Verify(%s) failed: %s", file.GetDisplayPath().c_str(), error_to_string(iRet) );
		return false;
	}

	if( !iMatch )
	{
		LOG->Warn( "Verify(%s) failed: signature mismatch", file.GetDisplayPath().c_str() );
		return false;
	}

	return true;
}
예제 #5
0
bool Digestor::Sha1File(const std::string &path, std::string *hash_hex)
{
  ByteArray hash;
	bool ok = HashFile(path, HASH_SHA1, hash);
  if (ok)
    *hash_hex = hash.toHexStr();
  return ok;
}
예제 #6
0
std::string Digestor::MD5File(const std::string &path)
{
	assert (!path.empty()); 

	ByteArray res;
	if (HashFile(path, HASH_MD5, res) == false)
		return "";

	return res.toHexStr();
}
예제 #7
0
void UManifest::GenerateManifest(QDomDocument* dom, QDomElement root, QString dir)
{
    QDomElement folders = dom->createElement("Folders");
    root.appendChild(folders);

    QDomElement files = dom->createElement("Files");
    root.appendChild(files);

    QDirIterator it(dir);
    while (it.hasNext())
    {
        QString filePath = it.next();
        QFileInfo fi(filePath);

        if (fi.fileName() == "UnrealManifest.exe"
         || fi.fileName() == "ReleaseNotes.xml"
         || fi.fileName() == "GameManifest.xml"
         ||(fi.fileName().startsWith("Qt5") && fi.fileName().endsWith(".dll")))
        {
            continue;
        }

        if (QDir(filePath).exists())
        {
            if (!filePath.endsWith("."))
            {
                QDomElement folder = dom->createElement("FolderProperties");

                folder.setAttribute("FolderName", fi.fileName());
                root.appendChild(folder);

                GenerateManifest(dom, folder, filePath);
            }
        }
        else
        {
            QDomElement e = dom->createElement("FileProperties");
            QString fileHash = HashFile(filePath);

            if (fileHash.length() > 0)
            {
                e.setAttribute("FileName", fi.fileName());
                e.setAttribute("Size", fi.size());
                e.setAttribute("md5", fileHash);
                ui->releaseNotes->append(filePath  + " : " + fileHash);
            }
            else
            {
                e.setTagName("EmptyFile");
            }

            files.appendChild(e);
        }
    }
}
예제 #8
0
파일: main.c 프로젝트: curiousme/mp3dupfind
void read_hash(const char *path)
{
	int total_read;
	unsigned char hash[SHA_DIGEST_LENGTH];

	if ((total_read = HashFile(path, hash, HASHED_SEGMENT)) > -1) {
		for (int i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%02x", hash[i]);
		printf(" in %d bytes", total_read);
		printf("\n");
	} else {
		printf("Failed to read, got -1");
	}
}
예제 #9
0
파일: pkcs7.cpp 프로젝트: mingpen/OpenNT
HRESULT CPkcs7::HashAndSetRawFile(HANDLE hFile, LPCWSTR wszFile, HCRYPTPROV hprov, ALG_ID algidHash)
// Set the content to be, indirectly, the indicated raw file, using the indicated 
// hash algorithm.
//
	{
	PKCS7_FILEDATA rf;
	m_pworld->Init(rf);
	if (wszFile)
		{
		rf.link.tag		= CERT_LINK_TYPE_FILE;
		rf.link.wszFile	= (LPWSTR)wszFile;
		}
	else
		rf.link.tag		= CERT_LINK_TYPE_NONE;

	HRESULT hr = S_OK;

	if (hFile != INVALID_HANDLE_VALUE)
		hr = HashFile(hFile, hprov, algidHash, rf.digest);
	else
		hr = HashFile(wszFile, hprov, algidHash, rf.digest);

	if (hr == S_OK)
		{
		hr = put_ContentRawFile(&rf);
		}

	#ifdef _DEBUG
	if (hr == S_OK)
		{
		GOOD(VerifyRawFile(hFile, wszFile, hprov, algidHash));
		}
	#endif

	return hr;
	}
예제 #10
0
RString CryptManager::GetMD5ForFile( RString fn )
{
	RageFile file;
	if( !file.Open( fn, RageFile::READ ) )
	{
		LOG->Warn( "GetMD5: Failed to open file '%s'", fn.c_str() );
		return RString();
	}
	int iHash = register_hash( &md5_desc );
	ASSERT( iHash >= 0 );

	unsigned char digest[16];
	HashFile( file, digest, iHash );

	return RString( (const char *) digest, sizeof(digest) );
}
예제 #11
0
bool CryptManager::Sign( RString sPath, RString &sSignatureOut, RString sPrivKey )
{
	if( !IsAFile(sPath) )
	{
		LOG->Trace( "SignFileToFile: \"%s\" doesn't exist", sPath.c_str() );
		return false;
	}

	RageFile file;
	if( !file.Open(sPath) )
	{
		LOG->Warn( "SignFileToFile: open(%s) failed: %s", sPath.c_str(), file.GetError().c_str() );
		return false;
	}

	RSAKeyWrapper key;
	RString sError;
	if( !key.Load(sPrivKey, sError) )
	{
		LOG->Warn( "Error loading RSA key: %s", sError.c_str() );
		return false;
	}

	int iHash = register_hash( &sha1_desc );
	ASSERT( iHash >= 0 );

	unsigned char buf_hash[20];
	if( !HashFile(file, buf_hash, iHash) )
		return false;

	unsigned char signature[256];
	unsigned long signature_len = sizeof(signature);

	int iRet = rsa_sign_hash_ex(
			buf_hash, sizeof(buf_hash),
			signature, &signature_len,
			LTC_PKCS_1_V1_5, &g_pPRNG->m_PRNG, g_pPRNG->m_iPRNG, iHash,
			0, &key.m_Key);
	if( iRet != CRYPT_OK )
	{
		LOG->Warn( "SignFileToFile error: %s", error_to_string(iRet) );
		return false;
	}

	sSignatureOut.assign( (const char *) signature, signature_len );
	return true;
}
예제 #12
0
int main(int argc, char* argv[]) {
    
    std::cout<<"foo"<<std::endl;
    
    //CHHashFileVSalted HashFile(16, 0, CHHASHFILESALTED_SALT_IS_FIRST, CHHASHFILESALTED_HEX_SALT);
    CHHashFileVSalted HashFile(16, 0, CHHASHFILESALTED_HASH_IS_FIRST, CHHASHFILESALTED_LITERAL_SALT);
    
    if (argc != 2) {
        printf("Call it with the file name!\n");
        exit(1);
    }
    
    
    HashFile.OpenHashFile(argv[1]);
    
    std::cout<<(int)HashFile.GetTotalHashCount();
}
예제 #13
0
파일: server_common.c 프로젝트: fabix/core
void CompareLocalHash(ServerConnectionState *conn, char *sendbuffer, char *recvbuffer)
{
    unsigned char digest1[EVP_MAX_MD_SIZE + 1], digest2[EVP_MAX_MD_SIZE + 1];
    char filename[CF_BUFSIZE], rfilename[CF_BUFSIZE];
    char *sp;
    int i;

/* TODO - when safe change this proto string to sha2 */

    sscanf(recvbuffer, "MD5 %[^\n]", rfilename);

    sp = recvbuffer + strlen(recvbuffer) + CF_SMALL_OFFSET;

    for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
    {
        digest1[i] = *sp++;
    }

    memset(sendbuffer, 0, CF_BUFSIZE);

    TranslatePath(filename, rfilename);

    HashFile(filename, digest2, CF_DEFAULT_DIGEST);

    if ((HashesMatch(digest1, digest2, CF_DEFAULT_DIGEST)) || (HashesMatch(digest1, digest2, HASH_METHOD_MD5)))
    {
        sprintf(sendbuffer, "%s", CFD_FALSE);
        Log(LOG_LEVEL_DEBUG, "Hashes matched ok");
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
    }
    else
    {
        sprintf(sendbuffer, "%s", CFD_TRUE);
        Log(LOG_LEVEL_DEBUG, "Hashes didn't match");
        SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE);
    }
}
예제 #14
0
static void PrependAuditFile(char *file)

{ struct stat statbuf;

if ((AUDITPTR = (struct Audit *)malloc(sizeof(struct Audit))) == NULL)
   {
   FatalError("Memory allocation failure in PrependAuditFile");
   }

if (cfstat(file,&statbuf) == -1)
   {
   /* shouldn't happen */
   return;
   }

HashFile(file,AUDITPTR->digest,CF_DEFAULT_DIGEST);

AUDITPTR->next = VAUDIT;
AUDITPTR->filename = strdup(file);
AUDITPTR->date = strdup(cf_ctime(&statbuf.st_mtime));
Chop(AUDITPTR->date);
AUDITPTR->version = NULL;
VAUDIT = AUDITPTR;
}
예제 #15
0
int CheckScriptIntegrity(char *ScriptPath)
{
STREAM *S;
char *Tempstr=NULL, *Token=NULL, *Hash=NULL, *FileHash=NULL, *ptr;
int result, len;

if (! ScriptPath) return(FALSE);
if (! (Settings.Flags & FLAG_CHECK_SCRIPTS)) return(TRUE);


S=STREAMOpenFile(Settings.ScriptHashFile,SF_RDONLY);
if (S)
{
	Tempstr=STREAMReadLine(Tempstr,S);
	while (Tempstr)
	{
		StripTrailingWhitespace(Tempstr);
		ptr=GetToken(Tempstr," ",&Token,0);
		while (ptr && isspace(*ptr)) ptr++;

		if (ptr && (strcmp(ptr,ScriptPath)==0))
		{
		Hash=CopyStr(Hash,Token);
		len=StrLen(Hash);
		switch (len)
		{
			case 32: //MD5
				HashFile(&FileHash, "md5", ScriptPath, ENCODE_HEX);
			break;

			case 40: //SHA1
				HashFile(&FileHash, "sha1", ScriptPath, ENCODE_HEX);
			break;

			case 64: //SHA256
				HashFile(&FileHash, "sha256", ScriptPath, ENCODE_HEX);
			break;

			case 128: //SHA512
				HashFile(&FileHash, "sha512", ScriptPath, ENCODE_HEX);
			break;
		}
		}

		Tempstr=STREAMReadLine(Tempstr,S);
	
	}
STREAMClose(S);
}


if (StrLen(FileHash) && StrLen(Hash) && (strcmp(FileHash,Hash)==0) ) result=TRUE;
else 
{
	LogToFile(Settings.LogPath,"ERROR: Not running script '%s'. Script failed integrity check.",ScriptPath);
	result=FALSE;
}

DestroyString(FileHash);
DestroyString(Tempstr);
DestroyString(Token);
DestroyString(Hash);

return(result);
}
예제 #16
0
파일: client_code.c 프로젝트: amousset/core
int CompareHashNet(const char *file1, const char *file2, bool encrypt, AgentConnection *conn)
{
    unsigned char d[EVP_MAX_MD_SIZE + 1];
    char *sp, sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], in[CF_BUFSIZE], out[CF_BUFSIZE];
    int i, tosend, cipherlen;

    HashFile(file2, d, CF_DEFAULT_DIGEST);

    memset(recvbuffer, 0, CF_BUFSIZE);

    /* We encrypt only for CLASSIC protocol. The TLS protocol is always over
     * encrypted layer, so it does not support encrypted (S*) commands. */
    encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC;

    if (encrypt)
    {
        snprintf(in, CF_BUFSIZE, "MD5 %s", file1);

        sp = in + strlen(in) + CF_SMALL_OFFSET;

        for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
        {
            *sp++ = d[i];
        }

        cipherlen =
            EncryptString(conn->encryption_type, in, out, conn->session_key,
                          strlen(in) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN);
        snprintf(sendbuffer, CF_BUFSIZE, "SMD5 %d", cipherlen);
        memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen);
        tosend = cipherlen + CF_PROTO_OFFSET;
    }
    else
    {
        snprintf(sendbuffer, CF_BUFSIZE, "MD5 %s", file1);
        sp = sendbuffer + strlen(sendbuffer) + CF_SMALL_OFFSET;

        for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
        {
            *sp++ = d[i];
        }

        tosend = strlen(sendbuffer) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN;
    }

    if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR, "Failed send. (SendTransaction: %s)", GetErrorStr());
        return false;
    }

    if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1)
    {
        /* TODO mark connection in the cache as closed. */
        Log(LOG_LEVEL_ERR, "Failed receive. (ReceiveTransaction: %s)", GetErrorStr());
        Log(LOG_LEVEL_VERBOSE,  "No answer from host, assuming checksum ok to avoid remote copy for now...");
        return false;
    }

    if (strcmp(CFD_TRUE, recvbuffer) == 0)
    {
        return true;            /* mismatch */
    }
    else
    {
        return false;
    }

/* Not reached */
}
예제 #17
0
bool Digestor::Sha512File(const std::string &path, ByteArray &hash)
{
	return HashFile(path, HASH_SHA512, hash);
}
예제 #18
0
int CHashManager::HashPath(char *pszBasePath, char *pszFileSpec)
{
	recursivesafe long lHandle = 0;
	recursivesafe long lSearcherHandle = 0;
	recursivesafe finddata fdInfo;
	recursivesafe char szFull[RH_MAX_PATH];
	recursivesafe char szAll[RH_MAX_PATH];

	if(pszBasePath == NULL) return RH_INVALID_PATH;
	if(pszFileSpec == NULL) return RH_INVALID_PATH;

	fmtPath(pszBasePath);
	fmtPath(pszFileSpec);

	if(strlen(pszBasePath) == 0) getcwd(pszBasePath, RH_MAX_PATH);
	fileonly(pszFileSpec);

	strcpy(szAll, pszBasePath);
	catdirsep(szAll);
	strcat(szAll, SZ_DIR_ALL);

	#ifdef RH_DEBUG
		printf("Function HashPath: pszBasePath=%s, pszFileSpec=%s", pszBasePath, pszFileSpec);
		printf(CPS_NEWLINE);
		printf("Function HashPath: szAll=%s", szAll);
		printf(CPS_NEWLINE);
	#endif

	//////////////////////////////////////////////////////////////////////////
	// Start directory enumeration code

	lSearcherHandle = findfirst(szAll, &fdInfo);
	while(1)
	{
		if(fdInfo.attrib & _A_SUBDIR)
		{
			if((ispathnav(fdInfo.name) == false) && (m_bRecursive))
			{
				if(chdir(fdInfo.name) == 0)
				{
					getcwd(szFull, RH_MAX_PATH);

					#ifdef RH_DEBUG
						printf("Opening new scan path: %s, filemask: %s", szFull, pszFileSpec);
						printf(CPS_NEWLINE);
					#endif

					HashPath(szFull, pszFileSpec);
					chdir(SZ_LEVEL_UP);
				}
			}
		}

		if(findnext(lSearcherHandle, &fdInfo) != 0) break;
	}
	findclose(lSearcherHandle);
	lSearcherHandle = 0;

	// End directory enumeration code
	//////////////////////////////////////////////////////////////////////////

	memset(&fdInfo, 0, sizeof(finddata));
	lHandle = findfirst(pszFileSpec, &fdInfo);
	if(lHandle == EINVAL) return RH_INVALID_PATH;
	if(lHandle == ENOENT) return RH_NO_PATTERN_MATCH;
	if(lHandle == -1) return RH_CANNOT_OPEN_FILE;

	while(1)
	{
		if(fdInfo.attrib & _A_SUBDIR)
		{
			// Don't process directories here
		}
		else
		{
			if(m_bFullPath)
			{
				fullpath(szFull, fdInfo.name, RH_MAX_PATH);
				HashFile(szFull);
			}
			else
			{
				HashFile(fdInfo.name);
			}
			printf(CPS_NEWLINE);
		}

		if(findnext(lHandle, &fdInfo) != 0) break;
	}

	findclose(lHandle);
	lHandle = 0;

	return RH_SUCCESS;
}
예제 #19
0
int CompareHashNet(char *file1, char *file2, bool encrypt, AgentConnection *conn)
{
    static unsigned char d[EVP_MAX_MD_SIZE + 1];
    char *sp, sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], in[CF_BUFSIZE], out[CF_BUFSIZE];
    int i, tosend, cipherlen;

    HashFile(file2, d, CF_DEFAULT_DIGEST);

    memset(recvbuffer, 0, CF_BUFSIZE);

    if (encrypt)
    {
        snprintf(in, CF_BUFSIZE, "MD5 %s", file1);

        sp = in + strlen(in) + CF_SMALL_OFFSET;

        for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
        {
            *sp++ = d[i];
        }

        cipherlen =
            EncryptString(conn->encryption_type, in, out, conn->session_key,
                          strlen(in) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN);
        snprintf(sendbuffer, CF_BUFSIZE, "SMD5 %d", cipherlen);
        memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen);
        tosend = cipherlen + CF_PROTO_OFFSET;
    }
    else
    {
        snprintf(sendbuffer, CF_BUFSIZE, "MD5 %s", file1);
        sp = sendbuffer + strlen(sendbuffer) + CF_SMALL_OFFSET;

        for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++)
        {
            *sp++ = d[i];
        }

        tosend = strlen(sendbuffer) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN;
    }

    if (SendTransaction(conn->sd, sendbuffer, tosend, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR, "Failed send. (SendTransaction: %s)", GetErrorStr());
        return false;
    }

    if (ReceiveTransaction(conn->sd, recvbuffer, NULL) == -1)
    {
        Log(LOG_LEVEL_ERR, "Failed receive. (ReceiveTransaction: %s)", GetErrorStr());
        Log(LOG_LEVEL_VERBOSE,  "No answer from host, assuming checksum ok to avoid remote copy for now...");
        return false;
    }

    if (strcmp(CFD_TRUE, recvbuffer) == 0)
    {
        return true;            /* mismatch */
    }
    else
    {
        return false;
    }

/* Not reached */
}
예제 #20
0
///-------------------------------------------------------------------------------------------------
///  Scan a single file. Everything that applies to ms_scan also applies to this function. If
///   you know the type of the file, set the type paramter to one of TYPE_AUDIO, TYPE_VIDEO, or
///   TYPE_IMAGE. Set it to TYPE_UNKNOWN to have it determined automatically.
///
/// @author Andy Grundman
/// @date 03/15/2011
///
/// @param [in,out] s If non-null, the.
/// @param full_path  Full pathname of the full file.
///
/// ### remarks .
///-------------------------------------------------------------------------------------------------
void ms_scan_file(MediaScan *s, const char *full_path, enum media_type type) {
  MediaScanError *e = NULL;
  MediaScanResult *r = NULL;
  int ret;
  uint32_t hash;
  int mtime = 0;
  uint64_t size = 0;
  DBT key, data;
  char tmp_full_path[MAX_PATH_STR_LEN];

#ifdef WIN32
  char *ext = strrchr(full_path, '.');
#endif

  if (s == NULL) {
    ms_errno = MSENO_NULLSCANOBJ;
    LOG_ERROR("MediaScan = NULL, aborting scan\n");
    return;
  }

  if (s->on_result == NULL) {
    ms_errno = MSENO_NORESULTCALLBACK;
    LOG_ERROR("Result callback not set, aborting scan\n");
    return;
  }

#if (defined(__APPLE__) && defined(__MACH__))
  if (isAlias(full_path)) {
    LOG_INFO("File  %s is a mac alias\n", full_path);
    // Check if this file is a shortcut and if so resolve it
    if (!CheckMacAlias(full_path, tmp_full_path)) {
      LOG_ERROR("Failure to follow symlink or alias, skipping file\n");
      return;
    }
  }
  else {
    strcpy(tmp_full_path, full_path);
  }
#elif defined(__unix__) || defined(__unix)
  if (isAlias(full_path)) {
    LOG_INFO("File %s is a unix symlink\n", full_path);
    // Check if this file is a shortcut and if so resolve it
    FollowLink(full_path, tmp_full_path);
  }
  else {
    strcpy(tmp_full_path, full_path);
  }
#elif defined(WIN32)
  if (strcasecmp(ext, ".lnk") == 0) {
    // Check if this file is a shortcut and if so resolve it
    parse_lnk(full_path, tmp_full_path, MAX_PATH_STR_LEN);
    if (PathIsDirectory(tmp_full_path))
      return;
  }
  else {
    strcpy(tmp_full_path, full_path);
  }
#endif

  // Check if the file has been recently scanned
  hash = HashFile(tmp_full_path, &mtime, &size);

  // Skip 0-byte files
  if (unlikely(size == 0)) {
    LOG_WARN("Skipping 0-byte file: %s\n", tmp_full_path);
    return;
  }

  // Setup DBT values
  memset(&key, 0, sizeof(DBT));
  memset(&data, 0, sizeof(DBT));
  key.data = (char *)full_path;
  key.size = strlen(full_path) + 1;
  data.data = &hash;
  data.size = sizeof(uint32_t);

  if ((s->flags & MS_RESCAN) || (s->flags & MS_FULL_SCAN)) {
    // s->dbp will be null if this function is called directly, if not check if this file is
    // already scanned.
    if (s->dbp != NULL) {
      // DB_GET_BOTH will only return OK if both key and data match, this avoids the need to check
      // the returned data against hash
      int ret = s->dbp->get(s->dbp, NULL, &key, &data, DB_GET_BOTH);
      if (ret != DB_NOTFOUND) {
        //  LOG_INFO("File %s already scanned, skipping\n", tmp_full_path);
        return;
      }
    }
  }

  LOG_INFO("Scanning file %s\n", tmp_full_path);

  if (type == TYPE_UNKNOWN || type == TYPE_LNK) {
    // auto-detect type
    type = _should_scan(s, tmp_full_path);
    if (!type) {
      if (s->on_error) {
        ms_errno = MSENO_SCANERROR;
        e = error_create(tmp_full_path, MS_ERROR_TYPE_UNKNOWN, "Unrecognized file extension");
        send_error(s, e);
        return;
      }
    }
  }

  r = result_create(s);
  if (r == NULL)
    return;

  r->type = type;
  r->path = strdup(full_path);

  if (result_scan(r)) {
    // These were determined by HashFile
    r->mtime = mtime;
    r->size = size;
    r->hash = hash;

    // Store path -> hash data in cache
    if (s->dbp != NULL) {
      memset(&data, 0, sizeof(DBT));
      data.data = &hash;
      data.size = sizeof(uint32_t);

      ret = s->dbp->put(s->dbp, NULL, &key, &data, 0);
      if (ret != 0) {
        s->dbp->err(s->dbp, ret, "Cache store failed: %s", db_strerror(ret));
      }
    }
    send_result(s, r);
  }
  else {
    if (s->on_error && r->error) {
      // Copy the error, because the original will be cleaned up by result_destroy below
      MediaScanError *ecopy = error_copy(r->error);
      send_error(s, ecopy);
    }

    result_destroy(r);
  }
}                               /* ms_scan_file() */
예제 #21
0
파일: loading.c 프로젝트: ddurieux/core
static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringSet *parsed_files_and_checksums, StringSet *failed_files)
{
    unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
    char hashbuffer[CF_HOSTKEY_STRING_SIZE] = { 0 };
    char hashprintbuffer[CF_BUFSIZE] = { 0 };

    HashFile(policy_file, digest, CF_DEFAULT_DIGEST);
    snprintf(hashprintbuffer, CF_BUFSIZE - 1, "{checksum}%s",
             HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest,
                           CF_DEFAULT_DIGEST, true));

    Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashprintbuffer);

    if (StringSetContains(parsed_files_and_checksums, policy_file))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file);
        return NULL;
    }
    else if (StringSetContains(parsed_files_and_checksums, hashprintbuffer))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file);
        return NULL;
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file);
    }

    Policy *policy = Cf3ParseFile(config, policy_file);
    // we keep the checksum and the policy file name to help debugging
    StringSetAdd(parsed_files_and_checksums, xstrdup(policy_file));
    StringSetAdd(parsed_files_and_checksums, xstrdup(hashprintbuffer));

    if (policy)
    {
        Seq *errors = SeqNew(10, free);
        if (!PolicyCheckPartial(policy, errors))
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            SeqDestroy(errors);

            StringSetAdd(failed_files, xstrdup(policy_file));
            PolicyDestroy(policy);
            return NULL;
        }

        SeqDestroy(errors);
    }
    else
    {
        StringSetAdd(failed_files, xstrdup(policy_file));
        return NULL;
    }

    PolicyResolve(ctx, policy, config);

    DataType def_inputs_type = CF_DATA_TYPE_NONE;
    VarRef *inputs_ref = VarRefParse("def.augment_inputs");
    const void *def_inputs = EvalContextVariableGet(ctx, inputs_ref, &def_inputs_type);
    VarRefDestroy(inputs_ref);

    if (RVAL_TYPE_CONTAINER == DataTypeToRvalType(def_inputs_type) && NULL != def_inputs)
    {
        const JsonElement *el;
        JsonIterator iter = JsonIteratorInit((JsonElement*) def_inputs);
        while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true)))
        {
            char *input = JsonPrimitiveToString(el);

            Log(LOG_LEVEL_VERBOSE, "Loading augments from def.augment_inputs: %s", input);

            Rlist* inputs_rlist = NULL;
            RlistAppendScalar(&inputs_rlist, input);
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, inputs_rlist,
                                                      parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }

            RlistDestroy(inputs_rlist);
            free(input);
        }
    }

    Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control");
    Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control");

    if (body_common_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    if (body_file_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    return policy;
}
예제 #22
0
파일: verify_files.c 프로젝트: lra/core
static PromiseResult RenderTemplateMustache(EvalContext *ctx, const Promise *pp, Attributes a,
                                            EditContext *edcontext)
{
    PromiseResult result = PROMISE_RESULT_NOOP;

    if (!FileCanOpen(a.edit_template, "r"))
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Template file '%s' could not be opened for reading", a.edit_template);
        return PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
    }

    unsigned char existing_output_digest[EVP_MAX_MD_SIZE + 1] = { 0 };
    if (access(pp->promiser, R_OK) == 0)
    {
        HashFile(pp->promiser, existing_output_digest, CF_DEFAULT_DIGEST);
    }

    int template_fd = safe_open(a.edit_template, O_RDONLY | O_TEXT);
    Writer *template_writer = NULL;
    if (template_fd >= 0)
    {
        template_writer = FileReadFromFd(template_fd, SIZE_MAX, NULL);
        close(template_fd);
    }
    if (!template_writer)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not read template file '%s'", a.edit_template);
        return PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
    }

    JsonElement *default_template_data = NULL;
    if (!a.template_data)
    {
        a.template_data = default_template_data = DefaultTemplateData(ctx);
    }

    Buffer *output_buffer = BufferNew();
    if (MustacheRender(output_buffer, StringWriterData(template_writer), a.template_data))
    {
        unsigned char rendered_output_digest[EVP_MAX_MD_SIZE + 1] = { 0 };
        HashString(BufferData(output_buffer), BufferSize(output_buffer), rendered_output_digest, CF_DEFAULT_DIGEST);
        if (!HashesMatch(existing_output_digest, rendered_output_digest, CF_DEFAULT_DIGEST))
        {
            if (SaveAsFile(SaveBufferCallback, output_buffer, edcontext->filename, a, edcontext->new_line_mode))
            {
                cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Updated rendering of '%s' from template mustache template '%s'",
                     pp->promiser, a.edit_template);
                result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE);
            }
            else
            {
                cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Updated rendering of '%s' from template mustache template '%s'",
                     pp->promiser, a.edit_template);
                result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
            }
        }

        JsonDestroy(default_template_data);
        WriterClose(template_writer);
        BufferDestroy(output_buffer);

        return result;
    }
    else
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error rendering mustache template '%s'", a.edit_template);
        result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
        JsonDestroy(default_template_data);
        WriterClose(template_writer);
        BufferDestroy(output_buffer);
        return PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
    }
}
예제 #23
0
파일: loading.c 프로젝트: lra/core
static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringSet *parsed_files_and_checksums, StringSet *failed_files)
{
    Policy *policy = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
    char hashbuffer[EVP_MAX_MD_SIZE * 4] = { 0 };
    char hashprintbuffer[CF_BUFSIZE] = { 0 };

    HashFile(policy_file, digest, CF_DEFAULT_DIGEST);
    snprintf(hashprintbuffer, CF_BUFSIZE - 1, "{checksum}%s",
             HashPrintSafe(CF_DEFAULT_DIGEST, true, digest, hashbuffer));

    Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashprintbuffer);

    if (StringSetContains(parsed_files_and_checksums, policy_file))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file);
        return NULL;
    }
    else if (StringSetContains(parsed_files_and_checksums, hashprintbuffer))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file);
        return NULL;
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file);
    }

    policy = Cf3ParseFile(config, policy_file);
    // we keep the checksum and the policy file name to help debugging
    StringSetAdd(parsed_files_and_checksums, xstrdup(policy_file));
    StringSetAdd(parsed_files_and_checksums, xstrdup(hashprintbuffer));

    if (policy)
    {
        Seq *errors = SeqNew(10, free);
        if (!PolicyCheckPartial(policy, errors))
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            SeqDestroy(errors);

            StringSetAdd(failed_files, xstrdup(policy_file));
            return NULL;
        }

        SeqDestroy(errors);
    }
    else
    {
        StringSetAdd(failed_files, xstrdup(policy_file));
        return NULL;
    }

    PolicyResolve(ctx, policy, config);

    Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control");
    Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control");

    if (body_common_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    if (body_file_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    return policy;
}