typedef struct {
PROTYP proto; //Connexion protocol type
int handle; //connexion handle
+ SSL *ssl; //ssl channel
SSL_CTX *ctx; //encryption context
int maxcarin; //absolute number within carin
char *EOL; //End of line marker
break;
case pro_smtps : //set secure socket
newsoc->ctx=ssl_getctx(true); //ssl in server mode
+ newsoc->ssl=ssl_setsocket(newsoc->handle,newsoc->ctx);
+ if (newsoc->ssl!=(SSL *)0)
+ (void) SSL_set_accept_state(newsoc->ssl);
+ else
+ newsoc=soc_release(newsoc); //trouble trouble
break;
default : //undefined socket type???
(void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)",
*/
/********************************************************/
/* */
+/* Procedure to check if remote certificat is a */
+/* valide one. */
+/* return -1if trouble, 0 otherwise */
+/* */
+/********************************************************/
+PUBLIC int ssl_check_peer(SSL *ssl)
+
+{
+#define OPEP "unissl.c:ssl_check_peer"
+
+int status;
+X509 *peer;
+int phase;
+int proceed;
+
+status=-1;
+peer=(X509 *)0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ (void) printf("JMPDBG phase='%d', check peer\n",phase);
+ switch (phase) {
+ case 0 : //check SSL
+ if (ssl==(SSL *)0) {
+ phase=999; //trouble trouble (Bug?)
+ }
+ break;
+ case 1 : //get peer
+ if ((peer=SSL_get_peer_certificate(ssl))==(X509 *)0) {
+ char reason[200];
+
+ (void) ERR_error_string(ERR_get_error(),reason);
+ (void) rou_alert(2,"%s Unable to get peer certificate (error=<%s>)",
+ OPEP,reason);
+ phase=999; //trouble trouble
+ }
+ break;
+ case 2 : //is peer valid?
+ if (SSL_get_verify_result(ssl)!=X509_V_OK) {
+ char reason[200];
+
+ (void) ERR_error_string(ERR_get_error(),reason);
+ (void) rou_alert(2,"%s Unable to verify certificate (error=<%s>)",
+ OPEP,reason);
+ phase=999; //trouble trouble
+ }
+ (void) X509_free(peer);
+ break;
+ case 3 : //everything is right
+ status=0;
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return status;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to link a socket reference to an */
+/* crypted (SSL) channel. */
+/* return an SSL pointer or a NULL pointer */
+/* */
+/********************************************************/
+PUBLIC SSL *ssl_setsocket(int handle,SSL_CTX *ctx)
+
+{
+#define OPEP "unissl.c:ssl_setsocket"
+
+SSL *ssl;
+int phase;
+_Bool proceed;
+
+ssl=(SSL *)0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //Setting inital context
+ if ((ssl=SSL_new(ctx))==(SSL *)0) {
+ char reason[200];
+
+ (void) ERR_error_string(ERR_get_error(),reason);
+ (void) rou_alert(0,"%S Unable to get a new SSL channel (error=<%s>)",
+ OPEP,reason);
+ phase=999; //trouble trouble
+ }
+ break;
+ case 1 : //assign SSL to socket reference
+ if (SSL_set_fd(ssl,handle)==0) {
+ char reason[200];
+
+ (void) ERR_error_string(ERR_get_error(),reason);
+ (void) rou_alert(0,"%S Unable to set new SSL to socket (error=<%s>)",
+ OPEP,reason);
+ (void) free(ssl);
+ ssl=(SSL *)0;
+ phase=999;
+ }
+ break;
+ case 2 : //verifying SSL channel
+ if (ssl_check_peer(ssl)<0) {
+ (void) rou_alert(0,"%s Unable to check peer certificat",OPEP);
+ (void) free(ssl);
+ ssl=(SSL *)0;
+ phase=999;
+ }
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return ssl;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
/* Procedure to "open/close" module and do */
/* homework purpose */
/* return zero if everything right */