]>
Commit | Line | Data |
---|---|---|
a09a7e79 | 1 | /* |
b9b0fd4c | 2 | * Copyright (C) 2004-2011 See the AUTHORS file for details. |
a09a7e79 | 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 | */ | |
6dcacaa7 | 8 | |
538d3ece | 9 | #include "Utils.h" |
6249e41c | 10 | #include "MD5.h" |
03896135 | 11 | #include "main.h" |
ac5c021c | 12 | #include "ZNCDebug.h" |
29d8ef89 | 13 | #include <errno.h> |
46daeeba | 14 | #ifdef HAVE_LIBSSL |
15 | #include <openssl/ssl.h> | |
16 | #endif /* HAVE_LIBSSL */ | |
e72c4456 | 17 | #include <sstream> |
18 | #include <sys/stat.h> | |
19 | #include <sys/types.h> | |
20 | #include <unistd.h> | |
46daeeba | 21 | |
9e68cd35 | 22 | // Required with GCC 4.3+ if openssl is disabled |
23 | #include <cstring> | |
24 | #include <cstdlib> | |
25 | ||
538d3ece | 26 | using std::stringstream; |
27 | ||
28 | CUtils::CUtils() {} | |
29 | CUtils::~CUtils() {} | |
30 | ||
7627ea11 | 31 | #ifdef HAVE_LIBSSL |
b03f495b | 32 | void CUtils::GenerateCert(FILE *pOut, const CString& sHost) { |
0955474b | 33 | EVP_PKEY *pKey = NULL; |
34 | X509 *pCert = NULL; | |
35 | X509_NAME *pName = NULL; | |
1d88f564 | 36 | const int days = 365; |
a0f977d2 | 37 | const int years = 10; |
a26fdbdf | 38 | |
b0a1714b | 39 | u_int iSeed = time(NULL); |
40 | int serial = (rand_r(&iSeed) % 9999); | |
0955474b | 41 | |
3bbe5e7a | 42 | RSA *pRSA = RSA_generate_key(2048, 0x10001, NULL, NULL); |
b0a1714b | 43 | if ((pKey = EVP_PKEY_new())) { |
44 | if (!EVP_PKEY_assign_RSA(pKey, pRSA)) { | |
45 | EVP_PKEY_free(pKey); | |
0955474b | 46 | return; |
47 | } | |
7627ea11 | 48 | |
b03f495b | 49 | PEM_write_RSAPrivateKey(pOut, pRSA, NULL, NULL, 0, NULL, NULL); |
e233decc | 50 | |
c64d7bc1 | 51 | if (!(pCert = X509_new())) { |
b0a1714b | 52 | EVP_PKEY_free(pKey); |
0955474b | 53 | return; |
54 | } | |
7627ea11 | 55 | |
b0a1714b | 56 | X509_set_version(pCert, 2); |
57 | ASN1_INTEGER_set(X509_get_serialNumber(pCert), serial); | |
58 | X509_gmtime_adj(X509_get_notBefore(pCert), 0); | |
a0f977d2 | 59 | X509_gmtime_adj(X509_get_notAfter(pCert), (long)60*60*24*days*years); |
b0a1714b | 60 | X509_set_pubkey(pCert, pKey); |
f74ab87e | 61 | |
b0a1714b | 62 | pName = X509_get_subject_name(pCert); |
7627ea11 | 63 | |
bf171597 | 64 | const char *pLogName = getenv("LOGNAME"); |
65 | const char *pHostName = NULL; | |
66 | ||
67 | if (!sHost.empty()) { | |
68 | pHostName = sHost.c_str(); | |
69 | } | |
70 | ||
71 | if (!pHostName) { | |
72 | pHostName = getenv("HOSTNAME"); | |
73 | } | |
7627ea11 | 74 | |
0955474b | 75 | if (!pLogName) { |
76 | pLogName = "Unknown"; | |
77 | } | |
7627ea11 | 78 | |
0955474b | 79 | if (!pHostName) { |
dcf357b1 | 80 | pHostName = "host.unknown"; |
0955474b | 81 | } |
e57edc5a | 82 | |
0955474b | 83 | CString sEmailAddr = pLogName; |
84 | sEmailAddr += "@"; | |
85 | sEmailAddr += pHostName; | |
86 | ||
b0a1714b | 87 | X509_NAME_add_entry_by_txt(pName, "C", MBSTRING_ASC, (unsigned char *)"US", -1, -1, 0); |
88 | X509_NAME_add_entry_by_txt(pName, "ST", MBSTRING_ASC, (unsigned char *)"SomeState", -1, -1, 0); | |
89 | X509_NAME_add_entry_by_txt(pName, "L", MBSTRING_ASC, (unsigned char *)"SomeCity", -1, -1, 0); | |
90 | X509_NAME_add_entry_by_txt(pName, "O", MBSTRING_ASC, (unsigned char *)"SomeCompany", -1, -1, 0); | |
91 | X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, (unsigned char *)pLogName, -1, -1, 0); | |
92 | X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, (unsigned char *)pHostName, -1, -1, 0); | |
93 | X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, (unsigned char *)sEmailAddr.c_str(), -1, -1, 0); | |
0955474b | 94 | |
b0a1714b | 95 | X509_set_subject_name(pCert, pName); |
7c6e5bb8 | 96 | X509_set_issuer_name(pCert, pName); |
0955474b | 97 | |
3bbe5e7a | 98 | if (!X509_sign(pCert, pKey, EVP_sha1())) { |
b0a1714b | 99 | X509_free(pCert); |
100 | EVP_PKEY_free(pKey); | |
0955474b | 101 | return; |
102 | } | |
103 | ||
b0a1714b | 104 | PEM_write_X509(pOut, pCert); |
105 | X509_free(pCert); | |
106 | EVP_PKEY_free(pKey); | |
0955474b | 107 | } |
0a622749 | 108 | } |
7627ea11 | 109 | #endif /* HAVE_LIBSSL */ |
110 | ||
078bbcf0 | 111 | CString CUtils::GetIP(unsigned long addr) { |
538d3ece | 112 | char szBuf[16]; |
113 | memset((char*) szBuf, 0, 16); | |
114 | ||
115 | if (addr >= (1 << 24)) { | |
116 | unsigned long ip[4]; | |
117 | ip[0] = addr >> 24 & 255; | |
118 | ip[1] = addr >> 16 & 255; | |
119 | ip[2] = addr >> 8 & 255; | |
120 | ip[3] = addr & 255; | |
121 | sprintf(szBuf, "%lu.%lu.%lu.%lu", ip[0], ip[1], ip[2], ip[3]); | |
122 | } | |
123 | ||
124 | return szBuf; | |
125 | } | |
126 | ||
078bbcf0 | 127 | unsigned long CUtils::GetLongIP(const CString& sIP) { |
4e6c6fea | 128 | unsigned long ret; |
129 | char ip[4][4]; | |
f4618594 | 130 | unsigned int i; |
538d3ece | 131 | |
4e6c6fea | 132 | i = sscanf(sIP.c_str(), "%3[0-9].%3[0-9].%3[0-9].%3[0-9]", |
133 | ip[0], ip[1], ip[2], ip[3]); | |
134 | if (i != 4) | |
538d3ece | 135 | return 0; |
538d3ece | 136 | |
f4618594 | 137 | // Beware that atoi("200") << 24 would overflow and turn negative! |
138 | ret = atol(ip[0]) << 24; | |
139 | ret += atol(ip[1]) << 16; | |
140 | ret += atol(ip[2]) << 8; | |
141 | ret += atol(ip[3]) << 0; | |
4e6c6fea | 142 | |
143 | return ret; | |
538d3ece | 144 | } |
145 | ||
cd63bae0 | 146 | // If you change this here and in GetSaltedHashPass(), |
147 | // don't forget CUser::HASH_DEFAULT! | |
148 | const CString CUtils::sDefaultHash = "sha256"; | |
1c2c5265 | 149 | CString CUtils::GetSaltedHashPass(CString& sSalt) { |
150 | sSalt = GetSalt(); | |
bf2bd397 | 151 | |
152 | while (true) { | |
a3169af5 | 153 | CString pass1 = CUtils::GetPass("Enter Password"); |
154 | CString pass2 = CUtils::GetPass("Confirm Password"); | |
155 | ||
156 | if (!pass1.Equals(pass2, true)) { | |
bf2bd397 | 157 | CUtils::PrintError("The supplied passwords did not match"); |
a3169af5 | 158 | } else if (pass1.empty()) { |
bf2bd397 | 159 | CUtils::PrintError("You can not use an empty password"); |
160 | } else { | |
161 | // Construct the salted pass | |
cd63bae0 | 162 | return SaltedSHA256Hash(pass1, sSalt); |
bf2bd397 | 163 | } |
bf2bd397 | 164 | } |
bf2bd397 | 165 | } |
166 | ||
1c2c5265 | 167 | CString CUtils::GetSalt() { |
168 | return CString::RandomString(20); | |
169 | } | |
170 | ||
cd63bae0 | 171 | CString CUtils::SaltedMD5Hash(const CString& sPass, const CString& sSalt) { |
a3169af5 | 172 | return CString(sPass + sSalt).MD5(); |
173 | } | |
174 | ||
cd63bae0 | 175 | CString CUtils::SaltedSHA256Hash(const CString& sPass, const CString& sSalt) { |
176 | return CString(sPass + sSalt).SHA256(); | |
177 | } | |
178 | ||
7ab0b8d9 | 179 | CString CUtils::GetPass(const CString& sPrompt) { |
1873745f | 180 | PrintPrompt(sPrompt); |
2c6a54b6 PD |
181 | #ifdef HAVE_GETPASSPHRASE |
182 | return getpassphrase(""); | |
183 | #else | |
1873745f | 184 | return getpass(""); |
2c6a54b6 | 185 | #endif |
1873745f | 186 | } |
187 | ||
078bbcf0 | 188 | bool CUtils::GetBoolInput(const CString& sPrompt, bool bDefault) { |
c6eea2ae | 189 | return CUtils::GetBoolInput(sPrompt, &bDefault); |
190 | } | |
191 | ||
078bbcf0 | 192 | bool CUtils::GetBoolInput(const CString& sPrompt, bool *pbDefault) { |
193 | CString sRet, sDefault; | |
c6eea2ae | 194 | |
195 | if (pbDefault) { | |
196 | sDefault = (*pbDefault) ? "yes" : "no"; | |
197 | } | |
198 | ||
88a993a6 | 199 | while (true) { |
200 | GetInput(sPrompt, sRet, sDefault, "yes/no"); | |
e233decc | 201 | |
88a993a6 | 202 | if (sRet.Equals("y") || sRet.Equals("yes")) { |
203 | return true; | |
204 | } else if (sRet.Equals("n") || sRet.Equals("no")) { | |
205 | return false; | |
206 | } | |
e233decc | 207 | } |
e233decc | 208 | } |
209 | ||
078bbcf0 | 210 | bool CUtils::GetNumInput(const CString& sPrompt, unsigned int& uRet, unsigned int uMin, unsigned int uMax, unsigned int uDefault) { |
3abf4222 | 211 | if (uMin > uMax) { |
212 | return false; | |
213 | } | |
214 | ||
a9e60b43 | 215 | CString sDefault = (uDefault != (unsigned int) ~0) ? CString(uDefault) : ""; |
078bbcf0 | 216 | CString sNum, sHint; |
3abf4222 | 217 | |
218 | if (uMax != (unsigned int) ~0) { | |
a9e60b43 | 219 | sHint = CString(uMin) + " to " + CString(uMax); |
3abf4222 | 220 | } else if (uMin > 0) { |
a9e60b43 | 221 | sHint = CString(uMin) + " and up"; |
3abf4222 | 222 | } |
223 | ||
224 | while (true) { | |
225 | GetInput(sPrompt, sNum, sDefault, sHint); | |
226 | if (sNum.empty()) { | |
227 | return false; | |
228 | } | |
229 | ||
607a7f1c | 230 | uRet = sNum.ToUInt(); |
3abf4222 | 231 | |
232 | if ((uRet >= uMin && uRet <= uMax)) { | |
233 | break; | |
234 | } | |
235 | ||
236 | CUtils::PrintError("Number must be " + sHint); | |
237 | } | |
238 | ||
239 | return true; | |
240 | } | |
241 | ||
078bbcf0 | 242 | bool CUtils::GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault, const CString& sHint) { |
243 | CString sExtra; | |
ee620347 | 244 | CString sInput; |
3abf4222 | 245 | sExtra += (!sHint.empty()) ? (" (" + sHint + ")") : ""; |
246 | sExtra += (!sDefault.empty()) ? (" [" + sDefault + "]") : ""; | |
247 | ||
c6eea2ae | 248 | PrintPrompt(sPrompt + sExtra); |
e233decc | 249 | char szBuf[1024]; |
250 | memset(szBuf, 0, 1024); | |
e3683f20 | 251 | if (fgets(szBuf, 1024, stdin) == NULL) { |
252 | // Reading failed (Error? EOF?) | |
253 | PrintError("Error while reading from stdin. Exiting..."); | |
254 | exit(-1); | |
255 | } | |
ee620347 | 256 | sInput = szBuf; |
e233decc | 257 | |
ee620347 | 258 | if (sInput.Right(1) == "\n") { |
259 | sInput.RightChomp(); | |
e233decc | 260 | } |
261 | ||
ee620347 | 262 | if (sInput.empty()) { |
c6eea2ae | 263 | sRet = sDefault; |
ee620347 | 264 | } else { |
265 | sRet = sInput; | |
c6eea2ae | 266 | } |
267 | ||
e233decc | 268 | return !sRet.empty(); |
269 | } | |
270 | ||
078bbcf0 | 271 | void CUtils::PrintError(const CString& sMessage) { |
ac5c021c | 272 | if (CDebug::StdoutIsTTY()) |
74fb58cc | 273 | fprintf(stdout, "\033[1m\033[34m[\033[31m ** \033[34m]\033[39m\033[22m %s\n", sMessage.c_str()); |
274 | else | |
766d775f | 275 | fprintf(stdout, "%s\n", sMessage.c_str()); |
b665bd2b | 276 | fflush(stdout); |
1873745f | 277 | } |
278 | ||
078bbcf0 | 279 | void CUtils::PrintPrompt(const CString& sMessage) { |
ac5c021c | 280 | if (CDebug::StdoutIsTTY()) |
74fb58cc | 281 | fprintf(stdout, "\033[1m\033[34m[\033[33m ?? \033[34m]\033[39m\033[22m %s: ", sMessage.c_str()); |
282 | else | |
283 | fprintf(stdout, "[ ?? ] %s: ", sMessage.c_str()); | |
b665bd2b | 284 | fflush(stdout); |
a9d08422 | 285 | } |
286 | ||
078bbcf0 | 287 | void CUtils::PrintMessage(const CString& sMessage, bool bStrong) { |
ac5c021c | 288 | if (CDebug::StdoutIsTTY()) { |
74fb58cc | 289 | if (bStrong) |
290 | fprintf(stdout, "\033[1m\033[34m[\033[33m ** \033[34m]\033[39m\033[22m \033[1m%s\033[22m\n", | |
291 | sMessage.c_str()); | |
292 | else | |
293 | fprintf(stdout, "\033[1m\033[34m[\033[33m ** \033[34m]\033[39m\033[22m %s\n", | |
294 | sMessage.c_str()); | |
295 | } else | |
296 | fprintf(stdout, "%s\n", sMessage.c_str()); | |
b665bd2b | 297 | |
298 | fflush(stdout); | |
a9d08422 | 299 | } |
300 | ||
078bbcf0 | 301 | void CUtils::PrintAction(const CString& sMessage) { |
ac5c021c | 302 | if (CDebug::StdoutIsTTY()) |
74fb58cc | 303 | fprintf(stdout, "\033[1m\033[34m[\033[32m \033[34m]\033[39m\033[22m %s... ", sMessage.c_str()); |
304 | else | |
305 | fprintf(stdout, "%s... ", sMessage.c_str()); | |
a9d08422 | 306 | fflush(stdout); |
307 | } | |
308 | ||
078bbcf0 | 309 | void CUtils::PrintStatus(bool bSuccess, const CString& sMessage) { |
ac5c021c | 310 | if (CDebug::StdoutIsTTY()) { |
74fb58cc | 311 | if (!sMessage.empty()) { |
312 | if (bSuccess) { | |
313 | fprintf(stdout, "%s", sMessage.c_str()); | |
314 | } else { | |
315 | fprintf(stdout, "\033[1m\033[34m[\033[31m %s \033[34m]" | |
316 | "\033[39m\033[22m", sMessage.c_str()); | |
317 | } | |
1873745f | 318 | } |
a9d08422 | 319 | |
74fb58cc | 320 | fprintf(stdout, "\r"); |
a9d08422 | 321 | |
74fb58cc | 322 | if (bSuccess) { |
323 | fprintf(stdout, "\033[1m\033[34m[\033[32m ok \033[34m]\033[39m\033[22m\n"); | |
324 | } else { | |
325 | fprintf(stdout, "\033[1m\033[34m[\033[31m !! \033[34m]\033[39m\033[22m\n"); | |
326 | } | |
a9d08422 | 327 | } else { |
74fb58cc | 328 | if (bSuccess) { |
329 | fprintf(stdout, "%s\n", sMessage.c_str()); | |
330 | } else { | |
331 | if (!sMessage.empty()) { | |
332 | fprintf(stdout, "[ %s ]", sMessage.c_str()); | |
333 | } | |
334 | ||
766d775f | 335 | fprintf(stdout, "\n"); |
74fb58cc | 336 | } |
a9d08422 | 337 | } |
b665bd2b | 338 | |
339 | fflush(stdout); | |
a9d08422 | 340 | } |
341 | ||
078bbcf0 | 342 | bool CTable::AddColumn(const CString& sName) { |
538d3ece | 343 | for (unsigned int a = 0; a < m_vsHeaders.size(); a++) { |
5237a247 | 344 | if (m_vsHeaders[a].Equals(sName)) { |
538d3ece | 345 | return false; |
346 | } | |
347 | } | |
348 | ||
349 | m_vsHeaders.push_back(sName); | |
ec58e6f1 | 350 | m_msuWidths[sName] = sName.size(); |
351 | ||
538d3ece | 352 | return true; |
353 | } | |
354 | ||
355 | unsigned int CTable::AddRow() { | |
859c4ea1 | 356 | // Don't add a row if no headers are defined |
0b6c5cc1 | 357 | if (m_vsHeaders.empty()) { |
859c4ea1 | 358 | return (unsigned int) -1; |
359 | } | |
360 | ||
c0c563de | 361 | // Add a vector with enough space for each column |
362 | push_back(vector<CString>(m_vsHeaders.size())); | |
859c4ea1 | 363 | return size() - 1; |
538d3ece | 364 | } |
365 | ||
078bbcf0 | 366 | bool CTable::SetCell(const CString& sColumn, const CString& sValue, unsigned int uRowIdx) { |
538d3ece | 367 | if (uRowIdx == (unsigned int) ~0) { |
368 | if (!size()) { | |
369 | return false; | |
370 | } | |
371 | ||
372 | uRowIdx = size() -1; | |
373 | } | |
374 | ||
859c4ea1 | 375 | unsigned int uColIdx = GetColumnIndex(sColumn); |
376 | ||
377 | if (uColIdx == (unsigned int) -1) | |
378 | return false; | |
379 | ||
380 | (*this)[uRowIdx][uColIdx] = sValue; | |
ec58e6f1 | 381 | |
382 | if (m_msuWidths[sColumn] < sValue.size()) | |
383 | m_msuWidths[sColumn] = sValue.size(); | |
384 | ||
538d3ece | 385 | return true; |
386 | } | |
387 | ||
ec58e6f1 | 388 | bool CTable::GetLine(unsigned int uIdx, CString& sLine) const { |
538d3ece | 389 | stringstream ssRet; |
390 | ||
2ccafaf5 | 391 | if (empty()) { |
538d3ece | 392 | return false; |
393 | } | |
394 | ||
395 | if (uIdx == 1) { | |
538d3ece | 396 | ssRet.fill(' '); |
397 | ssRet << "| "; | |
398 | ||
399 | for (unsigned int a = 0; a < m_vsHeaders.size(); a++) { | |
400 | ssRet.width(GetColumnWidth(a)); | |
401 | ssRet << std::left << m_vsHeaders[a]; | |
402 | ssRet << ((a == m_vsHeaders.size() -1) ? " |" : " | "); | |
403 | } | |
404 | ||
405 | sLine = ssRet.str(); | |
406 | return true; | |
407 | } else if ((uIdx == 0) || (uIdx == 2) || (uIdx == (size() +3))) { | |
408 | ssRet.fill('-'); | |
409 | ssRet << "+-"; | |
410 | ||
411 | for (unsigned int a = 0; a < m_vsHeaders.size(); a++) { | |
412 | ssRet.width(GetColumnWidth(a)); | |
413 | ssRet << std::left << "-"; | |
414 | ssRet << ((a == m_vsHeaders.size() -1) ? "-+" : "-+-"); | |
415 | } | |
416 | ||
417 | sLine = ssRet.str(); | |
418 | return true; | |
419 | } else { | |
420 | uIdx -= 3; | |
421 | ||
422 | if (uIdx < size()) { | |
c0c563de | 423 | const vector<CString>& mRow = (*this)[uIdx]; |
538d3ece | 424 | ssRet.fill(' '); |
425 | ssRet << "| "; | |
426 | ||
427 | for (unsigned int c = 0; c < m_vsHeaders.size(); c++) { | |
428 | ssRet.width(GetColumnWidth(c)); | |
c0c563de | 429 | ssRet << std::left << mRow[c]; |
538d3ece | 430 | ssRet << ((c == m_vsHeaders.size() -1) ? " |" : " | "); |
431 | } | |
432 | ||
433 | sLine = ssRet.str(); | |
434 | return true; | |
435 | } | |
436 | } | |
437 | ||
438 | return false; | |
439 | } | |
440 | ||
c0c563de | 441 | unsigned int CTable::GetColumnIndex(const CString& sName) const { |
442 | for (unsigned int i = 0; i < m_vsHeaders.size(); i++) { | |
443 | if (m_vsHeaders[i] == sName) | |
444 | return i; | |
445 | } | |
446 | ||
235b10c2 | 447 | DEBUG("CTable::GetColumnIndex(" + sName + ") failed"); |
03896135 | 448 | |
859c4ea1 | 449 | return (unsigned int) -1; |
c0c563de | 450 | } |
451 | ||
ec58e6f1 | 452 | unsigned int CTable::GetColumnWidth(unsigned int uIdx) const { |
538d3ece | 453 | if (uIdx >= m_vsHeaders.size()) { |
454 | return 0; | |
455 | } | |
456 | ||
078bbcf0 | 457 | const CString& sColName = m_vsHeaders[uIdx]; |
ec58e6f1 | 458 | map<CString, unsigned int>::const_iterator it = m_msuWidths.find(sColName); |
538d3ece | 459 | |
ec58e6f1 | 460 | if (it == m_msuWidths.end()) { |
461 | // AddColumn() and SetCell() should make sure that we get a value :/ | |
462 | return 0; | |
538d3ece | 463 | } |
ec58e6f1 | 464 | return it->second; |
538d3ece | 465 | } |
466 | ||
273d72c6 | 467 | void CTable::Clear() { |
468 | clear(); | |
469 | m_vsHeaders.clear(); | |
470 | m_msuWidths.clear(); | |
471 | } | |
538d3ece | 472 | |
538d3ece | 473 | #ifdef HAVE_LIBSSL |
078bbcf0 | 474 | CBlowfish::CBlowfish(const CString & sPassword, int iEncrypt, const CString & sIvec) { |
538d3ece | 475 | m_iEncrypt = iEncrypt; |
476 | m_ivec = (unsigned char *)calloc(sizeof(unsigned char), 8); | |
477 | m_num = 0; | |
e233decc | 478 | |
538d3ece | 479 | if (sIvec.length() >= 8) { |
480 | memcpy(m_ivec, sIvec.data(), 8); | |
481 | } | |
482 | ||
483 | BF_set_key(&m_bkey, sPassword.length(), (unsigned char *)sPassword.data()); | |
484 | } | |
485 | ||
486 | CBlowfish::~CBlowfish() { | |
487 | free(m_ivec); | |
488 | } | |
489 | ||
490 | //! output must be freed | |
491 | unsigned char *CBlowfish::MD5(const unsigned char *input, u_int ilen) { | |
492 | unsigned char *output = (unsigned char *)malloc(MD5_DIGEST_LENGTH); | |
493 | ::MD5(input, ilen, output); | |
494 | return output; | |
495 | } | |
496 | ||
078bbcf0 | 497 | //! returns an md5 of the CString (not hex encoded) |
498 | CString CBlowfish::MD5(const CString & sInput, bool bHexEncode) { | |
499 | CString sRet; | |
538d3ece | 500 | unsigned char *data = MD5((const unsigned char *)sInput.data(), sInput.length()); |
e233decc | 501 | |
538d3ece | 502 | if (!bHexEncode) { |
503 | sRet.append((const char *)data, MD5_DIGEST_LENGTH); | |
504 | } else { | |
c64d7bc1 | 505 | for (int a = 0; a < MD5_DIGEST_LENGTH; a++) { |
538d3ece | 506 | sRet += g_HexDigits[data[a] >> 4]; |
507 | sRet += g_HexDigits[data[a] & 0xf]; | |
508 | } | |
509 | } | |
e233decc | 510 | |
538d3ece | 511 | free(data); |
512 | return sRet; | |
513 | } | |
514 | ||
515 | //! output must be the same size as input | |
516 | void CBlowfish::Crypt(unsigned char *input, unsigned char *output, u_int ibytes) { | |
517 | BF_cfb64_encrypt(input, output, ibytes, &m_bkey, m_ivec, &m_num, m_iEncrypt); | |
518 | } | |
519 | ||
520 | //! must free result | |
521 | unsigned char * CBlowfish::Crypt(unsigned char *input, u_int ibytes) { | |
522 | unsigned char *buff = (unsigned char *)malloc(ibytes); | |
523 | Crypt(input, buff, ibytes); | |
524 | return buff; | |
525 | } | |
e233decc | 526 | |
078bbcf0 | 527 | CString CBlowfish::Crypt(const CString & sData) { |
538d3ece | 528 | unsigned char *buff = Crypt((unsigned char *)sData.data(), sData.length()); |
078bbcf0 | 529 | CString sOutput; |
538d3ece | 530 | sOutput.append((const char *)buff, sData.length()); |
531 | free(buff); | |
532 | return sOutput; | |
533 | } | |
534 | ||
535 | #endif // HAVE_LIBSSL |