Hello,

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like =C3=A9, =C3=AB, or =E2=82=AC.so I also need to be able to =
get these
characters in my filter.

Below is the code that works for characters with ASCII values lower
than 127. Can anyone tell me what I need to do to get this working for
all characters?

I've been searching and puzzling for two days now and haven't gotten
any closer to how to solve this.

Any help will be appreciated.

Thanks in advance,
Sandra


=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

#include <windows.h>
#include <ntsecapi.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "PwdHookNew.h"
#include <sstream>
#include <string>

using namespace std;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

string GetASCIIString(string oristring)
{
unsigned char ch;

int i, j, k;
string numstrings;

ostringstream oss;

for(i=3D0;i<oristring.size();i++)
{
ch=3Doristring[i];
k =3D int(ch);

if (k<10)
{
oss << "000" << k << "-";
}
else if (k<100)
{
oss << "00" << k << "-";
}
else if(k<1000)
{
oss << "0" << k << "-";
}
else
{
oss << k << "-";
}
}
numstrings=3Doss.str();
oss.clear();

return numstrings;
}

NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
{
const char* timeStringFormat =3D "%Y-%m-%d_%H-%M-%S";
const int timeStringLength =3D 20;
char timeString[timeStringLength];

// get current date and time
time_t t =3D time(0);
tm *curTime =3D localtime(&t);

strftime(timeString, timeStringLength, timeStringFormat,
curTime);

char path[80];
strcpy (path,"C:\\pwds\\");
strcat (path,timeString);
strcat (path,".txt");

char *usernameStr, *passwordStr;

usernameStr =3D (char*)calloc(1, (UserName->Length/2)+1);
passwordStr =3D (char*)calloc(1, (Password->Length/2)+1);


wcstombs(usernameStr, UserName->Buffer, (UserName->Length/2));
wcstombs(passwordStr, Password->Buffer, (Password->Length/2));

char xmlmsg[150];
strcpy (xmlmsg,"<userpwd><username>");
strcat (xmlmsg,usernameStr);
strcat (xmlmsg,"</username><password>");
strcat (xmlmsg,passwordStr);
strcat (xmlmsg,"</password></userpwd>");

string xmlASCII =3D GetASCIIString(xmlmsg);

ofstream outPwd(path, ios::app);

if (!outPwd)
{
ofstream outPwd(path, ios::out );
}

outPwd << xmlASCII ;
outPwd.close();

return STATUS_SUCCESS;
}

Re: Get ASCII value for character when higher than 127 by Jochen

Jochen
Thu May 24 08:51:50 CDT 2007

Hi ssetz!
> By using the ascii values I am sure I can
> store special characters, also in a textfile.

Ascii values can never store special characters! Do you mean
"Unicode-values"?

> I got it working, but only when the password only contains characters
> that have an ASCII value lower than 127.


Ascii characters *never* contain values > 127!

> Below is the code that works for characters with ASCII values lower
> than 127. Can anyone tell me what I need to do to get this working for
> all characters?

Very simple: You must not use Ascii! Use Unicode (wchar_t)


Greetings
Jochen

Re: Get ASCII value for character when higher than 127 by Ben

Ben
Thu May 24 10:14:59 CDT 2007

Instead of wcstombs, use WideCharToMultiByte and CP_UTF8

http://msdn2.microsoft.com/en-us/library/ms776420.aspx

Also write the UTF byte order mark to the beginning of the file, so it will
be decoded correctly by other programs (eg Notepad)


<ssetz@wxs.nl> wrote in message
news:1180011654.065962.94870@k79g2000hse.googlegroups.com...
Hello,

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like é, ë, or ?.so I also need to be able to get these
characters in my filter.

Below is the code that works for characters with ASCII values lower
than 127. Can anyone tell me what I need to do to get this working for
all characters?

I've been searching and puzzling for two days now and haven't gotten
any closer to how to solve this.

Any help will be appreciated.

Thanks in advance,
Sandra


==================================================================

#include <windows.h>
#include <ntsecapi.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "PwdHookNew.h"
#include <sstream>
#include <string>

using namespace std;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

string GetASCIIString(string oristring)
{
unsigned char ch;

int i, j, k;
string numstrings;

ostringstream oss;

for(i=0;i<oristring.size();i++)
{
ch=oristring[i];
k = int(ch);

if (k<10)
{
oss << "000" << k << "-";
}
else if (k<100)
{
oss << "00" << k << "-";
}
else if(k<1000)
{
oss << "0" << k << "-";
}
else
{
oss << k << "-";
}
}
numstrings=oss.str();
oss.clear();

return numstrings;
}

NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
{
const char* timeStringFormat = "%Y-%m-%d_%H-%M-%S";
const int timeStringLength = 20;
char timeString[timeStringLength];

// get current date and time
time_t t = time(0);
tm *curTime = localtime(&t);

strftime(timeString, timeStringLength, timeStringFormat,
curTime);

char path[80];
strcpy (path,"C:\\pwds\\");
strcat (path,timeString);
strcat (path,".txt");

char *usernameStr, *passwordStr;

usernameStr = (char*)calloc(1, (UserName->Length/2)+1);
passwordStr = (char*)calloc(1, (Password->Length/2)+1);


wcstombs(usernameStr, UserName->Buffer, (UserName->Length/2));
wcstombs(passwordStr, Password->Buffer, (Password->Length/2));

char xmlmsg[150];
strcpy (xmlmsg,"<userpwd><username>");
strcat (xmlmsg,usernameStr);
strcat (xmlmsg,"</username><password>");
strcat (xmlmsg,passwordStr);
strcat (xmlmsg,"</password></userpwd>");

string xmlASCII = GetASCIIString(xmlmsg);

ofstream outPwd(path, ios::app);

if (!outPwd)
{
ofstream outPwd(path, ios::out );
}

outPwd << xmlASCII ;
outPwd.close();

return STATUS_SUCCESS;
}



Re: Get ASCII value for character when higher than 127 by ssetz

ssetz
Fri May 25 06:56:33 CDT 2007

On 24 mei, 17:14, "Ben Voigt" <r...@nospam.nospam> wrote:
> Instead of wcstombs, use WideCharToMultiByte and CP_UTF8
>
> http://msdn2.microsoft.com/en-us/library/ms776420.aspx
>
> Also write the UTF byte order mark to the beginning of the file, so it wi=
ll
> be decoded correctly by other programs (eg Notepad)

Thanks, this helped me further a bit. But I'm still not able to get
the correct int value for the special characters. For example, when I
reset a users password to the following:

=C3=A9Abc1=C6=92=C3=ABp$%^

The int values that are written to my textfile for the password file
are:

0-61-0-87-0065-0098-0099-0049-0-58--110-0-61-0-85-0112-

And this should be:

0130-0065-0098-0099-0049-0159-0137-0112-0036-0037-0094-

Any idea what it is I'm still doing wrong? My code now looks like
below.

Thanks again,
Sandra

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D

#include <windows.h>
#include <ntsecapi.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "PwdHookNew.h"
#include <sstream>
#include <string>
#include <iomanip>
#include <lm.h>

using namespace std;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

string GetASCIIString(string oristring)
{
bool test =3D true;
int i, k;
string numstrings;

ostringstream oss;
for(i=3D0;i<oristring.size();i++)
{
k =3D int(oristring[i]);
oss << setw(4) << setfill('0') << k << '-';
}
numstrings=3Doss.str();
oss.clear();

return numstrings;
}

NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
{
// ******************************************
// *** get filename ***
// ******************************************

const char* timeStringFormat =3D "%Y-%m-%d_%H-%M-%S";
const int timeStringLength =3D 20;
char timeString[timeStringLength];
time_t t =3D time(0);
tm *curTime =3D localtime(&t);
strftime(timeString, timeStringLength, timeStringFormat, curTime);

char path[80];
strcpy (path,"C:\\pwds\\");
strcat (path,timeString);
strcat (path,".txt");

// *******************************
// *** get pwd and user string ***
// *******************************

char *usernameStr, *passwordStr;

usernameStr =3D (char*)calloc(1, (UserName->Length/2)+1);
passwordStr =3D (char*)calloc(1, (Password->Length/2)+1);

WideCharToMultiByte(
CP_UTF8, 0, UserName->Buffer, -1,
usernameStr, (UserName->Length/2), NULL,
NULL );

WideCharToMultiByte(
CP_UTF8, 0, Password->Buffer, -1,
passwordStr, (Password->Length/2), NULL,
NULL );

char xmlmsg[200];
strcpy (xmlmsg,"<userpwd><username>");
strcat (xmlmsg,usernameStr);
strcat (xmlmsg,"</username><password>");
strcat (xmlmsg,passwordStr);
strcat (xmlmsg,"</password></userpwd>");

string asciiString =3D GetASCIIString(xmlmsg);

// ********************
// *** write output ***
// ********************

fstream outPwd(path, ios::app);
if (!outPwd)
{
fstream outPwd(path, ios::out );
}

outPwd << asciiString;

outPwd.close();

return STATUS_SUCCESS;
}


Re: Get ASCII value for character when higher than 127 by David

David
Fri May 25 10:45:56 CDT 2007

ssetz@wxs.nl wrote:
> On 24 mei, 17:14, "Ben Voigt" <r...@nospam.nospam> wrote:
>> Instead of wcstombs, use WideCharToMultiByte and CP_UTF8
>>
>> http://msdn2.microsoft.com/en-us/library/ms776420.aspx
>>
>> Also write the UTF byte order mark to the beginning of the file, so it will
>> be decoded correctly by other programs (eg Notepad)
>
> Thanks, this helped me further a bit. But I'm still not able to get
> the correct int value for the special characters. For example, when I
> reset a users password to the following:
>
> éAbc1Æ?ëp$%^
>
> The int values that are written to my textfile for the password file
> are:
>
> 0-61-0-87-0065-0098-0099-0049-0-58--110-0-61-0-85-0112-
>
> And this should be:
>
> 0130-0065-0098-0099-0049-0159-0137-0112-0036-0037-0094-
>
> Any idea what it is I'm still doing wrong? My code now looks like
> below.
>
> Thanks again,
> Sandra
>
> =========================================================
>
> #include <windows.h>
> #include <ntsecapi.h>
> #include <time.h>
> #include <fstream>
> #include <iostream>
> #include "PwdHookNew.h"
> #include <sstream>
> #include <string>
> #include <iomanip>
> #include <lm.h>
>
> using namespace std;
>
> #ifndef STATUS_SUCCESS
> #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
> #endif
>
> string GetASCIIString(string oristring)
> {
> bool test = true;
> int i, k;
> string numstrings;
>
> ostringstream oss;
> for(i=0;i<oristring.size();i++)
> {
> k = int(oristring[i]);
> oss << setw(4) << setfill('0') << k << '-';
> }
> numstrings=oss.str();
> oss.clear();
>
> return numstrings;
> }
>
> NTSTATUS
> NTAPI
> PasswordChangeNotify(
> PUNICODE_STRING UserName,
> ULONG RelativeId,
> PUNICODE_STRING Password
> )
> {
> // ******************************************
> // *** get filename ***
> // ******************************************
>
> const char* timeStringFormat = "%Y-%m-%d_%H-%M-%S";
> const int timeStringLength = 20;
> char timeString[timeStringLength];
> time_t t = time(0);
> tm *curTime = localtime(&t);
> strftime(timeString, timeStringLength, timeStringFormat, curTime);
>
> char path[80];
> strcpy (path,"C:\\pwds\\");
> strcat (path,timeString);
> strcat (path,".txt");
>
> // *******************************
> // *** get pwd and user string ***
> // *******************************
>
> char *usernameStr, *passwordStr;
>
> usernameStr = (char*)calloc(1, (UserName->Length/2)+1);
> passwordStr = (char*)calloc(1, (Password->Length/2)+1);
>
> WideCharToMultiByte(
> CP_UTF8, 0, UserName->Buffer, -1,
> usernameStr, (UserName->Length/2), NULL,
> NULL );
>
> WideCharToMultiByte(
> CP_UTF8, 0, Password->Buffer, -1,
> passwordStr, (Password->Length/2), NULL,
> NULL );
>
> char xmlmsg[200];
> strcpy (xmlmsg,"<userpwd><username>");
> strcat (xmlmsg,usernameStr);
> strcat (xmlmsg,"</username><password>");
> strcat (xmlmsg,passwordStr);
> strcat (xmlmsg,"</password></userpwd>");
>
> string asciiString = GetASCIIString(xmlmsg);
>
> // ********************
> // *** write output ***
> // ********************
>
> fstream outPwd(path, ios::app);
> if (!outPwd)
> {
> fstream outPwd(path, ios::out );
> }
>
> outPwd << asciiString;
>
> outPwd.close();
>
> return STATUS_SUCCESS;
> }

Sandra:

A few things I notice:

1. Why are you using Length/2 when converting to UTF-8? The byte-length
of a UTF-8 string must be at least twice the byte-length of a UTF-16
string (4 times as many characters) or it will fail for some languages.

2. You are not freeing userNameStr and passwordStr. I would use
std::vector<char> and pass pointer to first element to
WideCharToMultiByte().

3. You should always check the return value of WideCharToMultiByte().

4. Better to use std::ostringstream than fixed size buffer xmlmsg,
strcpy and strcat are very dangerous functions

5. I don't see immediately why your file output is not what you expect,
but why do you not just output the UTF-8 xml string to the file?

--
David Wilkinson
Visual C++ MVP

Re: Get ASCII value for character when higher than 127 by MrAsm

MrAsm
Fri May 25 15:25:50 CDT 2007

On Fri, 25 May 2007 10:45:56 -0500, David Wilkinson
<no-reply@effisols.com> wrote:


>> char path[80];
>> strcpy (path,"C:\\pwds\\");
>> strcat (path,timeString);
>> strcat (path,".txt");
>>

>> char xmlmsg[200];
>> strcpy (xmlmsg,"<userpwd><username>");
>> strcat (xmlmsg,usernameStr);
>> strcat (xmlmsg,"</username><password>");
>> strcat (xmlmsg,passwordStr);
>> strcat (xmlmsg,"</password></userpwd>");

>Sandra:
>
>A few things I notice:

To add to David's notes, I would deprecate the use of char buffer and
strcpy and strcat... better using std::ostringstream and operator <<
or at least the safe versions of str... functions (when you specify
the buffer size to avoid buffer overruns).

MrAsm

Re: Get ASCII value for character when higher than 127 by peter

peter
Sat May 26 11:25:46 CDT 2007

On 24 Maj, 15:51, "Jochen Kalmbach [MVP]" <nospam-
Jochen.Kalmb...@holzma.de> wrote:
> Hi ssetz!
>
> > By using the ascii values I am sure I can
> > store special characters, also in a textfile.
>
> Ascii values can never store special characters! Do you mean
> "Unicode-values"?
>
> > I got it working, but only when the password only contains characters
> > that have an ASCII value lower than 127.
>
> Ascii characters *never* contain values > 127!

Is this so? At least there is an option so you can choose between
having char signed or unsigned. So far as I remember, the C++ standard
has no requirement as the signedness of char.

/Peter


Re: Get ASCII value for character when higher than 127 by Barry

Barry
Sat May 26 12:15:48 CDT 2007

On 26 May 2007 09:25:46 -0700, peter koch
<peter.koch.larsen@gmail.com> wrote:

>On 24 Maj, 15:51, "Jochen Kalmbach [MVP]" <nospam-
>Jochen.Kalmb...@holzma.de> wrote:
>> Hi ssetz!
>>
>> > By using the ascii values I am sure I can
>> > store special characters, also in a textfile.
>>
>> Ascii values can never store special characters! Do you mean
>> "Unicode-values"?
>>
>> > I got it working, but only when the password only contains characters
>> > that have an ASCII value lower than 127.
>>
>> Ascii characters *never* contain values > 127!
>
>Is this so? At least there is an option so you can choose between
>having char signed or unsigned. So far as I remember, the C++ standard
>has no requirement as the signedness of char.

And the standard does not require a char to be only 8 bits wide. The
issue is not whether a char can hold a value greater than 127 but
whether the ASCII standard defines values above that limit.


Remove del for email

Re: Get ASCII value for character when higher than 127 by Jochen

Jochen
Sat May 26 14:12:30 CDT 2007

Hi peter!
>>Ascii characters *never* contain values > 127!
>
> Is this so? At least there is an option so you can choose between
> having char signed or unsigned. So far as I remember, the C++ standard
> has no requirement as the signedness of char.

C++ standard does not define ascii characters!
ISO defines ASCII which is in range 0x01 - 0x7f.
It does not matter if you use char, int, short wchar_t or whatever...
ascii will never contains such numbers outside of this range.
If it contains such numbers, then you do not have ascii.


--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/

Re: Get ASCII value for character when higher than 127 by ajk

ajk
Sun May 27 06:47:26 CDT 2007

On Sat, 26 May 2007 21:12:30 +0200, "Jochen Kalmbach [MVP]"
<nospam-Jochen.Kalmbach@holzma.de> wrote:

>Hi peter!
>>>Ascii characters *never* contain values > 127!
>>
>> Is this so? At least there is an option so you can choose between
>> having char signed or unsigned. So far as I remember, the C++ standard
>> has no requirement as the signedness of char.
>
>C++ standard does not define ascii characters!
>ISO defines ASCII which is in range 0x01 - 0x7f.
>It does not matter if you use char, int, short wchar_t or whatever...
>ascii will never contains such numbers outside of this range.
>If it contains such numbers, then you do not have ascii.

FWIW

http://en.wikipedia.org/wiki/ASCII

Re: Get ASCII value for character when higher than 127 by Jochen

Jochen
Sun May 27 10:51:46 CDT 2007

Hi ajk!

>>>>Ascii characters *never* contain values > 127!
>>>
>>>Is this so?
>>
>>C++ standard does not define ascii characters!
>>ISO defines ASCII which is in range 0x01 - 0x7f.
>>It does not matter if you use char, int, short wchar_t or whatever...
>>ascii will never contains such numbers outside of this range.
>>If it contains such numbers, then you do not have ascii.
>
>
> http://en.wikipedia.org/wiki/ASCII

Ok... the range is from 0x00 to 0x7f...

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/

Re: Get ASCII value for character when higher than 127 by peter

peter
Mon May 28 00:39:50 CDT 2007

On 26 Maj, 21:12, "Jochen Kalmbach [MVP]" <nospam-
Jochen.Kalmb...@holzma.de> wrote:
> Hi peter!
>
> >>Ascii characters *never* contain values > 127!
>
> > Is this so? At least there is an option so you can choose between
> > having char signed or unsigned. So far as I remember, the C++ standard
> > has no requirement as the signedness of char.
>
> C++ standard does not define ascii characters!
> ISO defines ASCII which is in range 0x01 - 0x7f.

While I do agree with you on this point, if you read the OP, you must
surely agree with me that the poster used the phrase "ASCII" in the
sense of the current 8-bit codepage. This is technically incorrect,
but very common and can probably be found also in Microsoft
documentation.


> It does not matter if you use char, int, short wchar_t or whatever...
> ascii will never contains such numbers outside of this range.
> If it contains such numbers, then you do not have ascii.

Of course. But the OP used a char to store "ASCII"-characters and
obviously had problems when those chars were negative.

/Peter


Re: Get ASCII value for character when higher than 127 by Ben

Ben
Mon May 28 10:04:56 CDT 2007

You're comparing a standard encoding (UTF-8), capable of storing *any*
character, to a useless encoding of your own choosing. What will you do
with a password containing Chinese characters? UTF-8 will handle it.

Stop trying to evaluate the stored data based on your expectations (should
be), and start evaluating it based on your requirements (should do). Can it
be decoded back to the original password? Does it store the password
efficiently? With UTF-8, the answer is yes and yes. Do you have a
requirement for compatibility with some other software? If so, you need to
tell us that.


<ssetz@wxs.nl> wrote in message
news:1180094193.382198.13330@k79g2000hse.googlegroups.com...
On 24 mei, 17:14, "Ben Voigt" <r...@nospam.nospam> wrote:
> Instead of wcstombs, use WideCharToMultiByte and CP_UTF8
>
> http://msdn2.microsoft.com/en-us/library/ms776420.aspx
>
> Also write the UTF byte order mark to the beginning of the file, so it
> will
> be decoded correctly by other programs (eg Notepad)

Thanks, this helped me further a bit. But I'm still not able to get
the correct int value for the special characters. For example, when I
reset a users password to the following:

éAbc1fëp$%^

The int values that are written to my textfile for the password file
are:

0-61-0-87-0065-0098-0099-0049-0-58--110-0-61-0-85-0112-

And this should be:

0130-0065-0098-0099-0049-0159-0137-0112-0036-0037-0094-

Any idea what it is I'm still doing wrong? My code now looks like
below.

Thanks again,
Sandra

=========================================================

#include <windows.h>
#include <ntsecapi.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "PwdHookNew.h"
#include <sstream>
#include <string>
#include <iomanip>
#include <lm.h>

using namespace std;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

string GetASCIIString(string oristring)
{
bool test = true;
int i, k;
string numstrings;

ostringstream oss;
for(i=0;i<oristring.size();i++)
{
k = int(oristring[i]);
oss << setw(4) << setfill('0') << k << '-';
}
numstrings=oss.str();
oss.clear();

return numstrings;
}

NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
{
// ******************************************
// *** get filename ***
// ******************************************

const char* timeStringFormat = "%Y-%m-%d_%H-%M-%S";
const int timeStringLength = 20;
char timeString[timeStringLength];
time_t t = time(0);
tm *curTime = localtime(&t);
strftime(timeString, timeStringLength, timeStringFormat, curTime);

char path[80];
strcpy (path,"C:\\pwds\\");
strcat (path,timeString);
strcat (path,".txt");

// *******************************
// *** get pwd and user string ***
// *******************************

char *usernameStr, *passwordStr;

usernameStr = (char*)calloc(1, (UserName->Length/2)+1);
passwordStr = (char*)calloc(1, (Password->Length/2)+1);

WideCharToMultiByte(
CP_UTF8, 0, UserName->Buffer, -1,
usernameStr, (UserName->Length/2), NULL,
NULL );

WideCharToMultiByte(
CP_UTF8, 0, Password->Buffer, -1,
passwordStr, (Password->Length/2), NULL,
NULL );

char xmlmsg[200];
strcpy (xmlmsg,"<userpwd><username>");
strcat (xmlmsg,usernameStr);
strcat (xmlmsg,"</username><password>");
strcat (xmlmsg,passwordStr);
strcat (xmlmsg,"</password></userpwd>");

string asciiString = GetASCIIString(xmlmsg);

// ********************
// *** write output ***
// ********************

fstream outPwd(path, ios::app);
if (!outPwd)
{
fstream outPwd(path, ios::out );
}

outPwd << asciiString;

outPwd.close();

return STATUS_SUCCESS;
}



Re: Get ASCII value for character when higher than 127 by ssetz

ssetz
Tue May 29 03:17:47 CDT 2007

Pfew, had no idea this thread would grow this big over a weekend ;-)

First, let me explain once more that I really don't know much about C+
+=2E I would prefer to not write this thing at all, but I'm afraid I
have to. And there's no way I can do it in C# unfortunately. Also is
this the first time I have to do something with character encoding, so
that doesn't help

The reason I want to store the int-values for the characters in stead
of the characters themselves is that I need to load the output in a C#
Windows Service, that will process the passwords further. Since I
store in a textfile, I was afraid that I would lose information, since
those characters with value higher than 127 don't show up in a text
file.

I also imagined, that if I have the int value, I can perform some
actions on those int values to have some sort of encryption (add some
numbers, multiply the number, etc)

I want my passwordfilter to be as small as possible, so the chance on
errors, memory leaks, etc is as small as possible. The filter will
eventually have to be installed on our Domain Controllers and we don't
want to hang them up or anything. Therefor I don't want to use any
encryption library, other third party code, etc.

So, my goal is to get an output (that is not readable at first glance)
that I can read in C# to further process the passwords and store them
well encrypted in a database.

But, I do get what you mean. I will first focus on what C# wants for
input to retrieve the special characters, than I will try to create
that input with C++.

Sorry for all these questions, but I really don't see me getting this
filter working on my own. So far, all the help is great, it really
helps me!!!!

Thanks,
Sandra


On 28 mei, 17:04, "Ben Voigt" <r...@nospam.nospam> wrote:
> You're comparing a standard encoding (UTF-8), capable of storing *any*
> character, to a useless encoding of your own choosing. What will you do
> with a password containing Chinese characters? UTF-8 will handle it.
>
> Stop trying to evaluate the stored data based on your expectations (should
> be), and start evaluating it based on your requirements (should do). Can=
it
> be decoded back to the original password? Does it store the password
> efficiently? With UTF-8, the answer is yes and yes. Do you have a
> requirement for compatibility with some other software? If so, you need =
to
> tell us that.
>
> <s...@wxs.nl> wrote in message
>
> news:1180094193.382198.13330@k79g2000hse.googlegroups.com...
> On 24 mei, 17:14, "Ben Voigt" <r...@nospam.nospam> wrote:
>
> > Instead of wcstombs, use WideCharToMultiByte and CP_UTF8
>
> >http://msdn2.microsoft.com/en-us/library/ms776420.aspx
>
> > Also write the UTF byte order mark to the beginning of the file, so it
> > will
> > be decoded correctly by other programs (eg Notepad)
>
> Thanks, this helped me further a bit. But I'm still not able to get
> the correct int value for the special characters. For example, when I
> reset a users password to the following:
>
> =E9Abc1f=EBp$%^
>
> The int values that are written to my textfile for the password file
> are:
>
> 0-61-0-87-0065-0098-0099-0049-0-58--110-0-61-0-85-0112-
>
> And this should be:
>
> 0130-0065-0098-0099-0049-0159-0137-0112-0036-0037-0094-
>
> Any idea what it is I'm still doing wrong? My code now looks like
> below.
>
> Thanks again,
> Sandra
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D
>
> #include <windows.h>
> #include <ntsecapi.h>
> #include <time.h>
> #include <fstream>
> #include <iostream>
> #include "PwdHookNew.h"
> #include <sstream>
> #include <string>
> #include <iomanip>
> #include <lm.h>
>
> using namespace std;
>
> #ifndef STATUS_SUCCESS
> #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
> #endif
>
> string GetASCIIString(string oristring)
> {
> bool test =3D true;
> int i, k;
> string numstrings;
>
> ostringstream oss;
> for(i=3D0;i<oristring.size();i++)
> {
> k =3D int(oristring[i]);
> oss << setw(4) << setfill('0') << k << '-';}
>
> numstrings=3Doss.str();
> oss.clear();
>
> return numstrings;
>
> }
>
> NTSTATUS
> NTAPI
> PasswordChangeNotify(
> PUNICODE_STRING UserName,
> ULONG RelativeId,
> PUNICODE_STRING Password
> )
> {
> // ******************************************
> // *** get filename ***
> // ******************************************
>
> const char* timeStringFormat =3D "%Y-%m-%d_%H-%M-%S";
> const int timeStringLength =3D 20;
> char timeString[timeStringLength];
> time_t t =3D time(0);
> tm *curTime =3D localtime(&t);
> strftime(timeString, timeStringLength, timeStringFormat, curTime);
>
> char path[80];
> strcpy (path,"C:\\pwds\\");
> strcat (path,timeString);
> strcat (path,".txt");
>
> // *******************************
> // *** get pwd and user string ***
> // *******************************
>
> char *usernameStr, *passwordStr;
>
> usernameStr =3D (char*)calloc(1, (UserName->Length/2)+1);
> passwordStr =3D (char*)calloc(1, (Password->Length/2)+1);
>
> WideCharToMultiByte(
> CP_UTF8, 0, UserName->Buffer, -1,
> usernameStr, (UserName->Length/2), NULL,
> NULL );
>
> WideCharToMultiByte(
> CP_UTF8, 0, Password->Buffer, -1,
> passwordStr, (Password->Length/2), NULL,
> NULL );
>
> char xmlmsg[200];
> strcpy (xmlmsg,"<userpwd><username>");
> strcat (xmlmsg,usernameStr);
> strcat (xmlmsg,"</username><password>");
> strcat (xmlmsg,passwordStr);
> strcat (xmlmsg,"</password></userpwd>");
>
> string asciiString =3D GetASCIIString(xmlmsg);
>
> // ********************
> // *** write output ***
> // ********************
>
> fstream outPwd(path, ios::app);
> if (!outPwd)
> {
> fstream outPwd(path, ios::out );
>
> }
>
> outPwd << asciiString;
>
> outPwd.close();
>
> return STATUS_SUCCESS;
>
>
>
> }- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -



Re: Get ASCII value for character when higher than 127 by ssetz

ssetz
Tue May 29 09:01:32 CDT 2007

Oke, I've decided to leave the int values be for a while and am now
trying to XOR the string that I write to an output file, and then in
C# I do the same XOR to get the original string back.

But, again, this works fine for normal characters, but not for the
special ones. This whole encoding stuff is starting to driving me
nuts!!!

In C++ I use the following XOR function before writing the output to
text:

string XOR(string value,string key)
{
string retval(value);

unsigned int klen=key.length();
unsigned int vlen=value.length();
unsigned int k=0;
unsigned int v=0;

for(v;v<vlen;v++)
{
retval[v]=value[v]^key[k];
k=(++k<klen?k:0);
}

return retval;
}

Then, in C#, I've implemented my XOR function as follows:

private string XOR(string encrypted, string key)
{
string retval = "";
char[] encryptArray = encrypted.ToCharArray();
char[] keyArray = key.ToCharArray();
char currentChar;
int encryptedLen = encryptArray.Length -1;
int keyLen = keyArray.Length -1;

int k = 0;

for (int i = 0; i < encryptedLen; i++)
{
currentChar = Convert.ToChar(encryptArray[i] ^
keyArray[k]);
retval += currentChar.ToString();
if (k < keyLen)
{
k++;
}
else
{
k = 0;
}
}
return retval;
}

Anyone here with both C++ and C# knowledge who can tell me why this is
not working??

Maybe I should go back to the int values after all :-(

Sandra


Re: Get ASCII value for character when higher than 127 by Ben

Ben
Tue May 29 08:59:08 CDT 2007

On the C# end, there is System.Text.Encoding.UTF8. If you read the data
into a C# byte[], and pass it to Encoding.UTF8.GetString, you should get
back the original string.



<ssetz@wxs.nl> wrote in message
news:1180426667.076469.123720@q69g2000hsb.googlegroups.com...
Pfew, had no idea this thread would grow this big over a weekend ;-)

First, let me explain once more that I really don't know much about C+
+. I would prefer to not write this thing at all, but I'm afraid I
have to. And there's no way I can do it in C# unfortunately. Also is
this the first time I have to do something with character encoding, so
that doesn't help

The reason I want to store the int-values for the characters in stead
of the characters themselves is that I need to load the output in a C#
Windows Service, that will process the passwords further. Since I
store in a textfile, I was afraid that I would lose information, since
those characters with value higher than 127 don't show up in a text
file.

I also imagined, that if I have the int value, I can perform some
actions on those int values to have some sort of encryption (add some
numbers, multiply the number, etc)

I want my passwordfilter to be as small as possible, so the chance on
errors, memory leaks, etc is as small as possible. The filter will
eventually have to be installed on our Domain Controllers and we don't
want to hang them up or anything. Therefor I don't want to use any
encryption library, other third party code, etc.

So, my goal is to get an output (that is not readable at first glance)
that I can read in C# to further process the passwords and store them
well encrypted in a database.

But, I do get what you mean. I will first focus on what C# wants for
input to retrieve the special characters, than I will try to create
that input with C++.

Sorry for all these questions, but I really don't see me getting this
filter working on my own. So far, all the help is great, it really
helps me!!!!

Thanks,
Sandra


On 28 mei, 17:04, "Ben Voigt" <r...@nospam.nospam> wrote:
> You're comparing a standard encoding (UTF-8), capable of storing *any*
> character, to a useless encoding of your own choosing. What will you do
> with a password containing Chinese characters? UTF-8 will handle it.
>
> Stop trying to evaluate the stored data based on your expectations (should
> be), and start evaluating it based on your requirements (should do). Can
> it
> be decoded back to the original password? Does it store the password
> efficiently? With UTF-8, the answer is yes and yes. Do you have a
> requirement for compatibility with some other software? If so, you need
> to
> tell us that.
>
> <s...@wxs.nl> wrote in message
>
> news:1180094193.382198.13330@k79g2000hse.googlegroups.com...
> On 24 mei, 17:14, "Ben Voigt" <r...@nospam.nospam> wrote:
>
> > Instead of wcstombs, use WideCharToMultiByte and CP_UTF8
>
> >http://msdn2.microsoft.com/en-us/library/ms776420.aspx
>
> > Also write the UTF byte order mark to the beginning of the file, so it
> > will
> > be decoded correctly by other programs (eg Notepad)
>
> Thanks, this helped me further a bit. But I'm still not able to get
> the correct int value for the special characters. For example, when I
> reset a users password to the following:
>
> éAbc1fëp$%^
>
> The int values that are written to my textfile for the password file
> are:
>
> 0-61-0-87-0065-0098-0099-0049-0-58--110-0-61-0-85-0112-
>
> And this should be:
>
> 0130-0065-0098-0099-0049-0159-0137-0112-0036-0037-0094-
>
> Any idea what it is I'm still doing wrong? My code now looks like
> below.
>
> Thanks again,
> Sandra
>
> =========================================================
>
> #include <windows.h>
> #include <ntsecapi.h>
> #include <time.h>
> #include <fstream>
> #include <iostream>
> #include "PwdHookNew.h"
> #include <sstream>
> #include <string>
> #include <iomanip>
> #include <lm.h>
>
> using namespace std;
>
> #ifndef STATUS_SUCCESS
> #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
> #endif
>
> string GetASCIIString(string oristring)
> {
> bool test = true;
> int i, k;
> string numstrings;
>
> ostringstream oss;
> for(i=0;i<oristring.size();i++)
> {
> k = int(oristring[i]);
> oss << setw(4) << setfill('0') << k << '-';}
>
> numstrings=oss.str();
> oss.clear();
>
> return numstrings;
>
> }
>
> NTSTATUS
> NTAPI
> PasswordChangeNotify(
> PUNICODE_STRING UserName,
> ULONG RelativeId,
> PUNICODE_STRING Password
> )
> {
> // ******************************************
> // *** get filename ***
> // ******************************************
>
> const char* timeStringFormat = "%Y-%m-%d_%H-%M-%S";
> const int timeStringLength = 20;
> char timeString[timeStringLength];
> time_t t = time(0);
> tm *curTime = localtime(&t);
> strftime(timeString, timeStringLength, timeStringFormat, curTime);
>
> char path[80];
> strcpy (path,"C:\\pwds\\");
> strcat (path,timeString);
> strcat (path,".txt");
>
> // *******************************
> // *** get pwd and user string ***
> // *******************************
>
> char *usernameStr, *passwordStr;
>
> usernameStr = (char*)calloc(1, (UserName->Length/2)+1);
> passwordStr = (char*)calloc(1, (Password->Length/2)+1);
>
> WideCharToMultiByte(
> CP_UTF8, 0, UserName->Buffer, -1,
> usernameStr, (UserName->Length/2), NULL,
> NULL );
>
> WideCharToMultiByte(
> CP_UTF8, 0, Password->Buffer, -1,
> passwordStr, (Password->Length/2), NULL,
> NULL );
>
> char xmlmsg[200];
> strcpy (xmlmsg,"<userpwd><username>");
> strcat (xmlmsg,usernameStr);
> strcat (xmlmsg,"</username><password>");
> strcat (xmlmsg,passwordStr);
> strcat (xmlmsg,"</password></userpwd>");
>
> string asciiString = GetASCIIString(xmlmsg);
>
> // ********************
> // *** write output ***
> // ********************
>
> fstream outPwd(path, ios::app);
> if (!outPwd)
> {
> fstream outPwd(path, ios::out );
>
> }
>
> outPwd << asciiString;
>
> outPwd.close();
>
> return STATUS_SUCCESS;
>
>
>
> }- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -




Re: Get ASCII value for character when higher than 127 by MrAsm

MrAsm
Tue May 29 09:41:39 CDT 2007

On 29 May 2007 07:01:32 -0700, ssetz@wxs.nl wrote:

Hi Sandra,

>But, again, this works fine for normal characters, but not for the
>special ones. This whole encoding stuff is starting to driving me
>nuts!!!

In this message you can find a function I wrote in C++ to convert
"Windows Unicode" strings (i.e. UTF-16 Unicode) to the UTF-8 Unicode.

The function prototype is:

std::string StringUnicodeToUTF8( const wchar_t * unicodeString )

it gets a Unicode (UTF-16) string as input, and returns a UTF-8
encoded string as output.

<Notes>
- The function may throw exceptions on errors.
- The "core" of this function is the ::WideCharToMultiByte Win32 API
</Notes>

You could use this function to convert your (Unicode) strings into
UTF-8, and write them into XML files.
e.g.:

<CODE language="C++">

// Your Unicode strings
// (e.g. read from edit controls or whatever...)
const wchar_t * UserName = L"MisterJohn_è";
const wchar_t * Password = L"èìé";

// I put some typical Italian characters (vowels with stress)
// inside the strings.
// I don't know if the newsgroup will show them correctly;
// you may try with your own characters and also Chinese
// characters, etc.


// The XML file header with UTF-8 encoding
const std::string xmlHeader =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>";


//
// Build the XML text into an output string stream
//
std::ostringstream xmlString;
xmlString << xmlHeader << std::endl;

xmlString << "<userdata>";

xmlString << "<username>" << StringUnicodeToUTF8( UserName )
<< "</username>" << std::endl;

xmlString << "<password>" << StringUnicodeToUTF8( Password )
<< "</password>" << std::endl;

xmlString << "</userdata>" << std::endl;


//
// Write content to "user.xml" file
//
std::ofstream xmlFile( "user.xml" );
xmlFile << xmlString.str();

</CODE>


You can read the XML file from C# using code like the following (it
reads username and password from the XML file):

<CODE language="C#">
// Clear user name and password
// (txtUserName and txtPassword are TextBox'es)
txtUserName.Text = "";
txtPassword.Text = "";

// Read data from XML file
XmlTextReader reader = new XmlTextReader( @"user.xml" );
while (reader.Read())
{
if ( (reader.NodeType == XmlNodeType.Element))
{
if (reader.LocalName.Equals("username"))
{
txtUserName.Text = reader.ReadString();
}
else if (reader.LocalName.Equals("password"))
{
txtPassword.Text = reader.ReadString();
}
}
}
</CODE>


If you want to "scramble" the input XML file on the C++ side using
XOR, you could do as follows:

<CODE language="C++">
//
// Crypt file using XOR
//

// xmlString is an std::ostringstream,
// containing the text of the XML file.
std::string originalFile = xmlString.str();

// Destination file
std::ofstream scrambledFile( "user.xml.crypt" );

// Key for XOR crypt
const char scrambleKey = 0x77;

// Scrambling loop
for ( std::string::const_iterator it = originalFile.begin();
it != originalFile.end(); ++it )
{
scrambledFile.put( (*it) ^ scrambleKey );
}
</CODE>


And to read it back and un-sramble from C#, you could use code like
this (consider that I'm not a C# expert, so maybe there could exist a
better C# code than what I developed here):

<CODE language="C#">
//
// Decrypt file
//

// Input file to un-scramble
FileStream inputFile = new FileStream(@"user.xml.crypt",
FileMode.Open);
BinaryReader inputReader = new BinaryReader(inputFile);


// Output file
FileStream outputFile = new FileStream(@"user.xml",
FileMode.Create);
BinaryWriter outputWriter = new BinaryWriter(outputFile);


// XOR key
const byte scrambleKey = 0x77;

// Un-scrambling loop
for (long i = 0; i < inputReader.BaseStream.Length; i++)
{
byte dataByte = inputReader.ReadByte();
dataByte ^= scrambleKey;
outputWriter.Write(dataByte);
}


// Close files

outputWriter.Close();
outputFile.Close();

inputReader.Close();
inputFile.Close();

</CODE>

And there is the main StringUnicodeToUTF8 function:


<CODE language="C++">

//
// Convert (encode) a Unicode UTF-16 string to Unicode UTF-8.
//
// by MrAsm
//
std::string StringUnicodeToUTF8( const wchar_t * unicodeString )
{
// Check input string pointer
if ( unicodeString == NULL )
throw std::invalid_argument(
"StringUnicodeToUTF8: Bad pointer" );


// Special case of empty string
if ( *unicodeString == L'\0' )
return "";

// One Unicode UTF-16 character may be converted
// up to four (4) UTF-8 characters.
const int lengthW = ::lstrlenW( unicodeString ) + 1;
const int lengthUtf8 = lengthW * 4;

// Buffer for UTF-8 string
std::vector< char > utf8Buffer;
utf8Buffer.resize( lengthUtf8 );


// Try converting from Unicode UTF-16 to UTF-8
if ( ::WideCharToMultiByte(
CP_UTF8, // Convert to UTF-8
0, // Default flags [not used]
unicodeString, // Pointer to Unicode string to be
// converted
lengthW, // Number of wide-chars in input string
// (including NUL terminator)
&utf8Buffer[0], // Pointer to buffer to receive the
// destination string
lengthUtf8, // Size, in bytes, of the destination
// buffer
NULL, // [default - not used]
NULL ) // [default - not used]
== 0 )
{
throw std::runtime_error(
"StringUnicodeToUTF8: Conversion failed." );
}

// Return the UTF-8 string
return std::string( &utf8Buffer[0] );
}

</CODE>

HTH,
MrAsm

Re: Get ASCII value for character when higher than 127 by ssetz

ssetz
Tue May 29 09:46:43 CDT 2007

On 29 mei, 15:59, "Ben Voigt" <r...@nospam.nospam> wrote:
> On the C# end, there is System.Text.Encoding.UTF8. If you read the data
> into a C# byte[], and pass it to Encoding.UTF8.GetString, you should get
> back the original string.

When I read the textfile as a bytearray and use UTF8.GetString, I get
the same result as when I use a StreamReader. My code:

foreach (string filename in
Directory.GetFiles(_config.PwdPath))
{
//1. read with StreamReader
StreamReader rdr = new StreamReader(filename);
string line = rdr.ReadToEnd();
rdr.Close();

line = line.Replace("\r\n", "\n");
string xmlcontent = XOR(line, "pwdhook");


//2. read as bytearray
FileInfo fi = new FileInfo(filename);
FileStream fs = fi.OpenRead();
int nBytes = (int)fi.Length+1;
byte[] ByteArray = new byte[nBytes];
int nBytesRead = fs.Read(ByteArray, 0, nBytes);

string line2 =
System.Text.Encoding.UTF8.GetString(ByteArray);
line2 = line2.Replace("\r\n", "\n");
string xmlcontent2 = XOR(line2, "pwdhook");
}

Should I do something with the textfile in C++, to make sure it is
interpreted as UTF8 or something like that? Again, here's the C++ code
I use to write the password stuff to a textfile:

fstream outPwd(path, ios::app);
if (!outPwd)
{
fstream outPwd(path, ios::out );
}

outPwd << xmlEncrypt;

outPwd.close();

I feel I'm getting closer to the solution with every tip I get here,
hopefully I'm there soon ;-)

Thanks again for all the help.

Sandra


Re: Get ASCII value for character when higher than 127 by MrAsm

MrAsm
Tue May 29 10:04:48 CDT 2007

On 29 May 2007 07:46:43 -0700, ssetz@wxs.nl wrote:


>Should I do something with the textfile in C++, to make sure it is
>interpreted as UTF8 or something like that?

Have you tried the:

std::string StringUnicodeToUTF8( const wchar_t * unicodeString )

from my other post?

I wrote XML with Unicode characters from C++ and read them back from
C# and everything was fine...

MrAsm

Re: Get ASCII value for character when higher than 127 by MrAsm

MrAsm
Tue May 29 10:56:23 CDT 2007

On 29 May 2007 07:01:32 -0700, ssetz@wxs