📄 pssl.cxx
字号:
BOOL PSSLChannel::Read(void * buf, PINDEX len)
{
int r = SSL_read(ssl, (char *)buf, len);
lastReadCount = 0;
if (!ConvertOSError(r))
return FALSE;
lastReadCount = r;
return TRUE;
}
BOOL PSSLChannel::Write(const void * buf, PINDEX len)
{
lastWriteCount = 0;
while (len > 0) {
int sendResult = SSL_write(ssl, ((char *)buf)+lastWriteCount, len);
if (!ConvertOSError(sendResult))
return FALSE;
lastWriteCount += sendResult;
len -= sendResult;
}
return TRUE;
}
BOOL PSSLChannel::RawRead(void * buf, PINDEX len)
{
return readChannel->Read(buf, len);
}
PINDEX PSSLChannel::RawGetLastReadCount() const
{
return readChannel->GetLastReadCount();
}
BOOL PSSLChannel::RawWrite(const void * buf, PINDEX len)
{
return writeChannel->Write(buf, len);
}
PINDEX PSSLChannel::RawGetLastWriteCount() const
{
return writeChannel->GetLastWriteCount();
}
//////////////////////////////////////////////////////////////////////////
//
// Low level interface to SSLEay routines
//
#define PSSLSOCKET(bio) ((PSSLChannel *)(bio->num))
extern "C" {
#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include "cryptlib.h"
#include "buffer.h"
static int Psock_write(BIO *h,char *buf,int num);
static int Psock_read(BIO *h,char *buf,int size);
static int Psock_puts(BIO *h,char *str);
static int Psock_gets(BIO *h,char *str,int size);
static long Psock_ctrl(BIO *h,int cmd,long arg1,char *arg2);
static int Psock_new(BIO *h);
static int Psock_free(BIO *data);
static int Psock_should_retry(int s);
typedef int (*ifptr)();
typedef long (*lfptr)();
static BIO_METHOD methods_Psock =
{
BIO_TYPE_SOCKET,
"ptlib socket",
(ifptr)Psock_write,
(ifptr)Psock_read,
(ifptr)Psock_puts,
(ifptr)Psock_gets,
(lfptr)Psock_ctrl,
(ifptr)Psock_new,
(ifptr)Psock_free
};
static long Psock_ctrl(BIO * bio, int cmd, long num, char * ptr)
{
long ret = 1;
int *ip;
switch (cmd) {
//
// mandatory BIO commands
//
// case BIO_CTRL_SET:
case BIO_C_SET_FD:
if (bio != NULL);
Psock_free(bio);
bio->num = *((int *)ptr);
bio->shutdown = (int)num;
bio->init = 1;
break;
case BIO_CTRL_GET:
if (bio->init) {
ip = (int *)ptr;
if (ip == NULL)
ret = 0;
else
*ip = bio->num;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
bio->shutdown=(int)num;
break;
//
// optional BIO commands
//
case BIO_CTRL_RESET:
ret = 0;
break;
case BIO_CTRL_INFO:
ret = 0;
break;
case BIO_CTRL_EOF:
ret = 0;
break;
case BIO_CTRL_PUSH:
ret = 0;
break;
case BIO_CTRL_POP:
ret = 0;
break;
case BIO_CTRL_PENDING:
ret = 0;
break;
case BIO_CTRL_FLUSH:
break;
default:
ret = 0;
break;
}
return ret;
}
static int Psock_new(BIO * bio)
{
bio->init = 0;
bio->num = 0; // this is really (PSSLChannel *), not int
bio->ptr = NULL;
bio->flags = 0;
return(1);
}
static int Psock_free(BIO * bio)
{
if (bio == NULL)
return 0;
if (bio->shutdown) {
if (bio->init) {
PSSLSOCKET(bio)->Shutdown(PSocket::ShutdownReadAndWrite);
PSSLSOCKET(bio)->Close();
}
bio->init = 0;
bio->flags = 0;
}
return 1;
}
static int Psock_should_retry(int i)
{
if (i == PChannel::Interrupted)
return 1;
if (i == PChannel::Timeout)
return 1;
return 0;
}
static int Psock_read(BIO * bio, char * out, int outl)
{
int ret = 0;
if (out != NULL) {
BOOL b = PSSLSOCKET(bio)->RawRead(out, outl);
BIO_clear_retry_flags(bio);
if (b)
ret = PSSLSOCKET(bio)->RawGetLastReadCount();
else if (Psock_should_retry(PSSLSOCKET(bio)->GetErrorCode())) {
BIO_set_retry_read(bio);
ret = -1;
}
}
return(ret);
}
static int Psock_write(BIO * bio, char * in, int inl)
{
int ret = 0;
if (in != NULL) {
BOOL b = PSSLSOCKET(bio)->RawWrite(in, inl);
BIO_clear_retry_flags(bio);
bio->flags &= ~(BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
if (b)
ret = PSSLSOCKET(bio)->RawGetLastWriteCount();
else if (Psock_should_retry(PSSLSOCKET(bio)->GetErrorCode())) {
BIO_set_retry_write(bio);
ret = -1;
}
}
return(ret);
}
static int Psock_gets(BIO *,char *, int)
{
return -1;
}
static int Psock_puts(BIO * bio,char * str)
{
int n,ret;
n = strlen(str);
ret = Psock_write(bio,str,n);
return ret;
}
};
int PSSLChannel::Set_SSL_Fd()
{
int ret=0;
BIO * bio = NULL;
bio = BIO_new(&methods_Psock);
if (bio == NULL) {
SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB);
goto err;
}
SSL_set_bio(ssl, bio, bio);
BIO_set_fd(bio, (int)this, BIO_NOCLOSE);
/*
if (ssl->rbio != NULL)
BIO_free((bio_st *)ssl->rbio);
if ((ssl->wbio != NULL) && (ssl->wbio != ssl->rbio))
BIO_free((bio_st *)ssl->wbio);
ssl->rbio = bio;
ssl->wbio = bio;
ret = 1;
*/
err:
return(ret);
}
//////////////////////////////////////////////////////////////////////////
//
// misc unused code
//
#if 0
extern "C" {
static verify_depth = 0;
static verify_error = VERIFY_OK;
// should be X509 * but we can just have them as char *.
int verify_callback(int ok, X509 * xs, X509 * xi, int depth, int error)
{
char *s;
s = (char *)X509_NAME_oneline(X509_get_subject_name(xs));
if (s == NULL) {
// ERR_print_errors(bio_err);
return(0);
}
PError << "depth= " << depth << " " << (char *)s << endl;
free(s);
if (error == VERIFY_ERR_UNABLE_TO_GET_ISSUER) {
s=(char *)X509_NAME_oneline(X509_get_issuer_name(xs));
if (s == NULL) {
PError << "verify error" << endl;
//ERR_print_errors(bio_err);
return(0);
}
PError << "issuer = " << s << endl;
free(s);
}
if (!ok) {
PError << "verify error:num=" << error << " " <<
X509_cert_verify_error_string(error) << endl;
if (verify_depth <= depth) {
ok=1;
verify_error=VERIFY_OK;
} else {
ok=0;
verify_error=error;
}
}
PError << "verify return:" << ok << endl;
return(ok);
}
};
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -