You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SSecurityRSAAES.cxx 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. /* Copyright (C) 2022 Dinglan Peng
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #ifndef HAVE_NETTLE
  22. #error "This source should not be compiled without HAVE_NETTLE defined"
  23. #endif
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <assert.h>
  27. #include <nettle/bignum.h>
  28. #include <nettle/sha1.h>
  29. #include <nettle/sha2.h>
  30. #include <nettle/base64.h>
  31. #include <nettle/asn1.h>
  32. #include <rfb/SSecurityRSAAES.h>
  33. #include <rfb/SConnection.h>
  34. #include <rfb/LogWriter.h>
  35. #include <rfb/Exception.h>
  36. #include <rdr/AESInStream.h>
  37. #include <rdr/AESOutStream.h>
  38. #if !defined(WIN32) && !defined(__APPLE__)
  39. #include <rfb/UnixPasswordValidator.h>
  40. #endif
  41. #ifdef WIN32
  42. #include <rfb/WinPasswdValidator.h>
  43. #endif
  44. #include <rfb/SSecurityVncAuth.h>
  45. enum {
  46. SendPublicKey,
  47. ReadPublicKey,
  48. ReadRandom,
  49. ReadHash,
  50. ReadCredentials,
  51. };
  52. const int MinKeyLength = 1024;
  53. const int MaxKeyLength = 8192;
  54. const size_t MaxKeyFileSize = 32 * 1024;
  55. using namespace rfb;
  56. StringParameter SSecurityRSAAES::keyFile
  57. ("RSAKey", "Path to the RSA key for the RSA-AES security types in "
  58. "PEM format", "", ConfServer);
  59. BoolParameter SSecurityRSAAES::requireUsername
  60. ("RequireUsername", "Require username for the RSA-AES security types",
  61. false, ConfServer);
  62. SSecurityRSAAES::SSecurityRSAAES(SConnection* sc, rdr::U32 _secType,
  63. int _keySize, bool _isAllEncrypted)
  64. : SSecurity(sc), state(SendPublicKey),
  65. keySize(_keySize), isAllEncrypted(_isAllEncrypted), secType(_secType),
  66. serverKey(), clientKey(),
  67. serverKeyN(NULL), serverKeyE(NULL), clientKeyN(NULL), clientKeyE(NULL),
  68. accessRights(SConnection::AccessDefault),
  69. rais(NULL), raos(NULL), rawis(NULL), rawos(NULL)
  70. {
  71. assert(keySize == 128 || keySize == 256);
  72. }
  73. SSecurityRSAAES::~SSecurityRSAAES()
  74. {
  75. cleanup();
  76. }
  77. void SSecurityRSAAES::cleanup()
  78. {
  79. if (serverKeyN)
  80. delete[] serverKeyN;
  81. if (serverKeyE)
  82. delete[] serverKeyE;
  83. if (clientKeyN)
  84. delete[] clientKeyN;
  85. if (clientKeyE)
  86. delete[] clientKeyE;
  87. if (serverKey.size)
  88. rsa_private_key_clear(&serverKey);
  89. if (clientKey.size)
  90. rsa_public_key_clear(&clientKey);
  91. if (isAllEncrypted && rawis && rawos)
  92. sc->setStreams(rawis, rawos);
  93. if (rais)
  94. delete rais;
  95. if (raos)
  96. delete raos;
  97. }
  98. static inline ssize_t findSubstr(rdr::U8* data, size_t size, const char *pattern)
  99. {
  100. size_t patternLength = strlen(pattern);
  101. for (size_t i = 0; i + patternLength < size; ++i) {
  102. for (size_t j = 0; j < patternLength; ++j)
  103. if (data[i + j] != pattern[j])
  104. goto next;
  105. return i;
  106. next:
  107. continue;
  108. }
  109. return -1;
  110. }
  111. static bool loadPEM(rdr::U8* data, size_t size, const char *begin,
  112. const char *end, rdr::U8** der, size_t *derSize)
  113. {
  114. ssize_t pos1 = findSubstr(data, size, begin);
  115. if (pos1 == -1)
  116. return false;
  117. pos1 += strlen(begin);
  118. ssize_t base64Size = findSubstr(data + pos1, size - pos1, end);
  119. if (base64Size == -1)
  120. return false;
  121. char *derBase64 = (char *)data + pos1;
  122. if (!base64Size)
  123. return false;
  124. *der = new rdr::U8[BASE64_DECODE_LENGTH(base64Size)];
  125. struct base64_decode_ctx ctx;
  126. base64_decode_init(&ctx);
  127. if (!base64_decode_update(&ctx, derSize, *der, base64Size, derBase64))
  128. return false;
  129. if (!base64_decode_final(&ctx))
  130. return false;
  131. return true;
  132. }
  133. void SSecurityRSAAES::loadPrivateKey()
  134. {
  135. FILE* file = fopen(keyFile.getData(), "rb");
  136. if (!file)
  137. throw ConnFailedException("failed to open key file");
  138. fseek(file, 0, SEEK_END);
  139. size_t size = ftell(file);
  140. if (size == 0 || size > MaxKeyFileSize) {
  141. fclose(file);
  142. throw ConnFailedException("size of key file is zero or too big");
  143. }
  144. fseek(file, 0, SEEK_SET);
  145. rdr::U8Array data(size);
  146. if (fread(data.buf, 1, size, file) != size) {
  147. fclose(file);
  148. throw ConnFailedException("failed to read key");
  149. }
  150. fclose(file);
  151. rdr::U8Array der;
  152. size_t derSize;
  153. if (loadPEM(data.buf, size, "-----BEGIN RSA PRIVATE KEY-----\n",
  154. "-----END RSA PRIVATE KEY-----", &der.buf, &derSize)) {
  155. loadPKCS1Key(der.buf, derSize);
  156. return;
  157. }
  158. if (der.buf)
  159. delete[] der.takeBuf();
  160. if (loadPEM(data.buf, size, "-----BEGIN PRIVATE KEY-----\n",
  161. "-----END PRIVATE KEY-----", &der.buf, &derSize)) {
  162. loadPKCS8Key(der.buf, derSize);
  163. return;
  164. }
  165. throw ConnFailedException("failed to import key");
  166. }
  167. void SSecurityRSAAES::loadPKCS1Key(const rdr::U8* data, size_t size)
  168. {
  169. struct rsa_public_key pub;
  170. rsa_private_key_init(&serverKey);
  171. rsa_public_key_init(&pub);
  172. if (!rsa_keypair_from_der(&pub, &serverKey, 0, size, data)) {
  173. rsa_private_key_clear(&serverKey);
  174. rsa_public_key_clear(&pub);
  175. throw ConnFailedException("failed to import key");
  176. }
  177. serverKeyLength = serverKey.size * 8;
  178. serverKeyN = new rdr::U8[serverKey.size];
  179. serverKeyE = new rdr::U8[serverKey.size];
  180. nettle_mpz_get_str_256(serverKey.size, serverKeyN, pub.n);
  181. nettle_mpz_get_str_256(serverKey.size, serverKeyE, pub.e);
  182. rsa_public_key_clear(&pub);
  183. }
  184. void SSecurityRSAAES::loadPKCS8Key(const rdr::U8* data, size_t size)
  185. {
  186. struct asn1_der_iterator i, j;
  187. uint32_t version;
  188. const char* rsaIdentifier = "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01";
  189. const size_t rsaIdentifierLength = 9;
  190. enum asn1_iterator_result res = asn1_der_iterator_first(&i, size, data);
  191. if (res != ASN1_ITERATOR_CONSTRUCTED)
  192. goto failed;
  193. if (i.type != ASN1_SEQUENCE)
  194. goto failed;
  195. if (asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE)
  196. goto failed;
  197. if (!(i.type == ASN1_INTEGER &&
  198. asn1_der_get_uint32(&i, &version) &&
  199. version == 0))
  200. goto failed;
  201. if (!(asn1_der_iterator_next(&i) == ASN1_ITERATOR_CONSTRUCTED &&
  202. i.type == ASN1_SEQUENCE &&
  203. asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE &&
  204. j.type == ASN1_IDENTIFIER &&
  205. j.length == rsaIdentifierLength &&
  206. memcmp(j.data, rsaIdentifier, rsaIdentifierLength) == 0))
  207. goto failed;
  208. if (!(asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE &&
  209. i.type == ASN1_OCTETSTRING && i.length))
  210. goto failed;
  211. loadPKCS1Key(i.data, i.length);
  212. return;
  213. failed:
  214. throw ConnFailedException("failed to import key");
  215. }
  216. bool SSecurityRSAAES::processMsg()
  217. {
  218. switch (state) {
  219. case SendPublicKey:
  220. loadPrivateKey();
  221. writePublicKey();
  222. state = ReadPublicKey;
  223. /* fall through */
  224. case ReadPublicKey:
  225. if (!readPublicKey())
  226. return false;
  227. writeRandom();
  228. state = ReadRandom;
  229. /* fall through */
  230. case ReadRandom:
  231. if (!readRandom())
  232. return false;
  233. setCipher();
  234. writeHash();
  235. state = ReadHash;
  236. /* fall through */
  237. case ReadHash:
  238. if (!readHash())
  239. return false;
  240. clearSecrets();
  241. writeSubtype();
  242. state = ReadCredentials;
  243. /* fall through */
  244. case ReadCredentials:
  245. if (!readCredentials())
  246. return false;
  247. if (requireUsername)
  248. verifyUserPass();
  249. else
  250. verifyPass();
  251. return true;
  252. }
  253. assert(!"unreachable");
  254. return false;
  255. }
  256. void SSecurityRSAAES::writePublicKey()
  257. {
  258. rdr::OutStream* os = sc->getOutStream();
  259. os->writeU32(serverKeyLength);
  260. os->writeBytes(serverKeyN, serverKey.size);
  261. os->writeBytes(serverKeyE, serverKey.size);
  262. os->flush();
  263. }
  264. bool SSecurityRSAAES::readPublicKey()
  265. {
  266. rdr::InStream* is = sc->getInStream();
  267. if (!is->hasData(4))
  268. return false;
  269. is->setRestorePoint();
  270. clientKeyLength = is->readU32();
  271. if (clientKeyLength < MinKeyLength)
  272. throw ConnFailedException("client key is too short");
  273. if (clientKeyLength > MaxKeyLength)
  274. throw ConnFailedException("client key is too long");
  275. size_t size = (clientKeyLength + 7) / 8;
  276. if (!is->hasDataOrRestore(size * 2))
  277. return false;
  278. is->clearRestorePoint();
  279. clientKeyE = new rdr::U8[size];
  280. clientKeyN = new rdr::U8[size];
  281. is->readBytes(clientKeyN, size);
  282. is->readBytes(clientKeyE, size);
  283. rsa_public_key_init(&clientKey);
  284. nettle_mpz_set_str_256_u(clientKey.n, size, clientKeyN);
  285. nettle_mpz_set_str_256_u(clientKey.e, size, clientKeyE);
  286. if (!rsa_public_key_prepare(&clientKey))
  287. throw ConnFailedException("client key is invalid");
  288. return true;
  289. }
  290. static void random_func(void* ctx, size_t length, uint8_t* dst)
  291. {
  292. rdr::RandomStream* rs = (rdr::RandomStream*)ctx;
  293. if (!rs->hasData(length))
  294. throw ConnFailedException("failed to encrypt random");
  295. rs->readBytes(dst, length);
  296. }
  297. void SSecurityRSAAES::writeRandom()
  298. {
  299. rdr::OutStream* os = sc->getOutStream();
  300. if (!rs.hasData(keySize / 8))
  301. throw ConnFailedException("failed to generate random");
  302. rs.readBytes(serverRandom, keySize / 8);
  303. mpz_t x;
  304. mpz_init(x);
  305. int res;
  306. try {
  307. res = rsa_encrypt(&clientKey, &rs, random_func, keySize / 8,
  308. serverRandom, x);
  309. } catch (...) {
  310. mpz_clear(x);
  311. throw;
  312. }
  313. if (!res) {
  314. mpz_clear(x);
  315. throw ConnFailedException("failed to encrypt random");
  316. }
  317. rdr::U8* buffer = new rdr::U8[clientKey.size];
  318. nettle_mpz_get_str_256(clientKey.size, buffer, x);
  319. mpz_clear(x);
  320. os->writeU16(clientKey.size);
  321. os->writeBytes(buffer, clientKey.size);
  322. os->flush();
  323. delete[] buffer;
  324. }
  325. bool SSecurityRSAAES::readRandom()
  326. {
  327. rdr::InStream* is = sc->getInStream();
  328. if (!is->hasData(2))
  329. return false;
  330. is->setRestorePoint();
  331. size_t size = is->readU16();
  332. if (size != serverKey.size)
  333. throw ConnFailedException("server key length doesn't match");
  334. if (!is->hasDataOrRestore(size))
  335. return false;
  336. is->clearRestorePoint();
  337. rdr::U8* buffer = new rdr::U8[size];
  338. is->readBytes(buffer, size);
  339. size_t randomSize = keySize / 8;
  340. mpz_t x;
  341. nettle_mpz_init_set_str_256_u(x, size, buffer);
  342. delete[] buffer;
  343. if (!rsa_decrypt(&serverKey, &randomSize, clientRandom, x) ||
  344. randomSize != (size_t)keySize / 8) {
  345. mpz_clear(x);
  346. throw ConnFailedException("failed to decrypt client random");
  347. }
  348. mpz_clear(x);
  349. return true;
  350. }
  351. void SSecurityRSAAES::setCipher()
  352. {
  353. rawis = sc->getInStream();
  354. rawos = sc->getOutStream();
  355. rdr::U8 key[32];
  356. if (keySize == 128) {
  357. struct sha1_ctx ctx;
  358. sha1_init(&ctx);
  359. sha1_update(&ctx, 16, serverRandom);
  360. sha1_update(&ctx, 16, clientRandom);
  361. sha1_digest(&ctx, 16, key);
  362. rais = new rdr::AESInStream(rawis, key, 128);
  363. sha1_init(&ctx);
  364. sha1_update(&ctx, 16, clientRandom);
  365. sha1_update(&ctx, 16, serverRandom);
  366. sha1_digest(&ctx, 16, key);
  367. raos = new rdr::AESOutStream(rawos, key, 128);
  368. } else {
  369. struct sha256_ctx ctx;
  370. sha256_init(&ctx);
  371. sha256_update(&ctx, 32, serverRandom);
  372. sha256_update(&ctx, 32, clientRandom);
  373. sha256_digest(&ctx, 32, key);
  374. rais = new rdr::AESInStream(rawis, key, 256);
  375. sha256_init(&ctx);
  376. sha256_update(&ctx, 32, clientRandom);
  377. sha256_update(&ctx, 32, serverRandom);
  378. sha256_digest(&ctx, 32, key);
  379. raos = new rdr::AESOutStream(rawos, key, 256);
  380. }
  381. if (isAllEncrypted)
  382. sc->setStreams(rais, raos);
  383. }
  384. void SSecurityRSAAES::writeHash()
  385. {
  386. rdr::U8 hash[32];
  387. size_t len = serverKeyLength;
  388. rdr::U8 lenServerKey[4] = {
  389. (rdr::U8)((len & 0xff000000) >> 24),
  390. (rdr::U8)((len & 0xff0000) >> 16),
  391. (rdr::U8)((len & 0xff00) >> 8),
  392. (rdr::U8)(len & 0xff)
  393. };
  394. len = clientKeyLength;
  395. rdr::U8 lenClientKey[4] = {
  396. (rdr::U8)((len & 0xff000000) >> 24),
  397. (rdr::U8)((len & 0xff0000) >> 16),
  398. (rdr::U8)((len & 0xff00) >> 8),
  399. (rdr::U8)(len & 0xff)
  400. };
  401. int hashSize;
  402. if (keySize == 128) {
  403. hashSize = 20;
  404. struct sha1_ctx ctx;
  405. sha1_init(&ctx);
  406. sha1_update(&ctx, 4, lenServerKey);
  407. sha1_update(&ctx, serverKey.size, serverKeyN);
  408. sha1_update(&ctx, serverKey.size, serverKeyE);
  409. sha1_update(&ctx, 4, lenClientKey);
  410. sha1_update(&ctx, clientKey.size, clientKeyN);
  411. sha1_update(&ctx, clientKey.size, clientKeyE);
  412. sha1_digest(&ctx, hashSize, hash);
  413. } else {
  414. hashSize = 32;
  415. struct sha256_ctx ctx;
  416. sha256_init(&ctx);
  417. sha256_update(&ctx, 4, lenServerKey);
  418. sha256_update(&ctx, serverKey.size, serverKeyN);
  419. sha256_update(&ctx, serverKey.size, serverKeyE);
  420. sha256_update(&ctx, 4, lenClientKey);
  421. sha256_update(&ctx, clientKey.size, clientKeyN);
  422. sha256_update(&ctx, clientKey.size, clientKeyE);
  423. sha256_digest(&ctx, hashSize, hash);
  424. }
  425. raos->writeBytes(hash, hashSize);
  426. raos->flush();
  427. }
  428. bool SSecurityRSAAES::readHash()
  429. {
  430. rdr::U8 hash[32];
  431. rdr::U8 realHash[32];
  432. int hashSize = keySize == 128 ? 20 : 32;
  433. if (!rais->hasData(hashSize))
  434. return false;
  435. rais->readBytes(hash, hashSize);
  436. size_t len = serverKeyLength;
  437. rdr::U8 lenServerKey[4] = {
  438. (rdr::U8)((len & 0xff000000) >> 24),
  439. (rdr::U8)((len & 0xff0000) >> 16),
  440. (rdr::U8)((len & 0xff00) >> 8),
  441. (rdr::U8)(len & 0xff)
  442. };
  443. len = clientKeyLength;
  444. rdr::U8 lenClientKey[4] = {
  445. (rdr::U8)((len & 0xff000000) >> 24),
  446. (rdr::U8)((len & 0xff0000) >> 16),
  447. (rdr::U8)((len & 0xff00) >> 8),
  448. (rdr::U8)(len & 0xff)
  449. };
  450. if (keySize == 128) {
  451. struct sha1_ctx ctx;
  452. sha1_init(&ctx);
  453. sha1_update(&ctx, 4, lenClientKey);
  454. sha1_update(&ctx, clientKey.size, clientKeyN);
  455. sha1_update(&ctx, clientKey.size, clientKeyE);
  456. sha1_update(&ctx, 4, lenServerKey);
  457. sha1_update(&ctx, serverKey.size, serverKeyN);
  458. sha1_update(&ctx, serverKey.size, serverKeyE);
  459. sha1_digest(&ctx, hashSize, realHash);
  460. } else {
  461. struct sha256_ctx ctx;
  462. sha256_init(&ctx);
  463. sha256_update(&ctx, 4, lenClientKey);
  464. sha256_update(&ctx, clientKey.size, clientKeyN);
  465. sha256_update(&ctx, clientKey.size, clientKeyE);
  466. sha256_update(&ctx, 4, lenServerKey);
  467. sha256_update(&ctx, serverKey.size, serverKeyN);
  468. sha256_update(&ctx, serverKey.size, serverKeyE);
  469. sha256_digest(&ctx, hashSize, realHash);
  470. }
  471. if (memcmp(hash, realHash, hashSize) != 0)
  472. throw ConnFailedException("hash doesn't match");
  473. return true;
  474. }
  475. void SSecurityRSAAES::clearSecrets()
  476. {
  477. rsa_private_key_clear(&serverKey);
  478. rsa_public_key_clear(&clientKey);
  479. serverKey.size = 0;
  480. clientKey.size = 0;
  481. delete[] serverKeyN;
  482. delete[] serverKeyE;
  483. delete[] clientKeyN;
  484. delete[] clientKeyE;
  485. serverKeyN = NULL;
  486. serverKeyE = NULL;
  487. clientKeyN = NULL;
  488. clientKeyE = NULL;
  489. memset(serverRandom, 0, sizeof(serverRandom));
  490. memset(clientRandom, 0, sizeof(clientRandom));
  491. }
  492. void SSecurityRSAAES::writeSubtype()
  493. {
  494. if (requireUsername)
  495. raos->writeU8(secTypeRA2UserPass);
  496. else
  497. raos->writeU8(secTypeRA2Pass);
  498. raos->flush();
  499. }
  500. bool SSecurityRSAAES::readCredentials()
  501. {
  502. rais->setRestorePoint();
  503. if (!rais->hasData(1))
  504. return false;
  505. rdr::U8 lenUsername = rais->readU8();
  506. if (!rais->hasDataOrRestore(lenUsername + 1))
  507. return false;
  508. if (!username.buf) {
  509. username.replaceBuf(new char[lenUsername + 1]);
  510. rais->readBytes(username.buf, lenUsername);
  511. username.buf[lenUsername] = 0;
  512. } else {
  513. rais->skip(lenUsername);
  514. }
  515. rdr::U8 lenPassword = rais->readU8();
  516. if (!rais->hasDataOrRestore(lenPassword))
  517. return false;
  518. password.replaceBuf(new char[lenPassword + 1]);
  519. rais->readBytes(password.buf, lenPassword);
  520. password.buf[lenPassword] = 0;
  521. rais->clearRestorePoint();
  522. return true;
  523. }
  524. void SSecurityRSAAES::verifyUserPass()
  525. {
  526. #ifndef __APPLE__
  527. #ifdef WIN32
  528. WinPasswdValidator* valid = new WinPasswdValidator();
  529. #elif !defined(__APPLE__)
  530. UnixPasswordValidator *valid = new UnixPasswordValidator();
  531. #endif
  532. if (!valid->validate(sc, username.buf, password.buf)) {
  533. delete valid;
  534. throw AuthFailureException("invalid password or username");
  535. }
  536. delete valid;
  537. #else
  538. throw AuthFailureException("No password validator configured");
  539. #endif
  540. }
  541. void SSecurityRSAAES::verifyPass()
  542. {
  543. VncAuthPasswdGetter* pg = &SSecurityVncAuth::vncAuthPasswd;
  544. PlainPasswd passwd, passwdReadOnly;
  545. pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
  546. if (!passwd.buf)
  547. throw AuthFailureException("No password configured for VNC Auth");
  548. if (strcmp(password.buf, passwd.buf) == 0) {
  549. accessRights = SConnection::AccessDefault;
  550. return;
  551. }
  552. if (passwdReadOnly.buf && strcmp(password.buf, passwdReadOnly.buf) == 0) {
  553. accessRights = SConnection::AccessView;
  554. return;
  555. }
  556. throw AuthFailureException();
  557. }
  558. const char* SSecurityRSAAES::getUserName() const
  559. {
  560. return username.buf;
  561. }