Finally(?) fix DES stuff.
[openssl.git] / perl / openssl_bio.xs
1
2 #include "openssl.h"
3
4 static int p5_bio_ex_bio_ptr=0;
5 static int p5_bio_ex_bio_callback=0;
6 static int p5_bio_ex_bio_callback_data=0;
7
8 static long p5_bio_callback(bio,state,parg,cmd,larg,ret)
9 BIO *bio;
10 int state;
11 char *parg;
12 int cmd;
13 long larg;
14 int ret;
15         {
16         int i;
17         SV *me,*cb;
18
19         me=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
20         cb=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_callback);
21         if (cb != NULL)
22                 {
23                 dSP;
24
25                 ENTER ;
26                 SAVETMPS;
27
28                 PUSHMARK(sp);
29                 XPUSHs(sv_2mortal(newSViv(me)));
30                 XPUSHs(sv_2mortal(newSViv(state)));
31                 XPUSHs(sv_2mortal(newSViv(cmd)));
32                 if ((state == BIO_CB_READ) || (state == BIO_CB_WRITE))
33                         {
34                         XPUSHs(sv_2mortal(newSVpv(parg,larg)));
35                         }
36                 else
37                         XPUSHs(&sv_undef);
38                 /* ptr one */
39                 XPUSHs(sv_2mortal(newSViv(larg)));
40                 XPUSHs(sv_2mortal(newSViv(ret)));
41                 PUTBACK;
42
43                 i=perl_call_sv(cb,G_SCALAR);
44
45                 SPAGAIN;
46                 if (i == 1)
47                         ret=POPi;
48                 else
49                         ret=1;
50                 PUTBACK;
51                 FREETMPS;
52                 LEAVE;
53                 }
54         else
55                 {
56                 croak("Internal error in SSL p5_ssl_info_callback");
57                 }
58         return(ret);
59         }
60
61 int boot_bio()
62         {
63         p5_bio_ex_bio_ptr=
64                 BIO_get_ex_new_index(0,"OpenSSL::BIO",ex_new,NULL,
65                         ex_cleanup);
66         p5_bio_ex_bio_callback= 
67                 BIO_get_ex_new_index(0,"bio_callback",NULL,NULL,
68                         ex_cleanup);
69         p5_bio_ex_bio_callback_data=
70                 BIO_get_ex_new_index(0,"bio_callback_data",NULL,NULL,
71                         ex_cleanup);
72         return(1);
73         }
74
75 MODULE =  OpenSSL::BIO  PACKAGE = OpenSSL::BIO PREFIX = p5_BIO_
76
77 VERSIONCHECK: DISABLE
78
79 void
80 p5_BIO_new_buffer_ssl_connect(...)
81         PREINIT:
82                 SSL_CTX *ctx;
83                 BIO *bio;
84                 SV *arg;
85         PPCODE:
86                 if (items == 1)
87                         arg=ST(0);
88                 else if (items == 2)
89                         arg=ST(1);
90                 else
91                         arg=NULL;
92
93                 if ((arg == NULL) || !(sv_derived_from(arg,"OpenSSL::SSL::CTX")))
94                         croak("Usage: OpenSSL::BIO::new_buffer_ssl_connect(SSL_CTX)");
95                 else
96                         {
97                         IV tmp=SvIV((SV *)SvRV(arg));
98                         ctx=(SSL_CTX *)tmp;
99                         }
100                 EXTEND(sp,1);
101                 bio=BIO_new_buffer_ssl_connect(ctx);
102                 arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
103                 PUSHs(arg);
104
105 void
106 p5_BIO_new_ssl_connect(...)
107         PREINIT:
108                 SSL_CTX *ctx;
109                 BIO *bio;
110                 SV *arg;
111         PPCODE:
112                 if (items == 1)
113                         arg=ST(0);
114                 else if (items == 2)
115                         arg=ST(1);
116                 else
117                         arg=NULL;
118
119                 if ((arg == NULL) || !(sv_derived_from(arg,"OpenSSL::SSL::CTX")))
120                         croak("Usage: OpenSSL::BIO::new_ssl_connect(SSL_CTX)");
121                 else
122                         {
123                         IV tmp=SvIV((SV *)SvRV(arg));
124                         ctx=(SSL_CTX *)tmp;
125                         }
126                 EXTEND(sp,1);
127                 bio=BIO_new_ssl_connect(ctx);
128                 arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
129                 PUSHs(arg);
130
131 void
132 p5_BIO_new(...)
133         PREINIT:
134                 BIO *bio;
135                 char *type;
136                 SV *arg;
137         PPCODE:
138                 pr_name("p5_BIO_new");
139                 if ((items == 1) && SvPOK(ST(0)))
140                         type=SvPV(ST(0),na);
141                 else if ((items == 2) && SvPOK(ST(1)))
142                         type=SvPV(ST(1),na);
143                 else
144                         croak("Usage: OpenSSL::BIO::new(type)");
145
146                 EXTEND(sp,1);
147                 if (strcmp(type,"connect") == 0)
148                         bio=BIO_new(BIO_s_connect());
149                 else if (strcmp(type,"accept") == 0)
150                         bio=BIO_new(BIO_s_accept());
151                 else if (strcmp(type,"ssl") == 0)
152                         bio=BIO_new(BIO_f_ssl());
153                 else if (strcmp(type,"buffer") == 0)
154                         bio=BIO_new(BIO_f_buffer());
155                 else
156                         croak("unknown BIO type");
157                 arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
158                 PUSHs(arg);
159
160 int
161 p5_BIO_hostname(bio,name)
162         BIO *bio;
163         char *name;
164         CODE:
165                 RETVAL=BIO_set_conn_hostname(bio,name);
166         OUTPUT:
167                 RETVAL
168
169 int
170 p5_BIO_set_accept_port(bio,str)
171         BIO *bio;
172         char *str;
173         CODE:
174                 RETVAL=BIO_set_accept_port(bio,str);
175         OUTPUT:
176                 RETVAL
177
178 int
179 p5_BIO_do_handshake(bio)
180         BIO *bio;
181         CODE:
182                 RETVAL=BIO_do_handshake(bio);
183         OUTPUT:
184                 RETVAL
185
186 BIO *
187 p5_BIO_push(b,bio)
188         BIO *b;
189         BIO *bio;
190         CODE:
191                 /* This reference will be reduced when the reference is
192                  * let go, and then when the BIO_free_all() is called
193                  * inside the OpenSSL library by the BIO with this
194                  * pushed into */
195                 bio->references++;
196                 RETVAL=BIO_push(b,bio);
197         OUTPUT:
198                 RETVAL
199
200 void
201 p5_BIO_pop(b)
202         BIO *b
203         PREINIT:
204                 BIO *bio;
205                 char *type;
206                 SV *arg;
207         PPCODE:
208                 bio=BIO_pop(b);
209                 if (bio != NULL)
210                         {
211                         /* This BIO will either be one created in the
212                          * perl library, in which case it will have a perl
213                          * SV, otherwise it will have been created internally,
214                          * inside OpenSSL.  For the 'pushed in', it needs
215                          * the reference count decememted. */
216                         arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
217                         if (arg == NULL)
218                                 {
219                                 arg=new_ref("OpenSSL::BIO",(char *)bio,0);
220                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
221                                 PUSHs(arg);
222                                 }
223                         else
224                                 {
225                                 /* it was pushed in */
226                                 SvREFCNT_inc(arg);
227                                 PUSHs(arg);
228 #if 0           /* This does not need to be done. */
229                                 if (bio->references < 1)
230                                         abort();
231                                 /* decrement the reference count */
232                                 BIO_free(bio);
233 #endif
234                                 }
235                         }
236
237 int
238 p5_BIO_sysread(bio,in,num, ...)
239         BIO *bio;
240         SV *in;
241         int num;
242         PREINIT:
243                 int i,n,olen;
244                 int offset;
245                 char *p;
246         CODE:
247                 offset=0;
248                 if (!SvPOK(in))
249                         sv_setpvn(in,"",0);
250                 SvPV(in,olen);
251                 if (items > 3)
252                         {
253                         offset=SvIV(ST(3));
254                         if (offset < 0)
255                                 {
256                                 if (-offset > olen)
257                                         croak("Offset outside string");
258                                 offset+=olen;
259                                 }
260                         }
261                 if ((num+offset) > olen)
262                         {
263                         SvGROW(in,num+offset+1);
264                         p=SvPV(in,i);
265                         memset(&(p[olen]),0,(num+offset)-olen+1);
266                         }
267                 p=SvPV(in,n);
268
269                 i=BIO_read(bio,p+offset,num);
270                 RETVAL=i;
271                 if (i <= 0) i=0;
272                 SvCUR_set(in,offset+i);
273         OUTPUT:
274                 RETVAL
275
276 int
277 p5_BIO_syswrite(bio,in, ...)
278         BIO *bio;
279         SV *in;
280         PREINIT:
281                 char *ptr;
282                 int len,in_len;
283                 int offset=0;
284                 int n;
285         CODE:
286                 ptr=SvPV(in,in_len);
287                 if (items > 2)
288                         {
289                         len=SvOK(ST(2))?SvIV(ST(2)):in_len;
290                         if (items > 3)
291                                 {
292                                 offset=SvIV(ST(3));
293                                 if (offset < 0)
294                                         {
295                                         if (-offset > in_len)
296                                                 croak("Offset outside string");
297                                         offset+=in_len;
298                                         }
299                                 else if ((offset >= in_len) && (in_len > 0))
300                                         croak("Offset outside string");
301                                 }
302                         if (len >= (in_len-offset))
303                                 len=in_len-offset;
304                         }
305                 else
306                         len=in_len;
307
308                 RETVAL=BIO_write(bio,ptr+offset,len);
309         OUTPUT:
310                 RETVAL
311
312 void
313 p5_BIO_getline(bio)
314         BIO *bio;
315         PREINIT:
316                 int i;
317                 char *p;
318         PPCODE:
319                 pr_name("p5_BIO_gets");
320                 EXTEND(sp,1);
321                 PUSHs(sv_newmortal());
322                 sv_setpvn(ST(0),"",0);
323                 SvGROW(ST(0),1024);
324                 p=SvPV(ST(0),na);
325                 i=BIO_gets(bio,p,1024);
326                 if (i < 0) i=0;
327                 SvCUR_set(ST(0),i);
328
329 int
330 p5_BIO_flush(bio)
331         BIO *bio;
332         CODE:
333                 RETVAL=BIO_flush(bio);
334         OUTPUT:
335                 RETVAL
336
337 char *
338 p5_BIO_type(bio)
339         BIO *bio;
340         CODE:
341                 RETVAL=bio->method->name;
342         OUTPUT:
343                 RETVAL
344
345 void
346 p5_BIO_next_bio(b)
347         BIO *b
348         PREINIT:
349                 BIO *bio;
350                 char *type;
351                 SV *arg;
352         PPCODE:
353                 bio=b->next_bio;
354                 if (bio != NULL)
355                         {
356                         arg=(SV *)BIO_get_ex_data(bio,p5_bio_ex_bio_ptr);
357                         if (arg == NULL)
358                                 {
359                                 arg=new_ref("OpenSSL::BIO",(char *)bio,0);
360                                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,(char *)arg);
361                                 bio->references++;
362                                 PUSHs(arg);
363                                 }
364                         else
365                                 {
366                                 SvREFCNT_inc(arg);
367                                 PUSHs(arg);
368                                 }
369                         }
370
371 int
372 p5_BIO_puts(bio,in)
373         BIO *bio;
374         SV *in;
375         PREINIT:
376                 char *ptr;
377         CODE:
378                 ptr=SvPV(in,na);
379                 RETVAL=BIO_puts(bio,ptr);
380         OUTPUT:
381                 RETVAL
382
383 void
384 p5_BIO_set_callback(bio,cb,...)
385         BIO *bio;
386         SV *cb;
387         PREINIT:
388                 SV *arg=NULL;
389                 SV *arg2=NULL;
390         CODE:
391                 if (items > 3)
392                         croak("Usage: OpenSSL::BIO::set_callback(bio,callback[,arg]");
393                 if (items == 3)
394                         {
395                         arg2=sv_mortalcopy(ST(2));
396                         SvREFCNT_inc(arg2);
397                         BIO_set_ex_data(bio,p5_bio_ex_bio_callback_data,
398                                 (char *)arg2);
399                         }
400                 arg=sv_mortalcopy(ST(1));
401                 SvREFCNT_inc(arg);
402                 BIO_set_ex_data(bio,p5_bio_ex_bio_callback,(char *)arg);
403                 printf("%08lx < bio_ptr\n",BIO_get_ex_data(bio,p5_bio_ex_bio_ptr));
404                 BIO_set_callback(bio,p5_bio_callback);
405
406 void
407 p5_BIO_DESTROY(bio)
408         BIO *bio
409         PREINIT:
410                 SV *sv;
411         PPCODE:
412                 pr_name_d("p5_BIO_DESTROY",bio->references);
413                 printf("p5_BIO_DESTROY <%s> %d\n",bio->method->name,bio->references);
414                 BIO_set_ex_data(bio,p5_bio_ex_bio_ptr,NULL);
415                 BIO_free_all(bio);
416
417 int
418 p5_BIO_set_ssl(bio,ssl)
419         BIO *bio;
420         SSL *ssl;
421         CODE:
422                 pr_name("p5_BIO_set_ssl");
423                 ssl->references++;
424                 RETVAL=BIO_set_ssl(bio,ssl,BIO_CLOSE);
425         OUTPUT:
426                 RETVAL
427
428 int
429 p5_BIO_number_read(bio)
430         BIO *bio;
431         CODE:
432                 RETVAL=BIO_number_read(bio);
433         OUTPUT:
434                 RETVAL
435
436 int
437 p5_BIO_number_written(bio)
438         BIO *bio;
439         CODE:
440                 RETVAL=BIO_number_written(bio);
441         OUTPUT:
442                 RETVAL
443
444 int
445 p5_BIO_references(bio)
446         BIO *bio;
447         CODE:
448                 RETVAL=bio->references; 
449         OUTPUT:
450                 RETVAL
451