openssl/perl/openssl_bio.xs

452 lines
7.9 KiB
Plaintext
Raw Normal View History

#include "openssl.h"
static int p5_bio_ex_bio_ptr=0;
static int p5_bio_ex_bio_callback=0;
static int p5_bio_ex_bio_callback_data=0;
static long p5_bio_callback(bio,state,parg,cmd,larg,ret)
BIO *bio;
int state;
char *parg;
int cmd;
long larg;
int ret;
{
int i;
SV *me,*cb;
me=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
cb=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_callback);
if (cb != NULL)
{
dSP;
ENTER ;
SAVETMPS;
PUSHMARK(sp);
XPUSHs(sv_2mortal(newSViv(me)));
XPUSHs(sv_2mortal(newSViv(state)));
XPUSHs(sv_2mortal(newSViv(cmd)));
if ((state == BIO_CB_READ) || (state == BIO_CB_WRITE))
{
XPUSHs(sv_2mortal(newSVpv(parg,larg)));
}
else
XPUSHs(&sv_undef);
/* ptr one */
XPUSHs(sv_2mortal(newSViv(larg)));
XPUSHs(sv_2mortal(newSViv(ret)));
PUTBACK;
i=perl_call_sv(cb,G_SCALAR);
SPAGAIN;
if (i == 1)
ret=POPi;
else
ret=1;
PUTBACK;
FREETMPS;
LEAVE;
}
else
{
croak("Internal error in SSL p5_ssl_info_callback");
}
return(ret);
}
int boot_bio()
{
p5_bio_ex_bio_ptr=
BIO_get_ex_new_index(0,"OpenSSL::BIO",ex_new,NULL,
ex_cleanup);
p5_bio_ex_bio_callback=
BIO_get_ex_new_index(0,"bio_callback",NULL,NULL,
ex_cleanup);
p5_bio_ex_bio_callback_data=
BIO_get_ex_new_index(0,"bio_callback_data",NULL,NULL,
ex_cleanup);
return(1);
}
MODULE = OpenSSL::BIO PACKAGE = OpenSSL::BIO PREFIX = p5_BIO_
VERSIONCHECK: DISABLE
void
p5_BIO_new_buffer_ssl_connect(...)
PREINIT:
SSL_CTX *ctx;
BIO *bio;
SV *arg;
PPCODE:
if (items == 1)
arg=ST(0);
else if (items == 2)
arg=ST(1);
else
arg=NULL;
if ((arg == NULL) || !(sv_derived_from(arg,"OpenSSL::SSL::CTX")))
croak("Usage: OpenSSL::BIO::new_buffer_ssl_connect(SSL_CTX)");
else
{
IV tmp=SvIV((SV *)SvRV(arg));
ctx=(SSL_CTX *)tmp;
}
EXTEND(sp,1);
bio=BIO_new_buffer_ssl_connect(ctx);
arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
PUSHs(arg);
void
p5_BIO_new_ssl_connect(...)
PREINIT:
SSL_CTX *ctx;
BIO *bio;
SV *arg;
PPCODE:
if (items == 1)
arg=ST(0);
else if (items == 2)
arg=ST(1);
else
arg=NULL;
if ((arg == NULL) || !(sv_derived_from(arg,"OpenSSL::SSL::CTX")))
croak("Usage: OpenSSL::BIO::new_ssl_connect(SSL_CTX)");
else
{
IV tmp=SvIV((SV *)SvRV(arg));
ctx=(SSL_CTX *)tmp;
}
EXTEND(sp,1);
bio=BIO_new_ssl_connect(ctx);
arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
PUSHs(arg);
void
p5_BIO_new(...)
PREINIT:
BIO *bio;
char *type;
SV *arg;
PPCODE:
pr_name("p5_BIO_new");
if ((items == 1) && SvPOK(ST(0)))
type=SvPV(ST(0),na);
else if ((items == 2) && SvPOK(ST(1)))
type=SvPV(ST(1),na);
else
croak("Usage: OpenSSL::BIO::new(type)");
EXTEND(sp,1);
if (strcmp(type,"connect") == 0)
bio=BIO_new(BIO_s_connect());
else if (strcmp(type,"accept") == 0)
bio=BIO_new(BIO_s_accept());
else if (strcmp(type,"ssl") == 0)
bio=BIO_new(BIO_f_ssl());
else if (strcmp(type,"buffer") == 0)
bio=BIO_new(BIO_f_buffer());
else
croak("unknown BIO type");
arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
PUSHs(arg);
int
p5_BIO_hostname(bio,name)
BIO *bio;
char *name;
CODE:
RETVAL=BIO_set_conn_hostname(bio,name);
OUTPUT:
RETVAL
int
p5_BIO_set_accept_port(bio,str)
BIO *bio;
char *str;
CODE:
RETVAL=BIO_set_accept_port(bio,str);
OUTPUT:
RETVAL
int
p5_BIO_do_handshake(bio)
BIO *bio;
CODE:
RETVAL=BIO_do_handshake(bio);
OUTPUT:
RETVAL
BIO *
p5_BIO_push(b,bio)
BIO *b;
BIO *bio;
CODE:
/* This reference will be reduced when the reference is
* let go, and then when the BIO_free_all() is called
* inside the OpenSSL library by the BIO with this
* pushed into */
bio->references++;
RETVAL=BIO_push(b,bio);
OUTPUT:
RETVAL
void
p5_BIO_pop(b)
BIO *b
PREINIT:
BIO *bio;
char *type;
SV *arg;
PPCODE:
bio=BIO_pop(b);
if (bio != NULL)
{
/* This BIO will either be one created in the
* perl library, in which case it will have a perl
* SV, otherwise it will have been created internally,
* inside OpenSSL. For the 'pushed in', it needs
* the reference count decememted. */
arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
if (arg == NULL)
{
arg=new_ref("OpenSSL::BIO",(char *)bio,0);
BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
PUSHs(arg);
}
else
{
/* it was pushed in */
SvREFCNT_inc(arg);
PUSHs(arg);
#if 0 /* This does not need to be done. */
if (bio->references < 1)
abort();
/* decrement the reference count */
BIO_free(bio);
#endif
}
}
int
p5_BIO_sysread(bio,in,num, ...)
BIO *bio;
SV *in;
int num;
PREINIT:
int i,n,olen;
int offset;
char *p;
CODE:
offset=0;
if (!SvPOK(in))
sv_setpvn(in,"",0);
SvPV(in,olen);
if (items > 3)
{
offset=SvIV(ST(3));
if (offset < 0)
{
if (-offset > olen)
croak("Offset outside string");
offset+=olen;
}
}
if ((num+offset) > olen)
{
SvGROW(in,num+offset+1);
p=SvPV(in,i);
memset(&(p[olen]),0,(num+offset)-olen+1);
}
p=SvPV(in,n);
i=BIO_read(bio,p+offset,num);
RETVAL=i;
if (i <= 0) i=0;
SvCUR_set(in,offset+i);
OUTPUT:
RETVAL
int
p5_BIO_syswrite(bio,in, ...)
BIO *bio;
SV *in;
PREINIT:
char *ptr;
int len,in_len;
int offset=0;
int n;
CODE:
ptr=SvPV(in,in_len);
if (items > 2)
{
len=SvOK(ST(2))?SvIV(ST(2)):in_len;
if (items > 3)
{
offset=SvIV(ST(3));
if (offset < 0)
{
if (-offset > in_len)
croak("Offset outside string");
offset+=in_len;
}
else if ((offset >= in_len) && (in_len > 0))
croak("Offset outside string");
}
if (len >= (in_len-offset))
len=in_len-offset;
}
else
len=in_len;
RETVAL=BIO_write(bio,ptr+offset,len);
OUTPUT:
RETVAL
void
p5_BIO_getline(bio)
BIO *bio;
PREINIT:
int i;
char *p;
PPCODE:
pr_name("p5_BIO_gets");
EXTEND(sp,1);
PUSHs(sv_newmortal());
sv_setpvn(ST(0),"",0);
SvGROW(ST(0),1024);
p=SvPV(ST(0),na);
i=BIO_gets(bio,p,1024);
if (i < 0) i=0;
SvCUR_set(ST(0),i);
int
p5_BIO_flush(bio)
BIO *bio;
CODE:
RETVAL=BIO_flush(bio);
OUTPUT:
RETVAL
char *
p5_BIO_type(bio)
BIO *bio;
CODE:
RETVAL=bio->method->name;
OUTPUT:
RETVAL
void
p5_BIO_next_bio(b)
BIO *b
PREINIT:
BIO *bio;
char *type;
SV *arg;
PPCODE:
bio=b->next_bio;
if (bio != NULL)
{
arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
if (arg == NULL)
{
arg=new_ref("OpenSSL::BIO",(char *)bio,0);
BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
bio->references++;
PUSHs(arg);
}
else
{
SvREFCNT_inc(arg);
PUSHs(arg);
}
}
int
p5_BIO_puts(bio,in)
BIO *bio;
SV *in;
PREINIT:
char *ptr;
CODE:
ptr=SvPV(in,na);
RETVAL=BIO_puts(bio,ptr);
OUTPUT:
RETVAL
void
p5_BIO_set_callback(bio,cb,...)
BIO *bio;
SV *cb;
PREINIT:
SV *arg=NULL;
SV *arg2=NULL;
CODE:
if (items > 3)
croak("Usage: OpenSSL::BIO::set_callback(bio,callback[,arg]");
if (items == 3)
{
arg2=sv_mortalcopy(ST(2));
SvREFCNT_inc(arg2);
BIO_set_ex_data(bio,p5_bio_ex_bio_callback_data,
(char *)arg2);
}
arg=sv_mortalcopy(ST(1));
SvREFCNT_inc(arg);
BIO_set_ex_data(bio,p5_bio_ex_bio_callback,(char *)arg);
printf("%08lx < bio_ptr\n",BIO_get_ex_data(bio,p5_bio_ex_bio_ptr));
BIO_set_callback(bio,p5_bio_callback);
void
p5_BIO_DESTROY(bio)
BIO *bio
PREINIT:
SV *sv;
PPCODE:
pr_name_d("p5_BIO_DESTROY",bio->references);
printf("p5_BIO_DESTROY <%s> %d\n",bio->method->name,bio->references);
BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,NULL);
BIO_free_all(bio);
int
p5_BIO_set_ssl(bio,ssl)
BIO *bio;
SSL *ssl;
CODE:
pr_name("p5_BIO_set_ssl");
ssl->references++;
RETVAL=BIO_set_ssl(bio,ssl,BIO_CLOSE);
OUTPUT:
RETVAL
int
p5_BIO_number_read(bio)
BIO *bio;
CODE:
RETVAL=BIO_number_read(bio);
OUTPUT:
RETVAL
int
p5_BIO_number_written(bio)
BIO *bio;
CODE:
RETVAL=BIO_number_written(bio);
OUTPUT:
RETVAL
int
p5_BIO_references(bio)
BIO *bio;
CODE:
RETVAL=bio->references;
OUTPUT:
RETVAL