+ }
+}
+
+/*
+ * Send binary data to the client encrypted.
+ */
+void client_write_ssl(const StrBuf *Buf)
+{
+ const char *buf;
+ int retval;
+ int nremain;
+ long nbytes;
+ char junk[1];
+
+ if (THREADSSL == NULL) return;
+
+ nbytes = nremain = StrLength(Buf);
+ buf = ChrPtr(Buf);
+
+ while (nremain > 0) {
+ if (SSL_want_write(THREADSSL)) {
+ if ((SSL_read(THREADSSL, junk, 0)) < 1) {
+ syslog(9, "SSL_read in client_write: %s\n",
+ ERR_reason_error_string(ERR_get_error()));
+ }
+ }
+ retval = SSL_write(THREADSSL, &buf[nbytes - nremain], nremain);
+ if (retval < 1) {
+ long errval;
+
+ errval = SSL_get_error(THREADSSL, retval);
+ if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
+ sleeeeeeeeeep(1);
+ continue;
+ }
+ syslog(9, "SSL_write got error %ld, ret %d\n", errval, retval);
+ if (retval == -1) {
+ syslog(9, "errno is %d\n", errno);
+ }
+ endtls();
+ return;
+ }
+ nremain -= retval;
+ }
+}
+
+
+/*
+ * read data from the encrypted layer.
+ */
+int client_read_sslbuffer(StrBuf *buf, int timeout)
+{
+ char sbuf[16384]; /* OpenSSL communicates in 16k blocks, so let's speak its native tongue. */
+ int rlen;
+ char junk[1];
+ SSL *pssl = THREADSSL;
+
+ if (pssl == NULL) return(-1);
+
+ while (1) {
+ if (SSL_want_read(pssl)) {
+ if ((SSL_write(pssl, junk, 0)) < 1) {
+ syslog(9, "SSL_write in client_read\n");
+ }
+ }
+ rlen = SSL_read(pssl, sbuf, sizeof(sbuf));
+ if (rlen < 1) {
+ long errval;
+
+ errval = SSL_get_error(pssl, rlen);
+ if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
+ sleeeeeeeeeep(1);
+ continue;
+ }
+ syslog(9, "SSL_read got error %ld\n", errval);
+ endtls();
+ return (-1);
+ }
+ StrBufAppendBufPlain(buf, sbuf, rlen, 0);
+ return rlen;
+ }
+ return (0);