summaryrefslogtreecommitdiffstats
path: root/ldap/synctools/passwordsync/passhand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/synctools/passwordsync/passhand.cpp')
-rw-r--r--ldap/synctools/passwordsync/passhand.cpp409
1 files changed, 354 insertions, 55 deletions
diff --git a/ldap/synctools/passwordsync/passhand.cpp b/ldap/synctools/passwordsync/passhand.cpp
index 56cd80ed..32de25bf 100644
--- a/ldap/synctools/passwordsync/passhand.cpp
+++ b/ldap/synctools/passwordsync/passhand.cpp
@@ -1,127 +1,426 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// Copyright (C) 2005 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
// Created: 2-8-2005
// Author(s): Scott Bridges
#include "passhand.h"
+#include <time.h>
+
+#define KEY {0xe8, 0xa7, 0x7c, 0xe2, 0x05, 0x63, 0x6a, 0x31}
+#define IV {0xe4, 0xbb, 0x3b, 0xd3, 0xc3, 0x71, 0x2e, 0x58}
+
+void timeStamp(fstream* outFile)
+{
+ if(outFile->is_open())
+ {
+ char dateBuf[32];
+ char timeBuf[32];
+
+ _strdate(dateBuf);
+ _strtime(timeBuf);
+ *outFile << dateBuf << " " << timeBuf << ": ";
+ }
+}
PasswordHandler::PasswordHandler()
{
+ outLog.open("./passhand.log", ios::out | ios::app);
}
PasswordHandler::~PasswordHandler()
{
+ outLog.close();
}
int PasswordHandler::SaveSet(char* filename)
{
+ int result = 0;
fstream outFile;
list<USER_PASS_PAIR>::iterator currentPair;
+ strstream plainTextStream;
+ char* cipherTextBuf;
+ int usernameLen;
+ int passwordLen;
+ int plainTextLen;
+ int cipherTextLen;
+ int resultTextLen = 0;
+ int pairCount = userPassPairs.size();
- outFile.open(filename, ios::out | ios::binary);
-
- if(!outFile.is_open())
+ if(outLog.is_open())
{
- return -1;
+ timeStamp(&outLog);
+ outLog << "SaveSet: saving " << userPassPairs.size() << " entries to file" << endl;
}
+ // Write usernames and passwords to a strstream
+ plainTextStream.write((char*)&pairCount, sizeof(pairCount));
for(currentPair = userPassPairs.begin(); currentPair != userPassPairs.end(); currentPair++)
{
- outFile.write((char*)&currentPair->username.Length, sizeof(currentPair->username.Length));
- outFile.write((char*)currentPair->username.Buffer, currentPair->username.Length);
+ // Usernames
+ usernameLen = strlen(currentPair->username) + 1;
+ plainTextStream.write((char*)&usernameLen, sizeof(usernameLen));
+ plainTextStream.write(currentPair->username, usernameLen);
+
+ // Passwords
+ passwordLen = strlen(currentPair->password) + 1;
+ plainTextStream.write((char*)&passwordLen, sizeof(passwordLen));
+ plainTextStream.write(currentPair->password, passwordLen);
+ }
+
+
+ plainTextLen = plainTextStream.tellp() - plainTextStream.tellg();
+ // cipherTextBuf length must be at least plainTextLen + 8
+ cipherTextLen = plainTextLen + 8;
+
+ cipherTextBuf = (char*)malloc(cipherTextLen);
- outFile.write((char*)&currentPair->password.Length, sizeof(currentPair->password.Length));
- outFile.write((char*)currentPair->password.Buffer, currentPair->password.Length);
+ if(encrypt(plainTextStream.str(), plainTextLen, cipherTextBuf, cipherTextLen, &resultTextLen) != 0)
+ {
+ result = -1;
+ goto exit;
}
- // ToDo: Zero out memory.
+ // Write cipher text to file
+ outFile.open(filename, ios::out | ios::binary);
+ if(!outFile.is_open())
+ {
+ result = -1;
+ goto exit;
+ }
+ outFile.write(cipherTextBuf, resultTextLen);
+ outFile.close();
+
+ // ToDo: zero out memory
+
userPassPairs.clear();
- return 0;
+exit:
+ return result;
}
int PasswordHandler::LoadSet(char* filename)
{
+ int result = 0;
+ int i;
fstream inFile;
USER_PASS_PAIR newPair;
-
- inFile.open(filename, ios::in | ios::binary);
+ strstream* plainTextStream;
+ char* cipherTextBuf;
+ char* plainTextBuf;
+ int usernameLen;
+ int passwordLen;
+ int plainTextLen;
+ int cipherTextLen;
+ int resultTextLen = 0;
+ int pairCount;
+ // Read in cipher text from file
+ inFile.open(filename, ios::in | ios::binary);
if(!inFile.is_open())
{
- return -1;
+ result = -1;
+ goto exit;
}
+ // Determine file size
+ inFile.seekg(0, ios::end);
+ cipherTextLen = inFile.tellg();
+ inFile.seekg(0, ios::beg);
+ // plainTextLen length must be at least cipherTextLen
+ plainTextLen = cipherTextLen;
+
+ cipherTextBuf = (char*)malloc(cipherTextLen);
+ plainTextBuf = (char*)malloc(plainTextLen);
- while(!inFile.eof())
+ inFile.read(cipherTextBuf, cipherTextLen);
+ inFile.close();
+
+ if(decrypt(cipherTextBuf, cipherTextLen, plainTextBuf, plainTextLen, &resultTextLen) != 0)
{
- inFile.read((char*)&newPair.username.Length, sizeof(newPair.username.Length));
- newPair.username.Buffer = (unsigned short*)malloc(newPair.username.Length);
- inFile.read((char*)newPair.username.Buffer, newPair.username.Length);
- newPair.username.MaximumLength = newPair.username.Length;
+ result = -1;
+ goto exit;
+ }
- inFile.read((char*)&newPair.password.Length, sizeof(newPair.password.Length));
- newPair.password.Buffer = (unsigned short*)malloc(newPair.password.Length);
- inFile.read((char*)newPair.password.Buffer, newPair.password.Length);
- newPair.password.MaximumLength = newPair.password.Length;
+ plainTextStream = new strstream(plainTextBuf, resultTextLen);
- if(!inFile.eof())
- {
- userPassPairs.push_back(newPair);
- }
+ plainTextStream->read((char*)&pairCount, sizeof(pairCount));
+
+ // Read usernames and passwords from a strstream
+ for(i = 0; i < pairCount; i++)
+ {
+ // Username
+ plainTextStream->read((char*)&usernameLen, sizeof(usernameLen));
+ newPair.username = (char*)malloc(usernameLen);
+ plainTextStream->read((char*)newPair.username, usernameLen);
+
+ // Password
+ plainTextStream->read((char*)&passwordLen, sizeof(passwordLen));
+ newPair.password = (char*)malloc(passwordLen);
+ plainTextStream->read((char*)newPair.password, passwordLen);
+
+ userPassPairs.push_back(newPair);
}
- return 0;
+ delete plainTextStream;
+
+ if(outLog.is_open())
+ {
+ timeStamp(&outLog);
+ outLog << "LoadSet: "<< userPassPairs.size() << " entries loaded from file" << endl;
+ }
+
+exit:
+ return result;
}
-int PasswordHandler::PushUserPass(PUNICODE_STRING username, PUNICODE_STRING password)
+int PasswordHandler::PushUserPass(char* username, char* password)
{
USER_PASS_PAIR newPair;
- newPair.username.Length = username->Length;
- newPair.username.Buffer = (unsigned short*)malloc(username->Length);
- memcpy(newPair.username.Buffer, username->Buffer, username->Length);
- newPair.username.MaximumLength = newPair.username.Length;
+ newPair.username = (char*)malloc(strlen(username) + 1);
+ strcpy(newPair.username, username);
- newPair.password.Length = password->Length;
- newPair.password.Buffer = (unsigned short*)malloc(password->Length);
- memcpy(newPair.password.Buffer, password->Buffer, password->Length);
- newPair.password.MaximumLength = newPair.password.Length;
+ newPair.password = (char*)malloc(strlen(password) + 1);
+ strcpy(newPair.password, password);
userPassPairs.push_back(newPair);
+ if(outLog.is_open())
+ {
+ timeStamp(&outLog);
+ outLog << "PushUserPass: pushed user password pair, new length " << userPassPairs.size() << endl;
+ }
+
return 0;
}
-int PasswordHandler::PeekUserPass(PUNICODE_STRING username, PUNICODE_STRING password)
+int PasswordHandler::PeekUserPass(char* username, char* password)
{
+ int result = 0;
list<USER_PASS_PAIR>::iterator currentPair;
- if(userPassPairs.size() == 0)
+ if(userPassPairs.size() < 1)
{
- return -1;
+ result = -1;
+ goto exit;
}
currentPair = userPassPairs.begin();
+ strcpy(username, currentPair->username);
+ strcpy(password, currentPair->password);
- username->Length = currentPair->username.Length;
- username->Buffer = (unsigned short*)malloc(username->Length);
- memcpy(username->Buffer, currentPair->username.Buffer, username->Length);
- username->MaximumLength = username->Length;
-
- password->Length = currentPair->password.Length;
- password->Buffer = (unsigned short*)malloc(password->Length);
- memcpy(password->Buffer, currentPair->password.Buffer, password->Length);
- password->MaximumLength = password->Length;
+ if(outLog.is_open())
+ {
+ timeStamp(&outLog);
+ outLog << "PeekUserPass: current length " << userPassPairs.size() << endl;
+ }
- return 0;
+exit:
+ return result;
}
int PasswordHandler::PopUserPass()
{
- // ToDo: Zero out memory.
+ // ToDo: zero out memory.
+
userPassPairs.pop_front();
+ if(outLog.is_open())
+ {
+ timeStamp(&outLog);
+ outLog << "PopUserPass: popped user password pair, new length " << userPassPairs.size() << endl;
+ }
+
return 0;
}
+
+
+int PasswordHandler::encrypt(char* plainTextBuf, int plainTextLen, char* cipherTextBuf, int cipherTextLen, int* resultTextLen)
+{
+ int result = 0;
+ SECStatus rv1, rv2, rv3;
+ PK11SlotInfo* slot = NULL;
+ PK11SymKey* SymKey = NULL;
+ SECItem* SecParam = NULL;
+ PK11Context* EncContext = NULL;
+ unsigned char gKey[] = KEY;
+ unsigned char gIV[] = IV;
+ PK11SymKey* key = NULL;
+ SECItem keyItem;
+ SECItem ivItem;
+ CK_MECHANISM_TYPE cipherMech = CKM_DES_CBC_PAD;
+ int offset;
+ int tempTextLen;
+
+ // Initialize NSS
+ rv1 = NSS_NoDB_Init(".");
+ if(rv1 != SECSuccess)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Get a key slot
+ slot = PK11_GetInternalKeySlot();
+ if(slot == NULL)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Generate a symmetric key
+ keyItem.data = gKey;
+ keyItem.len = sizeof(gKey);
+ SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
+ if(SymKey == NULL)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Set up the PKCS11 encryption paramters
+ ivItem.data = gIV;
+ ivItem.len = sizeof(gIV);
+ SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
+ if(SecParam == NULL)
+ {
+ if(SymKey != NULL)
+ {
+ PK11_FreeSymKey(SymKey);
+ }
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // ToDo: check parameters
+
+
+ // Encrypt
+ tempTextLen = 0;
+ EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, SymKey, SecParam);
+ rv2 = PK11_CipherOp(EncContext, (unsigned char*)cipherTextBuf, &tempTextLen, cipherTextLen, (unsigned char*)plainTextBuf, plainTextLen);
+ offset = tempTextLen;
+ rv3 = PK11_DigestFinal(EncContext, (unsigned char*)cipherTextBuf + offset, (unsigned int*)&tempTextLen, cipherTextLen - offset);
+ *resultTextLen = offset + tempTextLen;
+
+ // Clean up
+ PK11_DestroyContext(EncContext, PR_TRUE);
+ PK11_FreeSymKey(SymKey);
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+
+ if((rv2 != SECSuccess) || (rv2 != SECSuccess))
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+exit:
+ if(outLog.is_open())
+ {
+ if(result == 0)
+ {
+ timeStamp(&outLog);
+ outLog << "encrypt: success" << endl;
+ }
+ else
+ {
+ timeStamp(&outLog);
+ outLog << "encrypt: failure" << endl;
+ }
+ }
+
+ return result;
+}
+
+int PasswordHandler::decrypt(char* cipherTextBuf, int cipherTextLen, char* plainTextBuf, int plainTextLen, int* resultTextLen)
+{
+ int result = 0;
+ SECStatus rv1, rv2, rv3;
+ PK11SlotInfo* slot = NULL;
+ PK11SymKey* SymKey = NULL;
+ SECItem* SecParam = NULL;
+ PK11Context* EncContext = NULL;
+ unsigned char gKey[] = KEY;
+ unsigned char gIV[] = IV;
+ PK11SymKey* key = NULL;
+ SECItem keyItem;
+ SECItem ivItem;
+ CK_MECHANISM_TYPE cipherMech = CKM_DES_CBC_PAD;
+ int offset;
+ int tempTextLen;
+
+ // Initialize NSS
+ rv1 = NSS_NoDB_Init(".");
+ if(rv1 != SECSuccess)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Get a key slot
+ slot = PK11_GetInternalKeySlot();
+ if(slot == NULL)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Generate a symmetric key
+ keyItem.data = gKey;
+ keyItem.len = sizeof(gKey);
+ SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
+ if(SymKey == NULL)
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // Set up the PKCS11 encryption paramters
+ ivItem.data = gIV;
+ ivItem.len = sizeof(gIV);
+ SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
+ if(SecParam == NULL)
+ {
+ if(SymKey != NULL)
+ {
+ PK11_FreeSymKey(SymKey);
+ }
+ result = PR_GetError();
+ goto exit;
+ }
+
+ // ToDo: check parameters
+
+
+ // Decrypt
+ tempTextLen = 0;
+ EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_DECRYPT, SymKey, SecParam);
+ rv2 = PK11_CipherOp(EncContext, (unsigned char*)plainTextBuf, &tempTextLen, plainTextLen, (unsigned char*)cipherTextBuf, cipherTextLen);
+ offset = tempTextLen;
+ rv3 = PK11_DigestFinal(EncContext, (unsigned char*)plainTextBuf + offset, (unsigned int*)&tempTextLen, plainTextLen - offset);
+ *resultTextLen = offset + tempTextLen;
+
+ // Clean up
+ PK11_DestroyContext(EncContext, PR_TRUE);
+ PK11_FreeSymKey(SymKey);
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+
+ if((rv2 != SECSuccess) || (rv2 != SECSuccess))
+ {
+ result = PR_GetError();
+ goto exit;
+ }
+
+exit:
+ if(outLog.is_open())
+ {
+ if(result == 0)
+ {
+ timeStamp(&outLog);
+ outLog << "decrypt: success" << endl;
+ }
+ else
+ {
+ timeStamp(&outLog);
+ outLog << "decrypt: failure" << endl;
+ }
+ }
+
+ return result;
+}