关键词搜索

源码搜索 ×
×

漫话Redis源码之七十四

发布2022-02-13浏览524次

详情内容

SSL大家应该很熟悉,就是为了确保安全的,openssl应该听说过吧:

  1. /* Wrapper around redisSecureConnection to avoid hiredis_ssl dependencies if
  2. * not building with TLS support.
  3. */
  4. int cliSecureConnection(redisContext *c, cliSSLconfig config, const char **err) {
  5. #ifdef USE_OPENSSL
  6. static SSL_CTX *ssl_ctx = NULL;
  7. if (!ssl_ctx) {
  8. ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  9. if (!ssl_ctx) {
  10. *err = "Failed to create SSL_CTX";
  11. goto error;
  12. }
  13. SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  14. SSL_CTX_set_verify(ssl_ctx, config.skip_cert_verify ? SSL_VERIFY_NONE : SSL_VERIFY_PEER, NULL);
  15. if (config.cacert || config.cacertdir) {
  16. if (!SSL_CTX_load_verify_locations(ssl_ctx, config.cacert, config.cacertdir)) {
  17. *err = "Invalid CA Certificate File/Directory";
  18. goto error;
  19. }
  20. } else {
  21. if (!SSL_CTX_set_default_verify_paths(ssl_ctx)) {
  22. *err = "Failed to use default CA paths";
  23. goto error;
  24. }
  25. }
  26. if (config.cert && !SSL_CTX_use_certificate_chain_file(ssl_ctx, config.cert)) {
  27. *err = "Invalid client certificate";
  28. goto error;
  29. }
  30. if (config.key && !SSL_CTX_use_PrivateKey_file(ssl_ctx, config.key, SSL_FILETYPE_PEM)) {
  31. *err = "Invalid private key";
  32. goto error;
  33. }
  34. if (config.ciphers && !SSL_CTX_set_cipher_list(ssl_ctx, config.ciphers)) {
  35. *err = "Error while configuring ciphers";
  36. goto error;
  37. }
  38. #ifdef TLS1_3_VERSION
  39. if (config.ciphersuites && !SSL_CTX_set_ciphersuites(ssl_ctx, config.ciphersuites)) {
  40. *err = "Error while setting cypher suites";
  41. goto error;
  42. }
  43. #endif
  44. }
  45. SSL *ssl = SSL_new(ssl_ctx);
  46. if (!ssl) {
  47. *err = "Failed to create SSL object";
  48. return REDIS_ERR;
  49. }
  50. if (config.sni && !SSL_set_tlsext_host_name(ssl, config.sni)) {
  51. *err = "Failed to configure SNI";
  52. SSL_free(ssl);
  53. return REDIS_ERR;
  54. }
  55. return redisInitiateSSL(c, ssl);
  56. error:
  57. SSL_CTX_free(ssl_ctx);
  58. ssl_ctx = NULL;
  59. return REDIS_ERR;
  60. #else
  61. (void) config;
  62. (void) c;
  63. (void) err;
  64. return REDIS_OK;
  65. #endif
  66. }
  67. /* Wrapper around hiredis to allow arbitrary reads and writes.
  68. *
  69. * We piggybacks on top of hiredis to achieve transparent TLS support,
  70. * and use its internal buffers so it can co-exist with commands
  71. * previously/later issued on the connection.
  72. *
  73. * Interface is close to enough to read()/write() so things should mostly
  74. * work transparently.
  75. */
  76. /* Write a raw buffer through a redisContext. If we already have something
  77. * in the buffer (leftovers from hiredis operations) it will be written
  78. * as well.
  79. */
  80. ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len)
  81. {
  82. int done = 0;
  83. /* Append data to buffer which is *usually* expected to be empty
  84. * but we don't assume that, and write.
  85. */
  86. c->obuf = sdscatlen(c->obuf, buf, buf_len);
  87. if (redisBufferWrite(c, &done) == REDIS_ERR) {
  88. if (!(c->flags & REDIS_BLOCK))
  89. errno = EAGAIN;
  90. /* On error, we assume nothing was written and we roll back the
  91. * buffer to its original state.
  92. */
  93. if (sdslen(c->obuf) > buf_len)
  94. sdsrange(c->obuf, 0, -(buf_len+1));
  95. else
  96. sdsclear(c->obuf);
  97. return -1;
  98. }
  99. /* If we're done, free up everything. We may have written more than
  100. * buf_len (if c->obuf was not initially empty) but we don't have to
  101. * tell.
  102. */
  103. if (done) {
  104. sdsclear(c->obuf);
  105. return buf_len;
  106. }
  107. /* Write was successful but we have some leftovers which we should
  108. * remove from the buffer.
  109. *
  110. * Do we still have data that was there prior to our buf? If so,
  111. * restore buffer to it's original state and report no new data was
  112. * writen.
  113. */
  114. if (sdslen(c->obuf) > buf_len) {
  115. sdsrange(c->obuf, 0, -(buf_len+1));
  116. return 0;
  117. }
  118. /* At this point we're sure no prior data is left. We flush the buffer
  119. * and report how much we've written.
  120. */
  121. size_t left = sdslen(c->obuf);
  122. sdsclear(c->obuf);
  123. return buf_len - left;
  124. }
  125. /* Wrapper around OpenSSL (libssl and libcrypto) initialisation
  126. */
  127. int cliSecureInit()
  128. {
  129. #ifdef USE_OPENSSL
  130. ERR_load_crypto_strings();
  131. SSL_load_error_strings();
  132. SSL_library_init();
  133. #endif
  134. return REDIS_OK;
  135. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载