Skip to content

Commit

Permalink
Fix Bug #1353559 and Bug #1249006: If disk S/N is hex encoded, try to…
Browse files Browse the repository at this point in the history
… decode it, then ensure S/N is printable before storing it.

If S/N is not printable, hex encode it
  • Loading branch information
Didier LIROULET committed Aug 24, 2014
1 parent cb44cde commit 08242c6
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 3 deletions.
63 changes: 63 additions & 0 deletions OCSInventory Front/OcsUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,14 @@ BOOL OCSINVENTORYFRONT_API fileDigest( LPCTSTR lpstrFile, CString &csDigest, LPC
// Digest is hexadecimal encoded
return hex_encode( pDigest, uLength, csDigest);
}

BOOL OCSINVENTORYFRONT_API is_hex( LPCTSTR lpstrString)
{
DWORD_PTR dw;
TCHAR ch; // !!!

return (1 == _stscanf( lpstrString, TEXT("%x%c"), &dw, &ch));
}

BOOL OCSINVENTORYFRONT_API hex_encode( LPBYTE pBuffer, UINT uLength, CString &csHex)
{
Expand All @@ -422,6 +430,48 @@ BOOL OCSINVENTORYFRONT_API hex_encode( LPBYTE pBuffer, UINT uLength, CString &cs
}
return TRUE;
}

LPBYTE OCSINVENTORYFRONT_API hex_decode( CString csHex, UINT *uLength)
{
CString csBuffer;
INT_PTR i = 0;
BYTE x;
LPBYTE pBuffer;

*uLength = 0;
if ((pBuffer = (LPBYTE) malloc( sizeof(BYTE))) == NULL)
return NULL;
while(!csHex.IsEmpty() && (i<(csHex.GetLength()-2)))
{
csBuffer.Format( _T( "%c%c"), csHex.GetAt( i), csHex.GetAt( i+1));
_stscanf( csBuffer, _T( "%2X"), &x);
pBuffer[*uLength] = x;
*uLength++;
if ((pBuffer = (LPBYTE) realloc(pBuffer, (*uLength+1)*sizeof(BYTE))) == NULL)
{
*uLength = 0;
free( pBuffer);
return NULL;
}
i += 2;
}
pBuffer[*uLength] = 0;
return pBuffer;
}

BOOL OCSINVENTORYFRONT_API is_base64( CString myString)
{
TCHAR ch; // !!!
BOOL bIsB64CharOnly = TRUE;

for (int i=0; i<myString.GetLength(); i++)
{
ch = myString.GetAt(i);
if (((ch<'A') || (ch>'Z')) && ((ch<'a') || (ch>'z')) && ((ch='=') && (i>=myString.GetLength()-2)))
bIsB64CharOnly = FALSE;
}
return ((myString.GetLength() % 4) == 0) && bIsB64CharOnly;
}

/* A helper function for base64 encoding */
BOOL OCSINVENTORYFRONT_API base64_encode( LPBYTE pBuffer, UINT uLength, CString &csBase64)
Expand Down Expand Up @@ -507,3 +557,16 @@ LPBYTE OCSINVENTORYFRONT_API base64_decode( LPCTSTR lpstrBase64, UINT *uLength)
return NULL;
}
}

BOOL OCSINVENTORYFRONT_API is_printable( CString myString)
{
BOOL bPrintable = TRUE;
CStringA myAnsiString = GetAnsiFromUnicode( myString);

for (int i=0; i<myAnsiString.GetLength(); i++)
{
if (!isprint( myAnsiString.GetAt( i)))
bPrintable = FALSE;
}
return bPrintable;
}
13 changes: 13 additions & 0 deletions OCSInventory Front/OcsUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,27 @@ BOOL OCSINVENTORYFRONT_API WriteVoidToFile( LPCVOID lpVoid, UINT uLength, LPCTST
// Compute digest on a file, using algorithm lpstralgo, and return result encode in base64 or hexa
BOOL OCSINVENTORYFRONT_API fileDigest( LPCTSTR lpstrFile, CString &csDigest, LPCTSTR lpstrAlgo = _T( "sha1"), BOOL bBase64 = TRUE);

// Check wether a string is hex encoded or not
BOOL OCSINVENTORYFRONT_API is_hex( LPCTSTR lpstrString);

// Encode pBuffer (uLength bytes long) into hexadecimal, and put result into CString
BOOL OCSINVENTORYFRONT_API hex_encode( LPBYTE pBuffer, UINT uLength, CString &csHex);

// Decode CString hexadecimal encoded, and put result into a BYTE array of uLength elements
// You MUST free this pointer when no more needed
LPBYTE OCSINVENTORYFRONT_API hex_decode( CString &csHex, UINT *uLength);

// Check wether a string is base64 encoded or not
BOOL OCSINVENTORYFRONT_API is_base64( CString myString);

// Encode pBuffer (uLength bytes long) into base64, and put result into CString
BOOL OCSINVENTORYFRONT_API base64_encode( LPBYTE pBuffer, UINT uLength, CString &csBase64);

// Decode null terminated string, and put result into a BYTE array of uLength elements
// You MUST free this pointer when no more needed
LPBYTE OCSINVENTORYFRONT_API base64_decode( LPCTSTR lpstrBase64, UINT *uLength);

// Check wether a string is printable or not
BOOL OCSINVENTORYFRONT_API is_printable( CString myString);

#endif // _OCS_UTILS_H_INCLUDED_
86 changes: 85 additions & 1 deletion OcsWmi/OcsWmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ BOOL COcsWmi::DisconnectWMI()
}
}


BOOL COcsWmi::BeginEnumClassObject( LPCTSTR lpstrObject, LPCTSTR lpstrCondition)
{
ASSERT( m_pIWbemServices);
Expand Down Expand Up @@ -305,6 +304,36 @@ BOOL COcsWmi::CloseEnumClassObject()
}
}

INT_PTR COcsWmi::GetClassObjectLength( LPCTSTR lpstrProperty)
{
ASSERT( m_pClassObject);
ASSERT( lpstrProperty);

try
{
VARIANT pVal;
VariantInit(&pVal);
CIMTYPE pType;

VariantClear(&pVal);
m_hResult = m_pClassObject->Get( _bstr_t( lpstrProperty), 0L, &pVal, &pType, NULL);
if (SUCCEEDED( m_hResult))
{
COleVariant myObject;
CByteArray myBytes;
myObject.Attach( pVal);
myObject.GetByteArrayFromVariantArray( myBytes);
return myBytes.GetSize();
}
return 0;
}
catch (CException *pEx)
{
pEx->Delete();
m_hResult = WBEM_E_FAILED;
return 0;
}
}

LPCTSTR COcsWmi::GetClassObjectStringValue(LPCTSTR lpstrProperty)
{
Expand Down Expand Up @@ -446,6 +475,61 @@ BOOL COcsWmi::GetClassObjectVariantValue( LPCTSTR lpstrProperty, VARIANT &pVal)
}


INT_PTR COcsWmi::GetRefElementClassObjectLength( LPCTSTR lpstrRefElement, LPCTSTR lpstrProperty)
{
ASSERT( m_pClassObject);
ASSERT( lpstrRefElement);
ASSERT( lpstrProperty);

try
{
CString csObject;
VARIANT pVal;
VariantInit(&pVal);
CIMTYPE pType;
IWbemClassObject *pClassObject;
static INT_PTR iResult;

VariantClear(&pVal);
m_hResult = m_pClassObject->Get( _bstr_t( lpstrRefElement), 0L, &pVal, &pType, NULL);
if (FAILED( m_hResult))
return 0;
csObject = strCimValue( pVal, pType);
if (csObject.IsEmpty())
return 0;
m_hResult = m_pIWbemServices->GetObject( _bstr_t( csObject),
WBEM_FLAG_RETURN_WBEM_COMPLETE,
NULL,
&pClassObject,
NULL);
if (FAILED( m_hResult))
{
// pClassObject->Release();
return 0;
}
VariantClear(&pVal);
m_hResult = pClassObject->Get( _bstr_t( lpstrProperty), 0L, &pVal, &pType, NULL);
if (FAILED( m_hResult))
iResult = 0;
else
{
COleVariant myObject;
CByteArray myBytes;
myObject.Attach( pVal);
myObject.GetByteArrayFromVariantArray( myBytes);
iResult = myBytes.GetSize();
}
pClassObject->Release();
return iResult;
}
catch (CException *pEx)
{
pEx->Delete();
m_hResult = WBEM_E_FAILED;
return 0;
}
}

BOOL COcsWmi::GetRefElementClassObjectVariantValue( LPCTSTR lpstrRefElement, LPCTSTR lpstrProperty, VARIANT &pVal)
{
ASSERT( m_pClassObject);
Expand Down
4 changes: 4 additions & 0 deletions OcsWmi/OcsWmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class OCSWMI_API COcsWmi
BOOL MoveNextEnumClassObject();
BOOL CloseEnumClassObject();

// Get Length of data in object
INT_PTR GetClassObjectLength( LPCTSTR lpstrProperty);
INT_PTR GetRefElementClassObjectLength( LPCTSTR lpstrRefElement, LPCTSTR lpstrProperty);

// Get current enumerated object properties (or properties of an objet referenced by the current enumerated object)
LPCTSTR GetClassObjectStringValue( LPCTSTR lpstrProperty);
LPCTSTR GetRefElementClassObjectStringValue( LPCTSTR lpstrRefElement, LPCTSTR lpstrProperty);
Expand Down
46 changes: 44 additions & 2 deletions SysInfo/StoragePeripheral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void CStoragePeripheral::SetSN( LPCTSTR lpstrSN)
char myCar;

m_csSN.Empty();
if ((lpstrSN != NULL) && (_tcslen( lpstrSN) > STORAGE_MAX_LENGTH_SERIAL))
if (is_hex( lpstrSN))
{
// Each serial number character is coded in ASCII hexadecimal value using 2 bytes, so we have to decode it
for (size_t i=0; (i<STORAGE_MAX_LENGTH_SERIAL) && ((i*2)<_tcslen( lpstrSN)); i++)
Expand All @@ -158,10 +158,24 @@ void CStoragePeripheral::SetSN( LPCTSTR lpstrSN)
m_csSN.SetAt( i, m_csSN.GetAt( i+1));
m_csSN.SetAt( i+1, cPermute);
}
StrForSQL( m_csSN);
if (is_printable( m_csSN))
// Hex decode successfull
return;
}
else
// Not hex encoded (or hex decode failed), ensure printable
if (is_printable( lpstrSN))
// Serial length seems good, assume well formatted
m_csSN = lpstrSN;
else
{
// Not printable, hex encode it
m_csSN.Empty();
for (UINT uIndex = 0; uIndex<_tcslen(lpstrSN); uIndex++)
{
m_csSN.AppendFormat( _T( "%02x"), lpstrSN[uIndex]);
}
}
StrForSQL( m_csSN);
}

Expand Down Expand Up @@ -216,3 +230,31 @@ int CStoragePeripheral::operator==(CStoragePeripheral cObject) const
(m_csSN == cObject.GetSN()) &&
(m_csFirmware == cObject.GetFirmware()));
}

BOOL CStoragePeripheral::is_hex( LPCTSTR lpstrString)
{
DWORD_PTR dw;
TCHAR ch; // !!!

return (1 == _stscanf( lpstrString, TEXT("&#37;x%c"), &dw, &ch));
}

BOOL CStoragePeripheral::is_printable( CString myString)
{
BOOL bPrintable = TRUE;
static CStringA csAnsi;
CT2W pszA( myString);

// Convert to Ansi, and avoid producing "(null)" string we converting
if (!myString.IsEmpty() && (myString.GetLength() > 0))
csAnsi = pszA;
else
csAnsi.Empty();

for (int i=0; i<csAnsi.GetLength(); i++)
{
if (!isprint( csAnsi.GetAt( i)))
bPrintable = FALSE;
}
return bPrintable;
}
5 changes: 5 additions & 0 deletions SysInfo/StoragePeripheral.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ class SYSINFO_API CStoragePeripheral
//////////////////////////////////

int operator==( const CStoragePeripheral cObject) const;
private:
// Check wether a string is hex encoded or not
BOOL is_hex( LPCTSTR lpstrString);
// Check wether a string is printable or not
BOOL is_printable( CString myString);

protected: // Attributes
CString m_csType; // Storage type (floppy, disk, tape...)
Expand Down

0 comments on commit 08242c6

Please sign in to comment.