~vcs-imports-ii/znc/master

839 by psychon
Switch to the copyright headers the GPLv2 wants us to have
1
/*
2230 by psychon
Oh, shiny... NOT
2
 * Copyright (C) 2004-2011  See the AUTHORS file for details.
839 by psychon
Switch to the copyright headers the GPLv2 wants us to have
3
 *
4
 * This program is free software; you can redistribute it and/or modify it
5
 * under the terms of the GNU General Public License version 2 as published
6
 * by the Free Software Foundation.
7
 */
750 by prozacx
Added contact info
8
2 by prozacx
Initial revision
9
#include "Utils.h"
467 by prozacx
Renamed md5.cpp/h to MD5.cpp/h
10
#include "MD5.h"
1213 by psychon
Print warnings in CTable if you feed it with unknown columns
11
#include "main.h"
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
12
#include "ZNCDebug.h"
240 by prozacx
Added include for errno - thanks derblubbe
13
#include <errno.h>
86 by imaginos
fix compile errors
14
#ifdef HAVE_LIBSSL
15
#include <openssl/ssl.h>
16
#endif /* HAVE_LIBSSL */
910 by psychon
Clean up includes
17
#include <sstream>
18
#include <sys/stat.h>
19
#include <sys/types.h>
20
#include <unistd.h>
86 by imaginos
fix compile errors
21
1202 by psychon
Fix compilation with gcc 4.3.1 is ssl is disabled
22
// Required with GCC 4.3+ if openssl is disabled
23
#include <cstring>
24
#include <cstdlib>
25
2 by prozacx
Initial revision
26
using std::stringstream;
27
28
CUtils::CUtils() {}
29
CUtils::~CUtils() {}
30
85 by imaginos
added GenerateCert
31
#ifdef HAVE_LIBSSL
1481 by psychon
Remove znc --encrypt-pem
32
void CUtils::GenerateCert(FILE *pOut, const CString& sHost) {
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
33
	EVP_PKEY *pKey = NULL;
34
	X509 *pCert = NULL;
35
	X509_NAME *pName = NULL;
1756 by psychon
Fix a bunch of style suggestions from cppcheck[1]
36
	const int days = 365;
545 by imaginos
need to make a different serial on each generation
37
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
38
	u_int iSeed = time(NULL);
39
	int serial = (rand_r(&iSeed) % 9999);
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
40
1754 by psychon
Generate stronger certificates in --makepem
41
	RSA *pRSA = RSA_generate_key(2048, 0x10001, NULL, NULL);
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
42
	if ((pKey = EVP_PKEY_new())) {
43
		if (!EVP_PKEY_assign_RSA(pKey, pRSA)) {
44
			EVP_PKEY_free(pKey);
45
			return;
46
		}
47
1481 by psychon
Remove znc --encrypt-pem
48
		PEM_write_RSAPrivateKey(pOut, pRSA, NULL, NULL, 0, NULL, NULL);
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
49
1024 by psychon
Force a space between if, for, while and (
50
		if (!(pCert = X509_new())) {
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
51
			EVP_PKEY_free(pKey);
52
			return;
53
		}
54
55
		X509_set_version(pCert, 2);
56
		ASN1_INTEGER_set(X509_get_serialNumber(pCert), serial);
57
		X509_gmtime_adj(X509_get_notBefore(pCert), 0);
58
		X509_gmtime_adj(X509_get_notAfter(pCert), (long)60*60*24*days);
59
		X509_set_pubkey(pCert, pKey);
60
61
		pName = X509_get_subject_name(pCert);
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
62
556 by prozacx
Added prompt for pem file generation
63
		const char *pLogName = getenv("LOGNAME");
64
		const char *pHostName = NULL;
65
66
		if (!sHost.empty()) {
67
			pHostName = sHost.c_str();
68
		}
69
70
		if (!pHostName) {
71
			pHostName = getenv("HOSTNAME");
72
		}
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
73
74
		if (!pLogName) {
75
			pLogName = "Unknown";
76
		}
77
78
		if (!pHostName) {
2399 by Uli Schlachter
Stop asking for the host name in --makepem
79
			pHostName = "host.unknown";
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
80
		}
81
82
		CString sEmailAddr = pLogName;
83
		sEmailAddr += "@";
84
		sEmailAddr += pHostName;
85
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
86
		X509_NAME_add_entry_by_txt(pName, "C", MBSTRING_ASC, (unsigned char *)"US", -1, -1, 0);
87
		X509_NAME_add_entry_by_txt(pName, "ST", MBSTRING_ASC, (unsigned char *)"SomeState", -1, -1, 0);
88
		X509_NAME_add_entry_by_txt(pName, "L", MBSTRING_ASC, (unsigned char *)"SomeCity", -1, -1, 0);
89
		X509_NAME_add_entry_by_txt(pName, "O", MBSTRING_ASC, (unsigned char *)"SomeCompany", -1, -1, 0);
90
		X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, (unsigned char *)pLogName, -1, -1, 0);
91
		X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, (unsigned char *)pHostName, -1, -1, 0);
92
		X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, (unsigned char *)sEmailAddr.c_str(), -1, -1, 0);
93
94
		X509_set_subject_name(pCert, pName);
1713 by psychon
CUtils::GenerateCert(): Set the issuer name
95
		X509_set_issuer_name(pCert, pName);
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
96
1754 by psychon
Generate stronger certificates in --makepem
97
		if (!X509_sign(pCert, pKey, EVP_sha1())) {
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
98
			X509_free(pCert);
99
			EVP_PKEY_free(pKey);
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
100
			return;
101
		}
102
1023 by psychon
Remove useless spaces inside of braces "( stuff )"
103
		PEM_write_X509(pOut, pCert);
104
		X509_free(pCert);
105
		EVP_PKEY_free(pKey);
544 by imaginos
rewrite GenerateCert to work with browsers, some code reorganization with a different approach
106
	}
788 by prozacx
Committing patches from crox/psychon
107
}
85 by imaginos
added GenerateCert
108
#endif /* HAVE_LIBSSL */
109
245 by prozacx
Moved some more functions from CUtils into CString
110
CString CUtils::GetIP(unsigned long addr) {
2 by prozacx
Initial revision
111
	char szBuf[16];
112
	memset((char*) szBuf, 0, 16);
113
114
	if (addr >= (1 << 24)) {
115
		unsigned long ip[4];
116
		ip[0] = addr >> 24 & 255;
117
		ip[1] = addr >> 16 & 255;
118
		ip[2] = addr >> 8  & 255;
119
		ip[3] = addr       & 255;
120
		sprintf(szBuf, "%lu.%lu.%lu.%lu", ip[0], ip[1], ip[2], ip[3]);
121
	}
122
123
	return szBuf;
124
}
125
245 by prozacx
Moved some more functions from CUtils into CString
126
unsigned long CUtils::GetLongIP(const CString& sIP) {
1045 by psychon
Cleanup CUtils::GetLongIP()
127
	unsigned long ret;
128
	char ip[4][4];
1329 by psychon
Fix a bug where ZNC would fail to send out its own ip for DCC bouncing
129
	unsigned int i;
1045 by psychon
Cleanup CUtils::GetLongIP()
130
131
	i = sscanf(sIP.c_str(), "%3[0-9].%3[0-9].%3[0-9].%3[0-9]",
132
			ip[0], ip[1], ip[2], ip[3]);
133
	if (i != 4)
2 by prozacx
Initial revision
134
		return 0;
1045 by psychon
Cleanup CUtils::GetLongIP()
135
1329 by psychon
Fix a bug where ZNC would fail to send out its own ip for DCC bouncing
136
	// Beware that atoi("200") << 24 would overflow and turn negative!
137
	ret  = atol(ip[0]) << 24;
138
	ret += atol(ip[1]) << 16;
139
	ret += atol(ip[2]) << 8;
140
	ret += atol(ip[3]) << 0;
1045 by psychon
Cleanup CUtils::GetLongIP()
141
142
	return ret;
2 by prozacx
Initial revision
143
}
144
1601 by psychon
Add sha256 support
145
// If you change this here and in GetSaltedHashPass(),
146
// don't forget CUser::HASH_DEFAULT!
147
const CString CUtils::sDefaultHash = "sha256";
1130 by psychon
Make webadmin generate salted passwords, too
148
CString CUtils::GetSaltedHashPass(CString& sSalt) {
149
	sSalt = GetSalt();
1118 by psychon
Add supports for salted hashes to znc.conf
150
151
	while (true) {
1313 by psychon
Add CUtils::SaltedHash() for doing salted hashes and do some cleanup
152
		CString pass1 = CUtils::GetPass("Enter Password");
153
		CString pass2 = CUtils::GetPass("Confirm Password");
1118 by psychon
Add supports for salted hashes to znc.conf
154
1313 by psychon
Add CUtils::SaltedHash() for doing salted hashes and do some cleanup
155
		if (!pass1.Equals(pass2, true)) {
1118 by psychon
Add supports for salted hashes to znc.conf
156
			CUtils::PrintError("The supplied passwords did not match");
1313 by psychon
Add CUtils::SaltedHash() for doing salted hashes and do some cleanup
157
		} else if (pass1.empty()) {
1118 by psychon
Add supports for salted hashes to znc.conf
158
			CUtils::PrintError("You can not use an empty password");
159
		} else {
160
			// Construct the salted pass
1601 by psychon
Add sha256 support
161
			return SaltedSHA256Hash(pass1, sSalt);
1118 by psychon
Add supports for salted hashes to znc.conf
162
		}
163
	}
164
}
165
1130 by psychon
Make webadmin generate salted passwords, too
166
CString CUtils::GetSalt() {
167
	return CString::RandomString(20);
168
}
169
1601 by psychon
Add sha256 support
170
CString CUtils::SaltedMD5Hash(const CString& sPass, const CString& sSalt) {
1313 by psychon
Add CUtils::SaltedHash() for doing salted hashes and do some cleanup
171
	return CString(sPass + sSalt).MD5();
172
}
173
1601 by psychon
Add sha256 support
174
CString CUtils::SaltedSHA256Hash(const CString& sPass, const CString& sSalt) {
175
	return CString(sPass + sSalt).SHA256();
176
}
177
1332 by psychon
Make GetPass() return a CString instead of a char*
178
CString CUtils::GetPass(const CString& sPrompt) {
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
179
	PrintPrompt(sPrompt);
2342 by Paul Driver
passwords >8chars on Solaris, nitpicky solaris LIBS
180
#ifdef HAVE_GETPASSPHRASE
181
	return getpassphrase("");
182
#else
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
183
	return getpass("");
2342 by Paul Driver
passwords >8chars on Solaris, nitpicky solaris LIBS
184
#endif
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
185
}
186
245 by prozacx
Moved some more functions from CUtils into CString
187
bool CUtils::GetBoolInput(const CString& sPrompt, bool bDefault) {
203 by prozacx
Added default values for GetInput() and GetBoolInput()
188
	return CUtils::GetBoolInput(sPrompt, &bDefault);
189
}
190
245 by prozacx
Moved some more functions from CUtils into CString
191
bool CUtils::GetBoolInput(const CString& sPrompt, bool *pbDefault) {
192
	CString sRet, sDefault;
203 by prozacx
Added default values for GetInput() and GetBoolInput()
193
194
	if (pbDefault) {
195
		sDefault = (*pbDefault) ? "yes" : "no";
196
	}
197
1234 by kroimon
Add recognition for 'y' and 'n' to CUtils::GetBoolInput.
198
	while (true) {
199
		GetInput(sPrompt, sRet, sDefault, "yes/no");
200 by prozacx
Added GetInput() and GetBoolInput()
200
1234 by kroimon
Add recognition for 'y' and 'n' to CUtils::GetBoolInput.
201
		if (sRet.Equals("y") || sRet.Equals("yes")) {
202
			return true;
203
		} else if (sRet.Equals("n") || sRet.Equals("no")) {
204
			return false;
205
		}
200 by prozacx
Added GetInput() and GetBoolInput()
206
	}
207
}
208
245 by prozacx
Moved some more functions from CUtils into CString
209
bool CUtils::GetNumInput(const CString& sPrompt, unsigned int& uRet, unsigned int uMin, unsigned int uMax, unsigned int uDefault) {
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
210
	if (uMin > uMax) {
211
		return false;
212
	}
213
668 by prozacx
Migrated away from CString::ToString() in favor of explicit constructors
214
	CString sDefault = (uDefault != (unsigned int) ~0) ? CString(uDefault) : "";
245 by prozacx
Moved some more functions from CUtils into CString
215
	CString sNum, sHint;
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
216
217
	if (uMax != (unsigned int) ~0) {
668 by prozacx
Migrated away from CString::ToString() in favor of explicit constructors
218
		sHint = CString(uMin) + " to " + CString(uMax);
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
219
	} else if (uMin > 0) {
668 by prozacx
Migrated away from CString::ToString() in favor of explicit constructors
220
		sHint = CString(uMin) + " and up";
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
221
	}
222
223
	while (true) {
224
		GetInput(sPrompt, sNum, sDefault, sHint);
225
		if (sNum.empty()) {
226
			return false;
227
		}
228
1309 by psychon
Get rid of most strtoul() and atoi() calls and use CString's features instead
229
		uRet = sNum.ToUInt();
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
230
231
		if ((uRet >= uMin && uRet <= uMax)) {
232
			break;
233
		}
234
235
		CUtils::PrintError("Number must be " + sHint);
236
	}
237
238
	return true;
239
}
240
245 by prozacx
Moved some more functions from CUtils into CString
241
bool CUtils::GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault, const CString& sHint) {
242
	CString sExtra;
755 by prozacx
Patched using fix_GetInput.patch by x-x
243
	CString sInput;
208 by prozacx
Added GetNumInput() and sHint argument to GetInput
244
	sExtra += (!sHint.empty()) ? (" (" + sHint + ")") : "";
245
	sExtra += (!sDefault.empty()) ? (" [" + sDefault + "]") : "";
246
203 by prozacx
Added default values for GetInput() and GetBoolInput()
247
	PrintPrompt(sPrompt + sExtra);
200 by prozacx
Added GetInput() and GetBoolInput()
248
	char szBuf[1024];
249
	memset(szBuf, 0, 1024);
1102 by psychon
CUtils::GetInput(): Kill ZNC if reading from stdin fails
250
	if (fgets(szBuf, 1024, stdin) == NULL) {
251
		// Reading failed (Error? EOF?)
252
		PrintError("Error while reading from stdin. Exiting...");
253
		exit(-1);
254
	}
755 by prozacx
Patched using fix_GetInput.patch by x-x
255
	sInput = szBuf;
200 by prozacx
Added GetInput() and GetBoolInput()
256
755 by prozacx
Patched using fix_GetInput.patch by x-x
257
	if (sInput.Right(1) == "\n") {
258
		sInput.RightChomp();
200 by prozacx
Added GetInput() and GetBoolInput()
259
	}
260
755 by prozacx
Patched using fix_GetInput.patch by x-x
261
	if (sInput.empty()) {
203 by prozacx
Added default values for GetInput() and GetBoolInput()
262
		sRet = sDefault;
755 by prozacx
Patched using fix_GetInput.patch by x-x
263
	} else {
264
		sRet = sInput;
203 by prozacx
Added default values for GetInput() and GetBoolInput()
265
	}
266
200 by prozacx
Added GetInput() and GetBoolInput()
267
	return !sRet.empty();
268
}
269
245 by prozacx
Moved some more functions from CUtils into CString
270
void CUtils::PrintError(const CString& sMessage) {
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
271
	if (CDebug::StdoutIsTTY())
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
272
		fprintf(stdout, "\033[1m\033[34m[\033[31m ** \033[34m]\033[39m\033[22m %s\n", sMessage.c_str());
273
	else
1424 by silverleo
Remove some useless tags from a non-tty output.
274
		fprintf(stdout, "%s\n", sMessage.c_str());
362 by prozacx
Added some fflush() calls to output functions
275
	fflush(stdout);
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
276
}
277
245 by prozacx
Moved some more functions from CUtils into CString
278
void CUtils::PrintPrompt(const CString& sMessage) {
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
279
	if (CDebug::StdoutIsTTY())
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
280
		fprintf(stdout, "\033[1m\033[34m[\033[33m ?? \033[34m]\033[39m\033[22m %s: ", sMessage.c_str());
281
	else
282
		fprintf(stdout, "[ ?? ] %s: ", sMessage.c_str());
362 by prozacx
Added some fflush() calls to output functions
283
	fflush(stdout);
138 by prozacx
Added colorful printing functions
284
}
285
245 by prozacx
Moved some more functions from CUtils into CString
286
void CUtils::PrintMessage(const CString& sMessage, bool bStrong) {
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
287
	if (CDebug::StdoutIsTTY()) {
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
288
		if (bStrong)
289
			fprintf(stdout, "\033[1m\033[34m[\033[33m ** \033[34m]\033[39m\033[22m \033[1m%s\033[22m\n",
290
					sMessage.c_str());
291
		else
292
			fprintf(stdout, "\033[1m\033[34m[\033[33m ** \033[34m]\033[39m\033[22m %s\n",
293
					sMessage.c_str());
294
	} else
295
		fprintf(stdout, "%s\n", sMessage.c_str());
362 by prozacx
Added some fflush() calls to output functions
296
297
	fflush(stdout);
138 by prozacx
Added colorful printing functions
298
}
299
245 by prozacx
Moved some more functions from CUtils into CString
300
void CUtils::PrintAction(const CString& sMessage) {
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
301
	if (CDebug::StdoutIsTTY())
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
302
		fprintf(stdout, "\033[1m\033[34m[\033[32m    \033[34m]\033[39m\033[22m %s... ", sMessage.c_str());
303
	else
304
		fprintf(stdout, "%s... ", sMessage.c_str());
138 by prozacx
Added colorful printing functions
305
	fflush(stdout);
306
}
307
245 by prozacx
Moved some more functions from CUtils into CString
308
void CUtils::PrintStatus(bool bSuccess, const CString& sMessage) {
2330 by Uli Schlachter
Move DEBUG() from Utils.h into new ZNCDebug.h
309
	if (CDebug::StdoutIsTTY()) {
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
310
		if (!sMessage.empty()) {
311
			if (bSuccess) {
312
				fprintf(stdout, "%s", sMessage.c_str());
313
			} else {
314
				fprintf(stdout, "\033[1m\033[34m[\033[31m %s \033[34m]"
315
						"\033[39m\033[22m", sMessage.c_str());
316
			}
317
		}
318
319
		fprintf(stdout, "\r");
320
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
321
		if (bSuccess) {
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
322
			fprintf(stdout, "\033[1m\033[34m[\033[32m ok \033[34m]\033[39m\033[22m\n");
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
323
		} else {
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
324
			fprintf(stdout, "\033[1m\033[34m[\033[31m !! \033[34m]\033[39m\033[22m\n");
140 by prozacx
Added PrintPrompt() and GetPass() to CUtils
325
		}
138 by prozacx
Added colorful printing functions
326
	} else {
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
327
		if (bSuccess) {
328
			fprintf(stdout, "%s\n", sMessage.c_str());
329
		} else {
330
			if (!sMessage.empty()) {
331
				fprintf(stdout, "[ %s ]", sMessage.c_str());
332
			}
333
1424 by silverleo
Remove some useless tags from a non-tty output.
334
			fprintf(stdout, "\n");
921 by psychon
Add --no-color switch and only use escape sequences if isatty() says so
335
		}
138 by prozacx
Added colorful printing functions
336
	}
362 by prozacx
Added some fflush() calls to output functions
337
338
	fflush(stdout);
138 by prozacx
Added colorful printing functions
339
}
340
245 by prozacx
Moved some more functions from CUtils into CString
341
bool CTable::AddColumn(const CString& sName) {
2 by prozacx
Initial revision
342
	for (unsigned int a = 0; a < m_vsHeaders.size(); a++) {
1224 by kroimon
Use CString::Equals() everywhere.
343
		if (m_vsHeaders[a].Equals(sName)) {
2 by prozacx
Initial revision
344
			return false;
345
		}
346
	}
347
348
	m_vsHeaders.push_back(sName);
1151 by psychon
Some cleanup and optimizations to CTable
349
	m_msuWidths[sName] = sName.size();
350
2 by prozacx
Initial revision
351
	return true;
352
}
353
354
unsigned int CTable::AddRow() {
2010 by cflakes
Made CTable not crash if someone failed at coding at tries to
355
	// Don't add a row if no headers are defined
2012 by cflakes
Yay for pink invisible unicorns! yay!
356
	if (m_vsHeaders.empty()) {
2010 by cflakes
Made CTable not crash if someone failed at coding at tries to
357
		return (unsigned int) -1;
358
	}
359
1154 by psychon
Fix FTBFS with CTable on g++ 3
360
	// Add a vector with enough space for each column
361
	push_back(vector<CString>(m_vsHeaders.size()));
2010 by cflakes
Made CTable not crash if someone failed at coding at tries to
362
	return size() - 1;
2 by prozacx
Initial revision
363
}
364
245 by prozacx
Moved some more functions from CUtils into CString
365
bool CTable::SetCell(const CString& sColumn, const CString& sValue, unsigned int uRowIdx) {
2 by prozacx
Initial revision
366
	if (uRowIdx == (unsigned int) ~0) {
367
		if (!size()) {
368
			return false;
369
		}
370
371
		uRowIdx = size() -1;
372
	}
373
2010 by cflakes
Made CTable not crash if someone failed at coding at tries to
374
	unsigned int uColIdx = GetColumnIndex(sColumn);
375
376
	if (uColIdx == (unsigned int) -1)
377
		return false;
378
379
	(*this)[uRowIdx][uColIdx] = sValue;
1151 by psychon
Some cleanup and optimizations to CTable
380
381
	if (m_msuWidths[sColumn] < sValue.size())
382
		m_msuWidths[sColumn] = sValue.size();
383
2 by prozacx
Initial revision
384
	return true;
385
}
386
1151 by psychon
Some cleanup and optimizations to CTable
387
bool CTable::GetLine(unsigned int uIdx, CString& sLine) const {
2 by prozacx
Initial revision
388
	stringstream ssRet;
389
2257.1.3 by Uli Schlachter
Add CTable::empty
390
	if (empty()) {
2 by prozacx
Initial revision
391
		return false;
392
	}
393
394
	if (uIdx == 1) {
395
		ssRet.fill(' ');
396
		ssRet << "| ";
397
398
		for (unsigned int a = 0; a < m_vsHeaders.size(); a++) {
399
			ssRet.width(GetColumnWidth(a));
400
			ssRet << std::left << m_vsHeaders[a];
401
			ssRet << ((a == m_vsHeaders.size() -1) ? " |" : " | ");
402
		}
403
404
		sLine = ssRet.str();
405
		return true;
406
	} else if ((uIdx == 0) || (uIdx == 2) || (uIdx == (size() +3))) {
407
		ssRet.fill('-');
408
		ssRet << "+-";
409
410
		for (unsigned int a = 0; a < m_vsHeaders.size(); a++) {
411
			ssRet.width(GetColumnWidth(a));
412
			ssRet << std::left << "-";
413
			ssRet << ((a == m_vsHeaders.size() -1) ? "-+" : "-+-");
414
		}
415
416
		sLine = ssRet.str();
417
		return true;
418
	} else {
419
		uIdx -= 3;
420
421
		if (uIdx < size()) {
1154 by psychon
Fix FTBFS with CTable on g++ 3
422
			const vector<CString>& mRow = (*this)[uIdx];
2 by prozacx
Initial revision
423
			ssRet.fill(' ');
424
			ssRet << "| ";
425
426
			for (unsigned int c = 0; c < m_vsHeaders.size(); c++) {
427
				ssRet.width(GetColumnWidth(c));
1154 by psychon
Fix FTBFS with CTable on g++ 3
428
				ssRet << std::left << mRow[c];
2 by prozacx
Initial revision
429
				ssRet << ((c == m_vsHeaders.size() -1) ? " |" : " | ");
430
			}
431
432
			sLine = ssRet.str();
433
			return true;
434
		}
435
	}
436
437
	return false;
438
}
439
1154 by psychon
Fix FTBFS with CTable on g++ 3
440
unsigned int CTable::GetColumnIndex(const CString& sName) const {
441
	for (unsigned int i = 0; i < m_vsHeaders.size(); i++) {
442
		if (m_vsHeaders[i] == sName)
443
			return i;
444
	}
445
1338 by psychon
Use that new define everywhere
446
	DEBUG("CTable::GetColumnIndex(" + sName + ") failed");
1213 by psychon
Print warnings in CTable if you feed it with unknown columns
447
2010 by cflakes
Made CTable not crash if someone failed at coding at tries to
448
	return (unsigned int) -1;
1154 by psychon
Fix FTBFS with CTable on g++ 3
449
}
450
1151 by psychon
Some cleanup and optimizations to CTable
451
unsigned int CTable::GetColumnWidth(unsigned int uIdx) const {
2 by prozacx
Initial revision
452
	if (uIdx >= m_vsHeaders.size()) {
453
		return 0;
454
	}
455
245 by prozacx
Moved some more functions from CUtils into CString
456
	const CString& sColName = m_vsHeaders[uIdx];
1151 by psychon
Some cleanup and optimizations to CTable
457
	map<CString, unsigned int>::const_iterator it = m_msuWidths.find(sColName);
458
459
	if (it == m_msuWidths.end()) {
460
		// AddColumn() and SetCell() should make sure that we get a value :/
461
		return 0;
462
	}
463
	return it->second;
2 by prozacx
Initial revision
464
}
465
1220 by psychon
Add a Clear() function to CTable and make the base class protected
466
void CTable::Clear() {
467
	clear();
468
	m_vsHeaders.clear();
469
	m_msuWidths.clear();
470
}
2 by prozacx
Initial revision
471
472
#ifdef HAVE_LIBSSL
245 by prozacx
Moved some more functions from CUtils into CString
473
CBlowfish::CBlowfish(const CString & sPassword, int iEncrypt, const CString & sIvec) {
2 by prozacx
Initial revision
474
	m_iEncrypt = iEncrypt;
475
	m_ivec = (unsigned char *)calloc(sizeof(unsigned char), 8);
476
	m_num = 0;
200 by prozacx
Added GetInput() and GetBoolInput()
477
2 by prozacx
Initial revision
478
	if (sIvec.length() >= 8) {
479
		memcpy(m_ivec, sIvec.data(), 8);
480
	}
481
482
	BF_set_key(&m_bkey, sPassword.length(), (unsigned char *)sPassword.data());
483
}
484
485
CBlowfish::~CBlowfish() {
486
	free(m_ivec);
487
}
488
489
//! output must be freed
490
unsigned char *CBlowfish::MD5(const unsigned char *input, u_int ilen) {
491
	unsigned char *output = (unsigned char *)malloc(MD5_DIGEST_LENGTH);
492
	::MD5(input, ilen, output);
493
	return output;
494
}
495
245 by prozacx
Moved some more functions from CUtils into CString
496
//! returns an md5 of the CString (not hex encoded)
497
CString CBlowfish::MD5(const CString & sInput, bool bHexEncode) {
498
	CString sRet;
2 by prozacx
Initial revision
499
	unsigned char *data = MD5((const unsigned char *)sInput.data(), sInput.length());
200 by prozacx
Added GetInput() and GetBoolInput()
500
2 by prozacx
Initial revision
501
	if (!bHexEncode) {
502
		sRet.append((const char *)data, MD5_DIGEST_LENGTH);
503
	} else {
1024 by psychon
Force a space between if, for, while and (
504
		for (int a = 0; a < MD5_DIGEST_LENGTH; a++) {
2 by prozacx
Initial revision
505
			sRet += g_HexDigits[data[a] >> 4];
506
			sRet += g_HexDigits[data[a] & 0xf];
507
		}
508
	}
200 by prozacx
Added GetInput() and GetBoolInput()
509
2 by prozacx
Initial revision
510
	free(data);
511
	return sRet;
512
}
513
514
//! output must be the same size as input
515
void CBlowfish::Crypt(unsigned char *input, unsigned char *output, u_int ibytes) {
516
	BF_cfb64_encrypt(input, output, ibytes, &m_bkey, m_ivec, &m_num, m_iEncrypt);
517
}
518
519
//! must free result
520
unsigned char * CBlowfish::Crypt(unsigned char *input, u_int ibytes) {
521
	unsigned char *buff = (unsigned char *)malloc(ibytes);
522
	Crypt(input, buff, ibytes);
523
	return buff;
524
}
200 by prozacx
Added GetInput() and GetBoolInput()
525
245 by prozacx
Moved some more functions from CUtils into CString
526
CString CBlowfish::Crypt(const CString & sData) {
2 by prozacx
Initial revision
527
	unsigned char *buff = Crypt((unsigned char *)sData.data(), sData.length());
245 by prozacx
Moved some more functions from CUtils into CString
528
	CString sOutput;
2 by prozacx
Initial revision
529
	sOutput.append((const char *)buff, sData.length());
530
	free(buff);
531
	return sOutput;
532
}
533
534
#endif // HAVE_LIBSSL