1 /*
2  **      $Id: context.c 1038 2009-01-07 17:33:42Z aaron $
3  */
4 /************************************************************************
5  *                                                                      *
6  *                             Copyright (C)  2002                      *
7  *                                Internet2                             *
8  *                             All Rights Reserved                      *
9  *                                                                      *
10  ************************************************************************/
11 /*
12  **        File:        context.c
13  **
14  **        Author:      Jeff W. Boote
15  **                     Anatoly Karp
16  **
17  **        Date:        Fri Apr 12 09:11:31  2002
18  **
19  **        Description:
20  */
21 #include "owampP.h"
22 
23 #include <assert.h>
24 #include <signal.h>
25 
26 
27 /*
28  * Function:        notmuch
29  *
30  * Description:
31  *                 "do nothing" signal handler. Put in place to ensure
32  *                 SIGCHLD events are received.
33  *
34  * In Args:
35  *
36  * Out Args:
37  *
38  * Scope:
39  * Returns:
40  * Side Effect:
41  */
42 static void
notmuch(int signo)43 notmuch(
44         int signo
45        )
46 {
47     switch(signo){
48         case SIGCHLD:
49             break;
50         default:
51             abort();
52             raise(SIGFPE);
53     }
54 }
55 
56 /*
57  * Function:        OWPContextCreate
58  *
59  * Description:
60  *         This function is used to initialize a "context" for the owamp
61  *         library. The context is used to define how error reporting
62  *         and other semi-global state should be defined.
63  *
64  * In Args:
65  *
66  * Out Args:
67  *
68  * Scope:
69  * Returns:
70  * Side Effect:
71  */
72 OWPContext
OWPContextCreate(I2ErrHandle eh)73 OWPContextCreate(
74         I2ErrHandle eh
75         )
76 {
77     struct sigaction    act;
78     I2LogImmediateAttr  ia;
79     OWPContext          ctx = calloc(1,sizeof(OWPContextRec));
80 
81     if(!ctx){
82         OWPError(eh,
83                 OWPErrFATAL,ENOMEM,":calloc(1,%d):%M",
84                 sizeof(OWPContextRec));
85         return NULL;
86     }
87 
88     if(!eh){
89         ctx->lib_eh = True;
90         ia.line_info = (I2NAME|I2MSG);
91         ia.fp = stderr;
92         ctx->eh = I2ErrOpen("libowamp",I2ErrLogImmediate,&ia,
93                 NULL,NULL);
94         if(!ctx->eh){
95             OWPError(NULL,OWPErrFATAL,OWPErrUNKNOWN,
96                     "Cannot init error module");
97             free(ctx);
98             return NULL;
99         }
100     }
101     else{
102         ctx->lib_eh = False;
103         ctx->eh = eh;
104     }
105 
106     if(_OWPInitNTP(ctx) != 0){
107         OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,
108                 "Unable to initialize clock interface.");
109         OWPContextFree(ctx);
110         return NULL;
111     }
112 
113     if( !(ctx->table = I2HashInit(ctx->eh,_OWP_CONTEXT_TABLE_SIZE,
114                     NULL,NULL))){
115         OWPContextFree(ctx);
116         return NULL;
117     }
118 
119     if( !(ctx->rand_src = I2RandomSourceInit(ctx->eh,I2RAND_DEV,NULL))){
120         OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,
121                 "Failed to initialize randomness sources");
122         OWPContextFree(ctx);
123         return NULL;
124     }
125 
126     if( !OWPContextConfigGetU32(ctx,OWPKeyDerivationCount,&ctx->pbkdf2_count)){
127         ctx->pbkdf2_count = _OWP_DEFAULT_PBKDF2_COUNT;
128     }
129 
130     /*
131      * Do NOT exit on SIGPIPE. To defeat this in the least intrusive
132      * way only set SIG_IGN if SIGPIPE is currently set to SIG_DFL.
133      * Presumably if someone actually set a SIGPIPE handler, they
134      * knew what they were doing...
135      */
136     sigemptyset(&act.sa_mask);
137     act.sa_handler = SIG_DFL;
138     act.sa_flags = 0;
139     if(sigaction(SIGPIPE,NULL,&act) != 0){
140         OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,"sigaction(): %M");
141         OWPContextFree(ctx);
142         return NULL;
143     }
144     if(act.sa_handler == SIG_DFL){
145         act.sa_handler = SIG_IGN;
146         if(sigaction(SIGPIPE,&act,NULL) != 0){
147             OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,
148                     "sigaction(): %M");
149             OWPContextFree(ctx);
150             return NULL;
151         }
152     }
153 
154     /*
155      * This library uses calls to select that are intended to
156      * interrupt select in the case of SIGCHLD, so I must
157      * ensure that the process is getting SIGCHLD events.
158      */
159     memset(&act,0,sizeof(act));
160     sigemptyset(&act.sa_mask);
161     act.sa_handler = SIG_DFL;
162     /* fetch current handler */
163     if(sigaction(SIGCHLD,NULL,&act) != 0){
164         OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,"sigaction(): %M");
165         OWPContextFree(ctx);
166         return NULL;
167     }
168     /* If there is no current handler - set a "do nothing" one. */
169     if(act.sa_handler == SIG_DFL){
170         act.sa_handler = notmuch;
171         if(sigaction(SIGCHLD,&act,NULL) != 0){
172             OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,
173                     "sigaction(): %M");
174             OWPContextFree(ctx);
175             return NULL;
176         }
177     }
178 
179     return ctx;
180 }
181 
182 /*
183  * Function:        OWPContextErrHandle
184  *
185  * Description:
186  *         Returns the ErrHandle that was set for this context upon creation.
187  *
188  * In Args:
189  *
190  * Out Args:
191  *
192  * Scope:
193  * Returns:
194  * Side Effect:
195  */
196 extern I2ErrHandle
OWPContextErrHandle(OWPContext ctx)197 OWPContextErrHandle(
198         OWPContext  ctx
199         )
200 {
201     return ctx->eh;
202 }
203 
204 typedef union _OWPContextHashValue{
205     void        *value;
206     void        (*func)(void);
207     uint32_t    u32;
208 } _OWPContextHashValue;
209 
210 struct _OWPContextHashRecord{
211     char                    key[_OWP_CONTEXT_MAX_KEYLEN+1];
212     _OWPContextHashValue    val;
213 };
214 
215 struct _OWPFreeHashRecord{
216     OWPContext  ctx;
217     I2Table     table;
218 };
219 
220 static I2Boolean
free_hash_entries(I2Datum key,I2Datum value,void * app_data)221 free_hash_entries(
222         I2Datum key,
223         I2Datum value,
224         void    *app_data
225         )
226 {
227     struct _OWPFreeHashRecord   *frec = (struct _OWPFreeHashRecord*)app_data;
228 
229     /*
230      * Delete hash so key.dptr will not be referenced again.
231      * (key.dptr is part of value.dptr alloc)
232      */
233     if(I2HashDelete(frec->table,key) != 0){
234         OWPError(frec->ctx,OWPErrFATAL,OWPErrUNKNOWN,
235                 "Unable to clean out Context hash?");
236         return False;
237     }
238 
239     free(value.dptr);
240 
241     return True;
242 }
243 
244 
245 void
OWPContextFree(OWPContext ctx)246 OWPContextFree(
247         OWPContext  ctx
248         )
249 {
250     struct _OWPFreeHashRecord   frec;
251 
252     while(ctx->cntrl_list){
253         OWPControlClose(ctx->cntrl_list);
254     }
255 
256     frec.ctx = ctx;
257     frec.table = ctx->table;
258 
259     if(ctx->table){
260         I2HashIterate(ctx->table,free_hash_entries,(void*)&frec);
261         I2HashClose(ctx->table);
262         ctx->table = NULL;
263     }
264 
265     if(ctx->rand_src){
266         I2RandomSourceClose(ctx->rand_src);
267         ctx->rand_src = NULL;
268     }
269 
270     if(ctx->lib_eh && ctx->eh){
271         I2ErrClose(ctx->eh);
272         ctx->eh = NULL;
273     }
274 
275     free(ctx);
276 
277     return;
278 }
279 
280 OWPErrSeverity
OWPControlClose(OWPControl cntrl)281 OWPControlClose(
282         OWPControl  cntrl
283         )
284 {
285     OWPErrSeverity              err = OWPErrOK;
286     OWPErrSeverity              lerr = OWPErrOK;
287     struct _OWPFreeHashRecord   frec;
288     OWPControl                  *list = &cntrl->ctx->cntrl_list;
289 
290     /*
291      * remove all test sessions
292      */
293     while(cntrl->tests){
294         lerr = _OWPTestSessionFree(cntrl->tests,OWP_CNTRL_FAILURE);
295         err = MIN(err,lerr);
296     }
297 
298     frec.ctx = cntrl->ctx;
299     frec.table = cntrl->table;
300 
301     if(cntrl->table){
302         I2HashIterate(cntrl->table,free_hash_entries,(void*)&frec);
303         I2HashClose(cntrl->table);
304     }
305 
306     if(cntrl->send_hmac_ctx){
307         I2HMACSha1Free(cntrl->send_hmac_ctx);
308         cntrl->send_hmac_ctx = NULL;
309     }
310     if(cntrl->recv_hmac_ctx){
311         I2HMACSha1Free(cntrl->recv_hmac_ctx);
312         cntrl->recv_hmac_ctx = NULL;
313     }
314 
315     /*
316      * Remove cntrl from ctx list.
317      */
318     while(*list && (*list != cntrl))
319         list = &(*list)->next;
320     if(*list == cntrl)
321         *list = cntrl->next;
322 
323     /*
324      * these functions will close the control socket if it is open.
325      */
326     I2AddrFree(cntrl->remote_addr);
327     I2AddrFree(cntrl->local_addr);
328 
329     free(cntrl);
330 
331     return err;
332 }
333 
334 OWPControl
_OWPControlAlloc(OWPContext ctx,OWPErrSeverity * err_ret)335 _OWPControlAlloc(
336         OWPContext      ctx,
337         OWPErrSeverity  *err_ret
338         )
339 {
340     OWPControl  cntrl;
341 
342     /*
343      * Use calloc to alloc memory so it will be initialized to 0.
344      */
345     if( !(cntrl = calloc(1,sizeof(OWPControlRec)))){
346         OWPError(ctx,OWPErrFATAL,errno,
347                 ":calloc(1,%d)",sizeof(OWPControlRec));
348         *err_ret = OWPErrFATAL;
349         return NULL;
350     }
351 
352     /*
353      * Init state fields
354      */
355     cntrl->ctx = ctx;
356 
357     /*
358      * Initialize control policy state hash.
359      */
360     if( !(cntrl->table = I2HashInit(ctx->eh,_OWP_CONTEXT_TABLE_SIZE,
361                     NULL,NULL))){
362         goto error;
363     }
364 
365     /*
366      * Init addr fields
367      */
368     cntrl->sockfd = -1;
369 
370     /*
371      * Init I/O fields
372      */
373     cntrl->retn_on_intr = (int *)OWPContextConfigGetV(ctx,OWPInterruptIO);
374 
375     /*
376      * Init encryption fields
377      */
378     memset(cntrl->userid_buffer,'\0',sizeof(cntrl->userid_buffer));
379 
380     if( !(cntrl->send_hmac_ctx = I2HMACSha1Alloc(ctx->eh))){
381         goto error;
382     }
383     if( !(cntrl->recv_hmac_ctx = I2HMACSha1Alloc(ctx->eh))){
384         goto error;
385     }
386 
387     /*
388      * Put this control record on the ctx list.
389      */
390     cntrl->next = ctx->cntrl_list;
391     ctx->cntrl_list = cntrl;
392 
393     return cntrl;
394 
395 error:
396     *err_ret = OWPErrFATAL;
397     if(cntrl){
398         if(cntrl->send_hmac_ctx){
399             I2HMACSha1Free(cntrl->send_hmac_ctx);
400         }
401         if(cntrl->recv_hmac_ctx){
402             I2HMACSha1Free(cntrl->recv_hmac_ctx);
403         }
404         free(cntrl);
405     }
406     return NULL;
407 }
408 
409 static OWPBoolean
ConfigSetU(I2Table table,const char * key,_OWPContextHashValue val)410 ConfigSetU(
411         I2Table                 table,
412         const char              *key,
413         _OWPContextHashValue    val
414         )
415 {
416     struct _OWPContextHashRecord    *rec,*trec;
417     I2Datum                         k,v,t;
418 
419     assert(table);
420     assert(key);
421 
422     if(!(rec = calloc(1,sizeof(struct _OWPContextHashRecord)))){
423         return False;
424     }
425     /* ensure nul byte */
426     rec->key[_OWP_CONTEXT_MAX_KEYLEN] = '\0';
427 
428     /* set key datum */
429     strncpy(rec->key,key,_OWP_CONTEXT_MAX_KEYLEN);
430     rec->val = val;
431 
432     k.dptr = rec->key;
433     k.dsize = strlen(rec->key);
434 
435     /* set value datum */
436     v.dptr = rec;
437     v.dsize = sizeof(rec);
438 
439     /*
440      * If there is already a key by this entry - free that record.
441      */
442     if(I2HashFetch(table,k,&t)){
443         trec = (struct _OWPContextHashRecord*)t.dptr;
444         I2HashDelete(table,k);
445         free(trec);
446     }
447 
448     if(I2HashStore(table,k,v) == 0){
449         return True;
450     }
451 
452     free(rec);
453     return False;
454 }
455 
456 static OWPBoolean
ConfigSetV(I2Table table,const char * key,void * value)457 ConfigSetV(
458         I2Table     table,
459         const char  *key,
460         void        *value
461         )
462 {
463     _OWPContextHashValue    val;
464 
465     val.value = value;
466     return ConfigSetU(table,key,val);
467 }
468 
469 static OWPBoolean
ConfigSetU32(I2Table table,const char * key,uint32_t u32)470 ConfigSetU32(
471         I2Table     table,
472         const char  *key,
473         uint32_t    u32
474         )
475 {
476     _OWPContextHashValue    val;
477 
478     val.u32 = u32;
479     return ConfigSetU(table,key,val);
480 }
481 
482 static OWPBoolean
ConfigSetF(I2Table table,const char * key,void (* func)(void))483 ConfigSetF(
484         I2Table     table,
485         const char  *key,
486         void        (*func)(void)
487         )
488 {
489     _OWPContextHashValue    val;
490 
491     val.func = func;
492     return ConfigSetU(table,key,val);
493 }
494 
495 static OWPBoolean
ConfigGetU(I2Table table,const char * key,_OWPContextHashValue * val)496 ConfigGetU(
497         I2Table                 table,
498         const char              *key,
499         _OWPContextHashValue    *val
500         )
501 {
502     struct _OWPContextHashRecord    *rec;
503     I2Datum                         k,v;
504     char                            kval[_OWP_CONTEXT_MAX_KEYLEN+1];
505 
506     assert(key);
507 
508     kval[_OWP_CONTEXT_MAX_KEYLEN] = '\0';
509     strncpy(kval,key,_OWP_CONTEXT_MAX_KEYLEN);
510     k.dptr = kval;
511     k.dsize = strlen(kval);
512 
513     if(!I2HashFetch(table,k,&v)){
514         return False;
515     }
516 
517     rec = (struct _OWPContextHashRecord*)v.dptr;
518     *val = rec->val;
519 
520     return True;
521 }
522 
523 static void *
ConfigGetV(I2Table table,const char * key)524 ConfigGetV(
525         I2Table     table,
526         const char  *key
527         )
528 {
529     _OWPContextHashValue    val;
530 
531     if( !ConfigGetU(table,key,&val)){
532         return NULL;
533     }
534 
535     return val.value;
536 }
537 
538 static OWPBoolean
ConfigGetU32(I2Table table,const char * key,uint32_t * u32)539 ConfigGetU32(
540         I2Table     table,
541         const char  *key,
542         uint32_t    *u32
543         )
544 {
545     _OWPContextHashValue    val;
546 
547     if( !ConfigGetU(table,key,&val)){
548         return False;
549     }
550 
551     *u32 = val.u32;
552 
553     return True;
554 }
555 
ConfigGetF(I2Table table,const char * key)556 static OWPFunc ConfigGetF(
557         I2Table     table,
558         const char  *key
559         )
560 {
561     _OWPContextHashValue    val;
562 
563     if( !ConfigGetU(table,key,&val)){
564         return NULL;
565     }
566 
567     return val.func;
568 }
569 
570 static OWPBoolean
ConfigDelete(I2Table table,const char * key)571 ConfigDelete(
572         I2Table     table,
573         const char  *key
574         )
575 {
576     I2Datum k;
577     char    kval[_OWP_CONTEXT_MAX_KEYLEN+1];
578 
579     assert(key);
580 
581     kval[_OWP_CONTEXT_MAX_KEYLEN] = '\0';
582     strncpy(kval,key,_OWP_CONTEXT_MAX_KEYLEN);
583     k.dptr = kval;
584     k.dsize = strlen(kval);
585 
586     if(I2HashDelete(table,k) == 0){
587         return True;
588     }
589 
590     return False;
591 }
592 
593 /*
594  * Function:        OWPContextSet
595  *
596  * Description:
597  *
598  * In Args:
599  *
600  * Out Args:
601  *
602  * Scope:
603  * Returns:
604  * Side Effect:
605  */
606 OWPBoolean
OWPContextConfigSetV(OWPContext ctx,const char * key,void * value)607 OWPContextConfigSetV(
608         OWPContext  ctx,
609         const char  *key,
610         void        *value
611         )
612 {
613     assert(ctx);
614 
615     return ConfigSetV(ctx->table,key,value);
616 }
617 
618 OWPBoolean
OWPContextConfigSetF(OWPContext ctx,const char * key,OWPFunc func)619 OWPContextConfigSetF(
620         OWPContext  ctx,
621         const char  *key,
622         OWPFunc     func
623         )
624 {
625     assert(ctx);
626 
627     return ConfigSetF(ctx->table,key,func);
628 }
629 
630 OWPBoolean
OWPContextConfigSetU32(OWPContext ctx,const char * key,uint32_t u32)631 OWPContextConfigSetU32(
632         OWPContext  ctx,
633         const char  *key,
634         uint32_t    u32
635         )
636 {
637     assert(ctx);
638 
639     return ConfigSetU32(ctx->table,key,u32);
640 }
641 
642 void *
OWPContextConfigGetV(OWPContext ctx,const char * key)643 OWPContextConfigGetV(
644         OWPContext  ctx,
645         const char  *key
646         )
647 {
648     assert(ctx);
649 
650     return ConfigGetV(ctx->table,key);
651 }
652 
653 OWPBoolean
OWPContextConfigGetU32(OWPContext ctx,const char * key,uint32_t * u32)654 OWPContextConfigGetU32(
655         OWPContext  ctx,
656         const char  *key,
657         uint32_t    *u32
658         )
659 {
660     assert(ctx);
661 
662     return ConfigGetU32(ctx->table,key,u32);
663 }
664 
665 OWPFunc
OWPContextConfigGetF(OWPContext ctx,const char * key)666 OWPContextConfigGetF(
667         OWPContext  ctx,
668         const char  *key
669         )
670 {
671     assert(ctx);
672 
673     return ConfigGetF(ctx->table,key);
674 }
675 
676 OWPBoolean
OWPContextConfigDelete(OWPContext ctx,const char * key)677 OWPContextConfigDelete(
678         OWPContext  ctx,
679         const char  *key
680         )
681 {
682     assert(ctx);
683 
684     return ConfigDelete(ctx->table,key);
685 }
686 
687 /*
688  * Function:        OWPControlSet
689  *
690  * Description:
691  *
692  * In Args:
693  *
694  * Out Args:
695  *
696  * Scope:
697  * Returns:
698  * Side Effect:
699  */
700 OWPBoolean
OWPControlConfigSetV(OWPControl cntrl,const char * key,void * value)701 OWPControlConfigSetV(
702         OWPControl  cntrl,
703         const char  *key,
704         void        *value
705         )
706 {
707     assert(cntrl);
708 
709     return ConfigSetV(cntrl->table,key,value);
710 }
711 
712 OWPBoolean
OWPControlConfigSetU32(OWPControl cntrl,const char * key,uint32_t u32)713 OWPControlConfigSetU32(
714         OWPControl  cntrl,
715         const char  *key,
716         uint32_t    u32
717         )
718 {
719     assert(cntrl);
720 
721     return ConfigSetU32(cntrl->table,key,u32);
722 }
723 
724 OWPBoolean
OWPControlConfigSetF(OWPControl cntrl,const char * key,OWPFunc func)725 OWPControlConfigSetF(
726         OWPControl  cntrl,
727         const char  *key,
728         OWPFunc     func
729         )
730 {
731     assert(cntrl);
732 
733     return ConfigSetF(cntrl->table,key,func);
734 }
735 
736 void *
OWPControlConfigGetV(OWPControl cntrl,const char * key)737 OWPControlConfigGetV(
738         OWPControl  cntrl,
739         const char  *key
740         )
741 {
742     assert(cntrl);
743 
744     return ConfigGetV(cntrl->table,key);
745 }
746 
747 OWPBoolean
OWPControlConfigGetU32(OWPControl cntrl,const char * key,uint32_t * u32)748 OWPControlConfigGetU32(
749         OWPControl  cntrl,
750         const char  *key,
751         uint32_t    *u32
752         )
753 {
754     assert(cntrl);
755 
756     return ConfigGetU32(cntrl->table,key,u32);
757 }
758 
759 OWPFunc
OWPControlConfigGetF(OWPControl cntrl,const char * key)760 OWPControlConfigGetF(
761         OWPControl  cntrl,
762         const char  *key
763         )
764 {
765     assert(cntrl);
766 
767     return ConfigGetF(cntrl->table,key);
768 }
769 
770 OWPBoolean
OWPControlConfigDelete(OWPControl cntrl,const char * key)771 OWPControlConfigDelete(
772         OWPControl  cntrl,
773         const char  *key
774         )
775 {
776     assert(cntrl);
777 
778     return ConfigDelete(cntrl->table,key);
779 }
780 
781 /*
782  * Function:        _OWPCallGetPF
783  *
784  * Description:
785  *         Calls the get_pf function that is defined by the application.
786  *         If the application didn't define the get_pf function, then provide
787  *         the default response of False.
788  */
789 OWPBoolean
_OWPCallGetPF(OWPContext ctx,const OWPUserID userid,uint8_t ** pf_ret,size_t * pf_len,void ** pf_free,OWPErrSeverity * err_ret)790 _OWPCallGetPF(
791         OWPContext      ctx,        /* library context  */
792         const OWPUserID userid,     /* identifies user  */
793         uint8_t         **pf_ret,   /* pf - return      */
794         size_t          *pf_len,    /* pf_len - return  */
795         void            **pf_free,  /* pf_free - return */
796         OWPErrSeverity  *err_ret    /* error - return   */
797         )
798 {
799     OWPGetPFFunc    func;
800 
801     *err_ret = OWPErrOK;
802 
803     func = (OWPGetPFFunc)OWPContextConfigGetF(ctx,OWPGetPF);
804 
805     /*
806      * Default action is no encryption support.
807      */
808     if(!func){
809         return False;
810     }
811 
812     return func(ctx,userid,pf_ret,pf_len,pf_free,err_ret);
813 }
814 
815 /*
816  * Function:        _OWPCallCheckControlPolicy
817  *
818  * Description:
819  *         Calls the check_control_func that is defined by the application.
820  *         If the application didn't define the check_control_func, then provide
821  *         the default response of True(allowed).
822  */
823 OWPBoolean
_OWPCallCheckControlPolicy(OWPControl cntrl,OWPSessionMode mode,const OWPUserID userid,struct sockaddr * local_sa_addr,struct sockaddr * remote_sa_addr,OWPErrSeverity * err_ret)824 _OWPCallCheckControlPolicy(
825         OWPControl      cntrl,              /* control record       */
826         OWPSessionMode  mode,               /* requested mode       */
827         const OWPUserID userid,             /* key identity         */
828         struct sockaddr *local_sa_addr,     /* local addr or NULL   */
829         struct sockaddr *remote_sa_addr,    /* remote addr          */
830         OWPErrSeverity  *err_ret            /* error - return       */
831         )
832 {
833     OWPCheckControlPolicyFunc   func;
834 
835     *err_ret = OWPErrOK;
836 
837     func = (OWPCheckControlPolicyFunc)OWPContextConfigGetF(cntrl->ctx,
838             OWPCheckControlPolicy);
839 
840     /*
841      * Default action is to allow anything.
842      */
843     if(!func){
844         return True;
845     }
846 
847     return func(cntrl,mode,userid,local_sa_addr,remote_sa_addr,err_ret);
848 }
849 
850 /*
851  * Function:        _OWPCallCheckTestPolicy
852  *
853  * Description:
854  *         Calls the check_test_func that is defined by the application.
855  *         If the application didn't define the check_test_func, then provide
856  *         the default response of True(allowed).
857  */
858 OWPBoolean
_OWPCallCheckTestPolicy(OWPControl cntrl,OWPBoolean local_sender,struct sockaddr * local,struct sockaddr * remote,socklen_t sa_len,OWPTestSpec * test_spec,void ** closure,OWPErrSeverity * err_ret)859 _OWPCallCheckTestPolicy(
860         OWPControl      cntrl,          /* control handle           */
861         OWPBoolean      local_sender,   /* Is local send or recv    */
862         struct sockaddr *local,         /* local endpoint           */
863         struct sockaddr *remote,        /* remote endpoint          */
864         socklen_t       sa_len,         /* saddr lens               */
865         OWPTestSpec     *test_spec,     /* test requested           */
866         void            **closure,
867         OWPErrSeverity  *err_ret        /* error - return           */
868         )
869 {
870     OWPCheckTestPolicyFunc  func;
871 
872     *err_ret = OWPErrOK;
873 
874     func = (OWPCheckTestPolicyFunc)OWPContextConfigGetF(cntrl->ctx,
875             OWPCheckTestPolicy);
876     /*
877      * Default action is to allow anything.
878      */
879     if(!func){
880         return True;
881     }
882 
883     return func(cntrl,local_sender,local,remote,sa_len,test_spec,closure,
884             err_ret);
885 }
886 
887 /*
888  * Function:        _OWPCallCheckFetchPolicy
889  *
890  * Description:
891  *         Calls the check_test_func that is defined by the application.
892  *         If the application didn't define the check_test_func, then provide
893  *         the default response of True(allowed).
894  */
895 OWPBoolean
_OWPCallCheckFetchPolicy(OWPControl cntrl,struct sockaddr * local,struct sockaddr * remote,socklen_t sa_len,uint32_t begin,uint32_t end,OWPSID sid,void ** closure,OWPErrSeverity * err_ret)896 _OWPCallCheckFetchPolicy(
897         OWPControl      cntrl,          /* control handle           */
898         struct sockaddr *local,         /* local endpoint           */
899         struct sockaddr *remote,        /* remote endpoint          */
900         socklen_t       sa_len,         /* saddr lens               */
901         uint32_t        begin,
902         uint32_t        end,
903         OWPSID          sid,
904         void            **closure,
905         OWPErrSeverity  *err_ret        /* error - return           */
906         )
907 {
908     OWPCheckFetchPolicyFunc  func;
909 
910     *err_ret = OWPErrOK;
911 
912     func = (OWPCheckFetchPolicyFunc)OWPContextConfigGetF(cntrl->ctx,
913             OWPCheckFetchPolicy);
914     /*
915      * Default action is to allow anything.
916      */
917     if(!func){
918         return True;
919     }
920 
921     return func(cntrl,local,remote,sa_len,begin,end,sid,closure,err_ret);
922 }
923 
924 /*
925  * Function:        _OWPCallTestComplete
926  *
927  * Description:
928  *         Calls the "OWPTestComplete" that is defined by the application.
929  *         If the application didn't define the "OWPTestComplete" function, then
930  *         this is a no-op.
931  *
932  *         The primary use for this hook is to free memory and other resources
933  *         (bandwidth etc...) allocated on behalf of this test.
934  */
935 void
_OWPCallTestComplete(OWPTestSession tsession,OWPAcceptType aval)936 _OWPCallTestComplete(
937         OWPTestSession  tsession,
938         OWPAcceptType   aval
939         )
940 {
941     OWPTestCompleteFunc func;
942 
943     func = (OWPTestCompleteFunc)OWPContextConfigGetF(tsession->cntrl->ctx,
944             OWPTestComplete);
945     /*
946      * Default action is nothing...
947      */
948     if(!func){
949         return;
950     }
951 
952     func(tsession->cntrl,tsession->closure,aval);
953 
954     return;
955 }
956 
957 /*
958  * Function:        _OWPCallOpenFile
959  *
960  * Description:
961  *         Calls the "OWPOpenFile" that is defined by the application.
962  *         If the application didn't define the "OWPOpenFile" function, then
963  *         it won't be able to implement the "FetchSession" functionality or
964  *         run a "receive" endpoint from a "server" point-of-view.
965  *
966  *         (This is not needed from the client point-of-view since it passes
967  *         a FILE* into the retrieve/receiver functions directly.)
968  *
969  *         (basically - this is a hook to allow relatively simple changes
970  *         to the way owampd saves/fetches session data.)
971  *
972  *         The "closure" pointer is a pointer to the value that is returned
973  *         from the CheckTestPolicy or CheckFetchPolicy function. This is
974  *         the way resource requests/releases can be adjusted based upon
975  *         actual use.
976  *
977  *         (keeping policy separate from function is challenging... I hope
978  *         it is worth it...)
979  *
980  */
981 FILE *
_OWPCallOpenFile(OWPControl cntrl,void * closure,OWPSID sid,char fname_ret[PATH_MAX])982 _OWPCallOpenFile(
983         OWPControl  cntrl,              /* control handle   */
984         void        *closure,           /* null if r/o      */
985         OWPSID      sid,                /* sid              */
986         char        fname_ret[PATH_MAX] /* return name      */
987         )
988 {
989     OWPOpenFileFunc func;
990 
991     func = (OWPOpenFileFunc)OWPContextConfigGetF(cntrl->ctx,
992             OWPOpenFile);
993     /*
994      * Default action is nothing...
995      */
996     if(!func){
997         return NULL;
998     }
999 
1000     return func(cntrl,closure,sid,fname_ret);
1001 }
1002 
1003 /*
1004  * Function:        _OWPCallCloseFile
1005  *
1006  * Description:
1007  *         Calls the "OWPCloseFile" that is defined by the application.
1008  *         If the application didn't define the "OWPCloseFile" function, then
1009  *         fclose will be called on the fp.
1010  *
1011  *         (The primary use for this hook is to implement the delete-on-fetch
1012  *         functionality. i.e. once this is called on a file with that policy
1013  *         setting, unlink can be called on the file.)
1014  */
1015 void
_OWPCallCloseFile(OWPControl cntrl,void * closure,FILE * fp,OWPAcceptType aval)1016 _OWPCallCloseFile(
1017         OWPControl      cntrl,      /* control handle   */
1018         void            *closure,
1019         FILE            *fp,
1020         OWPAcceptType   aval
1021         )
1022 {
1023     OWPCloseFileFunc    func;
1024 
1025     func = (OWPCloseFileFunc)OWPContextConfigGetF(cntrl->ctx,
1026             OWPCloseFile);
1027     /*
1028      * Default action is nothing...
1029      */
1030     if(!func){
1031         int rc;
1032 
1033         while(((rc = fclose(fp)) != 0) && (errno == EINTR));
1034         if(rc != 0){
1035             OWPError(cntrl->ctx,OWPErrFATAL,errno,"fclose(): %M");
1036         }
1037         return;
1038     }
1039 
1040     func(cntrl,closure,fp,aval);
1041 
1042     return;
1043 }
1044