*/
/********************************************************/
/* */
+/* Procedure to wait for characeter to be available*/
+/* on the tls link. */
+/* Wait for at most mili-second time. */
+/* */
+/********************************************************/
+PUBLIC int tls_waitforchar(TLSTYP *tls,u_int millisec)
+
+{
+#define OPEP "unitls.c:tls_waitforchar,"
+
+int status;
+struct pollfd polling[1];
+_Bool proceed;
+int phase;
+
+status=-1;
+polling[0].events=POLLIN|POLLPRI;
+polling[0].revents=(short)0;
+proceed=true;
+phase=0;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //check TLS
+ if ((tls==(TLSTYP *)0)||(tls->handle<0)) {
+ (void) rou_alert(0,"%s TLS is not available (Bug?)",OPEP);
+ phase=999; //trouble trouble (Bug?)
+ }
+ break;
+ case 1 : //lets assume we are cleartext mode
+ polling[0].fd=tls->handle;
+ if (tls->tls==true) { //we are crypted mode
+ if (tls->ssl==(SSL *)0) { //Is ssl definined
+ (void) rou_alert(0,"%s Crypted mode but no SSL (Bug?)",OPEP);
+ phase=999; //trouble trouble (Bug?)
+ }
+ else
+ polling[0].fd=SSL_get_fd(tls->ssl);
+ }
+ break;
+ case 2 : //lets wait for char
+ status=poll(polling,1,millisec);
+ switch (status) {
+ case -1 : //Polling error
+ (void) rou_alert(0,"%s Polling error (error=<%s>",OPEP,strerror(errno));
+ break;
+ case 0 : //polling time out
+ //nothing to do
+ break;
+ case 1 : //char is available.
+ //nothing to do
+ break;
+ }
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return status;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to accept a TLS connection from a */
+/* remote client. */
+/* */
+/********************************************************/
+PUBLIC int tls_accept(TLSTYP *tls)
+
+{
+#define OPEP "unitls.c:tls_accept,"
+
+int statut;
+X509 *peer;
+int tic;
+int done;
+
+statut=-1;
+peer=(X509 *)0;
+tic=30; //30 second MAX to extablish SSL connexio
+done=false;
+if ((tls->bio=BIO_new_fd(tls->handle,BIO_NOCLOSE))==(BIO *)0) {
+ (void) rou_core_dump("%s Unable to get the BIO (error=<%s>)",
+ OPEP,strerror(errno));
+ }
+(void) SSL_set_bio(tls->ssl,tls->bio,tls->bio);
+while (done==false) {
+ int sslerr;
+
+ statut=SSL_accept(tls->ssl);
+ switch (sslerr=SSL_get_error(tls->ssl,statut)) {
+ case SSL_ERROR_NONE :
+ statut=0;
+ if ((peer=SSL_get_peer_certificate(tls->ssl))!=(X509 *)0) {
+ if (SSL_get_verify_result(tls->ssl)!=X509_V_OK)
+ statut=-1;
+ (void) X509_free(peer);
+ }
+ done=true;
+ break;
+ case SSL_ERROR_WANT_READ :
+ switch(tls_waitforchar(tls,(u_int)1000)) {
+ case -1 :
+ switch(errno) { /*received a signal, lets see...*/
+ case EINTR : /*could be a TERM signal */
+ break;
+ default : /*hummm real code fault report */
+ (void) rou_core_dump("%s poll error '%s'",OPEP,strerror(errno));
+ done=true;
+ statut=-1;
+ break;
+ }
+ break;
+ case 0 : /*standard time out */
+ tic--;
+ if (tic<=0) {
+ done=true;
+ (void) rou_alert(0,"%s, SSL_accept too long to establish",OPEP);
+ statut=-1;
+ }
+ break;
+ default :
+ break;
+ }
+ break;
+#ifdef SSL_ERROR_WANT_ACCEPT
+ case SSL_ERROR_WANT_ACCEPT :
+#endif
+ case SSL_ERROR_WANT_WRITE :
+ break;
+ case SSL_ERROR_SYSCALL: /*EOF received */
+ if (ERR_get_error()==0)
+ tls->goteof=true;
+ else
+ (void) showtlserror(tls,statut,"%s SSL_SYSCALL pbs",OPEP);
+ statut=-1;
+ done=true;
+ break;
+ default :
+ (void) showtlserror(tls,statut,"%s SSL_accept fatal error "
+ "(sslerr='%d')",OPEP,sslerr);
+ statut=-1;
+ done=true;
+ break;
+ }
+ }
+return statut;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
/* Procedure to check if remote certificat is a */
/* valide one. */
/* return -1if trouble, 0 otherwise */
typedef struct {
_Bool server; //SSL server/client mode
_Bool goteof; //SSL End Of File
+ _Bool tls; //link in TLS (crypted) mode
+ BIO *bio; //SSL Basic IO
int handle; //device handle
char *peerip; //Remote IP number
char *locip; //Local IP number
//read from the SSL channel
extern int tls_read(TLSTYP *tls,char *buffer,int maxread);
-//accept a TLS connection
+//wait for a char alvalable on channel
+extern int tls_waitforchar(TLSTYP *tls,u_int millisec);
+
+//accept from a TLS client connection
extern int tls_accept(TLSTYP *tls);
+//connect to a TLS serveur connection
+extern int tls_connect(TLSTYP *tls);
+
//check peer certificat
extern int tls_check_peer(TLSTYP *tls);