-#ifdef TLS_SUPPORT
-/*
- * Negotiate Transport Layer Security
- */
-
-static int
-tls_negotiate(void)
-{
- BIO *ssl_bio;
-
- if (! sslctx) {
- const SSL_METHOD *method;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- method = TLSv1_client_method(); /* Not sure about this */
-
- /* Older ssl takes a non-const arg. */
- sslctx = SSL_CTX_new((SSL_METHOD *) method);
-
- if (! sslctx) {
- sm_end(NOTOK);
- return sm_ierror("Unable to initialize OpenSSL context: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
- }
-
- ssl = SSL_new(sslctx);
-
- if (! ssl) {
- sm_end(NOTOK);
- return sm_ierror("Unable to create SSL connection: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- sbior = BIO_new_socket(fileno(sm_rfp), BIO_NOCLOSE);
- sbiow = BIO_new_socket(fileno(sm_wfp), BIO_NOCLOSE);
-
- if (sbior == NULL || sbiow == NULL) {
- sm_end(NOTOK);
- return sm_ierror("Unable to create BIO endpoints: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- SSL_set_bio(ssl, sbior, sbiow);
- SSL_set_connect_state(ssl);
-
- /*
- * Set up a BIO to handle buffering for us
- */
-
- io = BIO_new(BIO_f_buffer());
-
- if (! io) {
- sm_end(NOTOK);
- return sm_ierror("Unable to create a buffer BIO: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- ssl_bio = BIO_new(BIO_f_ssl());
-
- if (! ssl_bio) {
- sm_end(NOTOK);
- return sm_ierror("Unable to create a SSL BIO: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
- BIO_push(io, ssl_bio);
-
- /*
- * Try doing the handshake now
- */
-
- if (BIO_do_handshake(io) < 1) {
- sm_end(NOTOK);
- return sm_ierror("Unable to negotiate SSL connection: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- if (sm_debug) {
- const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
- printf("SSL negotiation successful: %s(%d) %s\n",
- SSL_CIPHER_get_name(cipher),
- SSL_CIPHER_get_bits(cipher, NULL),
- SSL_CIPHER_get_version(cipher));
-
- }
-
- tls_active = 1;
-
- return RP_OK;
-}
-#endif /* TLS_SUPPORT */
-
-/*
- * Convenience functions to replace occurrences of fputs() and fputc()
- */
-
-static int
-sm_fputs(char *buffer)
-{
- return sm_fwrite(buffer, strlen(buffer));
-}
-
-static int
-sm_fputc(int c)
-{
- char h = c;
-
- return sm_fwrite(&h, 1);
-}
-
-/*
- * Flush out any pending data on the connection
- */
-
-static void
-sm_fflush(void)
-{
-#ifdef CYRUS_SASL
- const char *output;
- unsigned int outputlen;
- int result;
-
- if (sasl_complete == 1 && sasl_ssf > 0 && sasl_outbuflen > 0) {
- result = sasl_encode(conn, sasl_outbuffer, sasl_outbuflen,
- &output, &outputlen);
- if (result != SASL_OK) {
- sm_ierror("Unable to SASL encode connection data: %s",
- sasl_errdetail(conn));
- return;
- }
-
- if (fwrite(output, sizeof(*output), outputlen, sm_wfp) < outputlen) {
- advise ("sm_fflush", "fwrite");
- }
- sasl_outbuflen = 0;
- }
-#endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
- if (tls_active) {
- (void) BIO_flush(io);
- }
-#endif /* TLS_SUPPORT */
-
- fflush(sm_wfp);
-}
-