Search squid archive

Re: Ssl-Bump and revoked server certificates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04.10.2015 21:08, Walter H. wrote:
Hello,

does anybody know if squid does certificate checks and how to tell squid to do so;

this is a site with a revoked certificate
https://revoked.grc.com/

without squid, the browser shows that the certificate is revoked and doesn't show the page
with squid, the page is shown ...

Thanks,
Walter

I have solved it:

my solution not only does certificate checks using OCSP, it also stores the real certificates into a different "database" folder;
if someone doesn't want this, just remove the few lines of the shell script;
as there exist no CA that allows IP adresses neither in certificate subject nor in the SAN (subject alternative name),

https://www.whitehouse.gov/
(is blocked at my solution because of a root certificate not in the cert store)

all these candidates are blocked with error 
X509_V_ERR_CERT_REJECTED
it uses two components:

- a shell script (BASH) called by the programme
- the main programme (in C): the only missing is an exception list of domains/hosts not to validate through this procedure

the squid.conf is expanded by these lines:

<squid.conf>
acl certSelfSigned ssl_error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
acl certHasExpired ssl_error X509_V_ERR_CERT_HAS_EXPIRED
acl certNotValid ssl_error X509_V_ERR_CERT_NOT_YET_VALID
acl certRejected ssl_error X509_V_ERR_CERT_REJECTED
acl certRevoked ssl_error X509_V_ERR_CERT_REVOKED
acl certUntrusted ssl_error X509_V_ERR_CERT_UNTRUSTED

acl certSelfSignedChain ssl_error X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
acl certChainTooLong ssl_error X509_V_ERR_CERT_CHAIN_TOO_LONG
acl certPathLengthExceeded ssl_error X509_V_ERR_PATH_LENGTH_EXCEEDED

acl certSignatureFailure ssl_error X509_V_ERR_CERT_SIGNATURE_FAILURE
acl crlSignatureFailure ssl_error X509_V_ERR_CRL_SIGNATURE_FAILURE

acl caInvalid ssl_error X509_V_ERR_INVALID_CA

acl squidDomainMismatch ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
acl squidInfiniteValidation ssl_error SQUID_X509_V_ERR_INFINITE_VALIDATION
acl squidSslHandshake ssl_error SQUID_ERR_SSL_HANDSHAKE

sslproxy_cert_adapt setValidBefore all   ; I have these two, but they are not needed;
sslproxy_cert_adapt setValidAfter all

sslproxy_cert_error deny certSelfSigned
sslproxy_cert_error deny certRejected
sslproxy_cert_error deny certRevoked
sslproxy_cert_error deny certHasExpired
sslproxy_cert_error deny certNotValid
sslproxy_cert_error deny certUntrusted
sslproxy_cert_error deny certSelfSignedChain
sslproxy_cert_error deny certChainTooLong
sslproxy_cert_error deny certPathLengthExceeded
sslproxy_cert_error deny certSignatureFailure
sslproxy_cert_error deny crlSignatureFailure
sslproxy_cert_error deny caInvalid
sslproxy_cert_error deny squidDomainMismatch
sslproxy_cert_error deny squidInfiniteValidation
sslproxy_cert_error deny squidSslHandshake
sslproxy_cert_error allow all

sslcrtvalidator_program cache=8192 ttl=240 /usr/lib64/squid/ssl_crtvalid/main.sh
sslcrtvalidator_children 12 startup=5 idle=1 concurrency=1
</squid.conf>

this main.sh script is only

<main.sh>
#!/bin/sh
/usr/lib64/squid/ssl_crtvalid/helper 2>>/tmp/crtvalid-debug.log
</main.sh>
when someone compiles the programme without _DEBUG
then the line in squid.conf would be without this

sslcrtvalidator_program cache=8192 ttl=240 /usr/lib64/squid/ssl_crtvalid/helper

the shellscript  verify.sh is

<verify.sh>
#!/bin/sh

CAFILE=/etc/pki/tls/certs/ca-bundle.trust.crt
DTABASE=/var/local/squid/ssl_crtvalid

CERT=$1
CHAIN=$3
ISSUER=$2
SSLHOST=$4

openssl verify -CAfile $CAFILE -untrusted $CHAIN $CERT

OCSPURL=$(openssl x509 -in $CERT -noout -ocsp_uri)

if [ "$OCSPURL" == "" ];
then
  echo "$CERT: rejected"
else
  OCSPHOST=$(echo "$OCSPURL" |gawk -F\/ '{ print $3 }' -)
  openssl ocsp -CAfile $CAFILE -no_nonce -noverify -issuer $ISSUER -cert $CERT -url "$OCSPURL" -header Host $OCSPHOST |grep "$CERT"
fi

FINGERPRINT=$(openssl x509 -in $CERT -noout -sha1 -fingerprint |sed "{s/SHA1\ Fingerprint\=//g;s/\://g}")
SUBJECT=$( openssl x509 -in $CERT -noout -subject |sed "{s/subject\=\ //g}")

if [ -f $DTABASE/certs/$FINGERPRINT.pem ];
then
  ENTRY=$(cat $DTABASE/index.txt |grep "$SSLHOST" |grep "$FINGERPRINT")
  if [ "$ENTRY" == "" ];
  then
    echo -e -n "$SSLHOST\t$SUBJECT\t$FINGERPRINT.pem\n" >>$DTABASE/index.txt
  fi
else
  openssl x509 -in $CERT -out $DTABASE/certs/$FINGERPRINT.pem
  echo -e -n "$SSLHOST\t$SUBJECT\t$FINGERPRINT.pem\n" >>$DTABASE/index.txt
fi
</verify.sh>

<helper.c>
/*
 * Squid SSL Validator helper programme
 *
 */

#include <ctype.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <time.h>

#include <unistd.h>

#define _DEBUG

#ifdef _DEBUG
#define DEBUGINIT( ) debugInit( __LINE__ )
#define DEBUGOUT2( val, len ) debugWrite( (const void*) ( val ), len )
#define DEBUGOUT( szval ) debugWrite( (const void*) ( szval ), strlen( szval ) )
#define DEBUGOUTINT( intval ) debugOutputInt( __LINE__, #intval, intval )
#define DEBUGOUTSZ( szval ) debugOutputStr( __LINE__, #szval, szval )
#else
#define DEBUGINIT( )
#define DEBUGOUT2( val, len )
#define DEBUGOUT( szval )
#define DEBUGOUTINT( intval )
#define DEBUGOUTSZ( szval )
#endif

enum _MSGTYPE { INTERNERROR = -1, NOERROR = 0, SSLERROR = 1 };

struct _sslmsg_t
{
    char szErrorName[ 72 ];
    int nCertNmbr;
};

const char szMsgConcurrencyRequired[ ] = "This SSL Certificate Validator helper is concurrent and requires the concurrency option to be specified.";
const char szMsgInvalidSize[ ] = "SSL Certificate Validator: invalid request size parameter.";
const char szMsgMemoryAllocFailed[ ] = "SSL Certificate Validator: memory allocation failed.";
const char szMsgSyntaxError[ ] = "SSL Certificate Validator: request syntax error.";
const char szMsgReadIOError[ ] = "SSL Certificate Validator: read i/o error.";
const char szMsgUnknownError[ ] = "SSL Certificate Validator: unknown error.";
   
const char szSslMsgCertRevoked[ ] = "X509_V_ERR_CERT_REVOKED";
const char szSslMsgCertUntrusted[ ] = "X509_V_ERR_CERT_UNTRUSTED";

const char szSslMsgCertRejected[ ] = "X509_V_ERR_CERT_REJECTED";

const char szSslMsgCertHasExpired[ ] = "X509_V_ERR_CERT_HAS_EXPIRED";
const char szSslMsgCertNotYetValid[ ] = "X509_V_ERR_CERT_NOT_YET_VALID";

const char szSslMsgCertChainTooLong[ ] = "X509_V_ERR_CERT_CHAIN_TOO_LONG";

const char szSslMsgCertSelfSigned[ ] = "X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT";

const char szSslMsgCertSelfSignedInChain[ ] =
    "X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN";

const char szSslMsgCertPathLengthExceeded[ ] = "X509_V_ERR_PATH_LENGTH_EXCEEDED";

const char szSslMsgInvalidCa[ ] = "X509_V_ERR_INVALID_CA";

const char szSslMsgSquidDomainMismatch[ ] = "SQUID_X509_V_ERR_DOMAIN_MISMATCH";

const char* pszSslMsgs[ ] = { szSslMsgSquidDomainMismatch,
    szSslMsgCertPathLengthExceeded,
    szSslMsgCertSelfSigned,
    szSslMsgCertSelfSignedInChain,
    szSslMsgCertUntrusted,
    szSslMsgCertRevoked,
    szSslMsgCertHasExpired, szSslMsgCertNotYetValid };

#ifdef _DEBUG
const char szDbgMarkInit[ ] = "=====[ INIT ]=====\n";
const char szDbgMarkReceiveRqustBegin[ ] = "-----[ REQUEST BEGIN ]-----\n";
const char szDbgMarkReceiveRqustEnd[ ] = "-----[ REQUEST END ]-----\n";
const char szDbgMarkReturnMsgBegin[ ] = "-----[ MSG BEGIN ]-----\n";
const char szDbgMarkReturnMsgEnd[ ] = "-----[ MSG END ]-----\n";
#endif


static int nFileCert;
static int nFileChain;
static int nFileIssuer;

static char szFnameCert[ 260 ];
static char szFnameChain[ 260 ];
static char szFnameIssuer[ 260 ];

static char szSslHost[ 260 ];

static char* pszRqustBuf = (char*) NULL;

static struct _sslmsg_t stRqustSslMsgs[ 8 ];
static int nRqustSslMsgsCount;


void cleanupData( void );

void initData( void );

int readRqustHlpr( int* pnEchoId, int* pnRqustRead );
int receiveRequest( int* pnEchoId );

void returnMsg( int nEchoId, int nMsgType, int nCert, const char* pszMsg );

int verifyCertificate( char* pszSslMsg );
int verifyHostName( const char* pszHostName );

#ifdef _DEBUG
void debugInit( int nLine );
void debugOutputHlpr( int nLine, const void* pvdBuf, int nBufLen );
void debugOutputInt( int nLine, const char* pszName, int nVal );
void debugOutputStr( int nLine, const char* pszName, const char* pszVal );
void debugWrite( const void* pvdBuf, int nBufLen );
#endif


// call params: none

int main( int argc, char* argv[ ] )
{
    int nEchoId, nRet = 0;

    DEBUGINIT( );

    initData( );

    nRet = receiveRequest( &nEchoId );

    DEBUGOUTINT( nRet );

    if ( nRet < 0 )
    {
        switch ( nRet )
        {
            case -1 :
                returnMsg( -1, (int) INTERNERROR, -1, szMsgConcurrencyRequired );
                break;
            case -2 :
                returnMsg( 0, (int) INTERNERROR, -1, szMsgMemoryAllocFailed );
                break;
            case -3 :
                returnMsg( 0, (int) INTERNERROR, -1, szMsgInvalidSize );
                break;
            case -4 :
                returnMsg( 0, (int) INTERNERROR, -1, szMsgSyntaxError );
                break;
            case -5 :
                returnMsg( 0, (int) INTERNERROR, -1, szMsgReadIOError );
                break;
            default :
                returnMsg( 0, (int) INTERNERROR, -1, szMsgUnknownError );
        }
        cleanupData( );
        exit( EXIT_FAILURE );
    }

    if ( nRet > 0 )
    {
        returnMsg( nEchoId, (int) NOERROR, 0, (const char*) NULL );
        cleanupData( );
        exit( EXIT_SUCCESS );
    }

    {
        int m, n;
        for ( n = 0; n < sizeof( pszSslMsgs ) / sizeof( char* ); n++ )
            for ( m = 0; m < nRqustSslMsgsCount; m++ )
                if ( strcmp( pszSslMsgs[ n ], stRqustSslMsgs[ m ].szErrorName ) == 0 )
                {
                    returnMsg( nEchoId, (int) SSLERROR,
                        stRqustSslMsgs[ m ].nCertNmbr,
                        stRqustSslMsgs[ m ].szErrorName );
                    cleanupData( );
                    exit( EXIT_SUCCESS );
                }
    }

    if ( verifyHostName( szSslHost ) < 0 )
    {
        returnMsg( nEchoId, (int) SSLERROR, 0, szSslMsgSquidDomainMismatch );
        cleanupData( );
        exit( EXIT_SUCCESS );
    }

    {
        static char szSslMsg[ 72 ];
        if ( ( nRet = verifyCertificate( szSslMsg ) ) < 0 )
        {
            returnMsg( nEchoId, (int) INTERNERROR, -1, szMsgUnknownError );
            cleanupData( );
            exit( EXIT_FAILURE );
        }
        if ( nRet > 0 )
        {
            returnMsg( nEchoId, (int) SSLERROR, 0, szSslMsg );
            cleanupData( );
            exit( EXIT_SUCCESS );
        }
    }
    returnMsg( nEchoId, (int) NOERROR, 0, (const char*) NULL );
    cleanupData( );
    exit( EXIT_SUCCESS );

    return 0;
}

void cleanupData( void )
{
    if ( nFileCert > 0 )
    {
        unlink( szFnameCert );
        nFileCert = 0;
    }
    if ( nFileChain > 0 )
    {
        unlink( szFnameChain );
        nFileChain = 0;
    }
    if ( nFileIssuer > 0 )
    {
        unlink( szFnameIssuer );
        nFileIssuer = 0;
    }
    if ( pszRqustBuf )
    {
        free( pszRqustBuf );
        pszRqustBuf = (char*) NULL;
    }
    fsync( STDOUT_FILENO );
}

void initData( void )
{
    const char szFnameTmplte[ ] = "/tmp/squidXXXXXXXX";

    register int n;

    for ( n = 0; n < sizeof( stRqustSslMsgs ) / sizeof( struct _sslmsg_t ); n++ )
    {
        strcpy( stRqustSslMsgs[ n ].szErrorName, "" );
        stRqustSslMsgs[ n ].nCertNmbr = 0;
    }

    nRqustSslMsgsCount = 0;

    strcpy( szFnameCert, szFnameTmplte );   
    strcpy( szFnameChain, szFnameTmplte );
    strcpy( szFnameIssuer, szFnameTmplte );

    nFileCert = nFileChain = nFileIssuer = 0;
}

int readRqustHlpr( int* pnEchoId, int* pnRqustRead )
{
    const char chLf = '\n';

    static szBuf[ 260 ];

    int nLen, nCount = 0, nSize = 0, nRet = 0;

    if ( ( nLen = read( STDIN_FILENO, (void*) szBuf, 256 ) ) > 0 )
    {
        char* pszNxt;

        szBuf[ nLen ] = '\0';

        DEBUGOUT( szDbgMarkReceiveRqustBegin );

        {
            char* psz = (char*) szBuf;
            long l = (long) strtol( psz, &pszNxt, 10 );
            if ( psz < pszNxt )
            {
                *pnEchoId = (int) l;
            }
            else
            {
                nRet = -1;
            }
        }

        if ( nRet >= 0 )
        {
            char* psz = (char*) ++pszNxt;

            DEBUGOUT2( szBuf, nLen );

            if ( strncmp( psz, "cert_validate", 13 ) == 0 )
            {
                long lVal = (long) strtol( psz + 14, &pszNxt, 10 );
                if ( ( lVal > 0L ) && ( lVal < 10000L ) )
                    nSize = (int) lVal;
                else
                    *pnRqustRead = -1;

                if ( nSize > 0 )
                {
                    if ( pszRqustBuf = (char*) malloc( nSize + 4 ) )
                    {
                        int n = (int) strlen( ++pszNxt );

                        strcpy( pszRqustBuf, pszNxt );
                        while ( ( n < nSize ) && ( ( nLen = read( STDIN_FILENO, (void*) ( pszRqustBuf + n ), nSize - n ) ) > 0 ) )
                        {
                            *( pszRqustBuf + n + nLen ) = '\0';

                            DEBUGOUT2( pszRqustBuf + n, nLen );
                            nCount++;
                            n += nLen;
                        }
                        DEBUGOUT2( &chLf, 1 );

                        if ( n >= nSize )
                            *pnRqustRead = 1;
                        else
                            nRet = -5;
                    }
                    else
                        nRet = -2;
                }
                else
                    nRet = -3;
            }
            else
                nRet = -4;
        }

        DEBUGOUT( szDbgMarkReceiveRqustEnd );
    }
    else
        nRet = -5;

    DEBUGOUTINT( nRet );
    DEBUGOUTINT( nSize );
    DEBUGOUTINT( nCount );

    return nRet;
}

int receiveRequest( int* pnEchoId )
{
    const char chLf = '\n';

    static char sz[ 130 ], szTmp[ 50 ];

    char* pszItemPtr;

    int m, n, nItemLen, nRqustRead = 0;

    int nRet = (int) readRqustHlpr( pnEchoId, &nRqustRead );

    DEBUGOUTINT( nRqustRead );

    if ( nRet < 0 )
        return nRet;

    if ( nRet == 0 )
    {
        if ( pszItemPtr = strstr( pszRqustBuf, "host=" ) )
        {
            nItemLen = strcspn( pszItemPtr += 5, " \r\n" );
            strncpy( szSslHost, pszItemPtr, nItemLen );
            szSslHost[ nItemLen ] = '\0';
        }
        else
            nRet = 1;
    }

    DEBUGOUTINT( nRet );

    if ( nRet > 0 )
        return nRet;

    DEBUGOUTSZ( szSslHost );

    if ( nRet == 0 )
    {
        for ( n = 0; n < 8; n++ )
        {
            int nCertNmbr = -1;

            sprintf( sz, "error_cert_%d=", n );
            if ( pszItemPtr = strstr( pszRqustBuf, sz ) )
            {
                nItemLen = strcspn( pszItemPtr += 13, " \r\n" );
                strncpy( szTmp, (void*) pszItemPtr, nItemLen );
                szTmp[ nItemLen ] = '\0';

                for ( m = 0; m < 7; m++ )
                {
                    sprintf( sz, "cert_%d", m );
                    if ( strcmp( sz, szTmp ) == 0 )
                    {
                        nCertNmbr = m;
                        break;
                    }
                }
            }
            if ( nCertNmbr >= 0 )
            {
                sprintf( sz, "error_name_%d=", n );
                if ( pszItemPtr = strstr( pszRqustBuf, sz ) )
                {
                    nItemLen = strcspn( pszItemPtr += 13, " \r\n" );
                    strncpy( szTmp, (void*) pszItemPtr, nItemLen );
                    szTmp[ nItemLen ] = '\0';
                    strcpy( stRqustSslMsgs[ nRqustSslMsgsCount ].szErrorName, szTmp );
                    stRqustSslMsgs[ nRqustSslMsgsCount++ ].nCertNmbr = nCertNmbr;
                }
                else
                    nRet = 1;
            }
        }
    }

    DEBUGOUTINT( nRet );

    if ( nRet > 0 )
        return nRet;

    DEBUGOUTINT( nRqustSslMsgsCount );
#ifdef _DEBUG
    for ( n = 0; n < nRqustSslMsgsCount; n++ )
    {
        DEBUGOUTINT( stRqustSslMsgs[ n ].nCertNmbr );
        DEBUGOUTSZ( stRqustSslMsgs[ n ].szErrorName );
    }
#endif

    if ( nRet == 0 )
    {
        if ( ( nFileCert = mkstemp( szFnameCert ) ) > 0 );
        else
        {
            nRet = 2;
        }
        if ( nRet == 0 )
        {
            if ( ( nFileChain = mkstemp( szFnameChain ) ) > 0 );
            else
            {
                close( nFileCert );
                unlink( szFnameCert );
                nFileCert = 0;
                nRet = 2;
            }
        }
        if ( nRet == 0 )
        {
            if ( ( nFileIssuer = mkstemp( szFnameIssuer ) ) > 0 );
            else
            {
                close( nFileCert );
                close( nFileChain );
                unlink( szFnameCert );
                unlink( szFnameChain );
                nFileCert = 0;
                nFileChain = 0;
                nRet = 2;
            }
        }
    }

    DEBUGOUTINT( nRet );

    if ( nRet > 0 )
        return nRet;
   
    DEBUGOUTINT( nFileCert );
    DEBUGOUTINT( nFileChain );
    DEBUGOUTINT( nFileIssuer );

    if ( nRet == 0 )
    {
        for ( n = 0; n < 8; n++ )
        {
            sprintf( sz, "cert_%d=-----BEGIN CERTIFICATE-----", n );
            if ( pszItemPtr = strstr( pszRqustBuf, sz ) )
            {
                char* pszTag = (char*) strstr( pszItemPtr += 7, "-----END CERTIFICATE-----" );
                if ( pszTag )
                {
                    nItemLen = (int) ( pszTag - pszItemPtr ) + 25;
                    if ( n == 0 )
                    {
                        write( nFileCert, (void*) pszItemPtr, nItemLen );
                        write( nFileCert, (void*) &chLf, 1 );
                    }
                    if ( n == 1 )
                    {
                        write( nFileIssuer, (void*) pszItemPtr, nItemLen );
                        write( nFileIssuer, (void*) &chLf, 1 );
                    }
                    if ( n >= 1 )
                    {
                        write( nFileChain, (void*) pszItemPtr, nItemLen );
                        write( nFileChain, (void*) &chLf, 1 );
                    }
                }
                else
                {
                    nRet = 3;
                    break;
                }
            }
            else
            {
                if ( n == 0 )
                    nRet = 3;
                break;
            }
        }

        close( nFileCert );
        close( nFileChain );
        close( nFileIssuer );
    }

    DEBUGOUTINT( nRet );

    DEBUGOUTSZ( szFnameCert );
    DEBUGOUTSZ( szFnameChain );
    DEBUGOUTSZ( szFnameIssuer );

    return nRet;
}

void returnMsg( int nEchoId, int nMsgType, int nCert, const char* pszMsg )
{
    static char sz[ 260 ];
    static char szMsgBuf[ 260 ];

#ifdef _DEBUG
    const char szEndTerm[ ] = "\\x01\n";
#endif

    if ( nMsgType == (int) NOERROR )
    {
        sprintf( szMsgBuf, "%d OK 0 \1", nEchoId );
    }
    else
    {
        if ( nMsgType == (int) SSLERROR )
        {
            const char szFmtError[ ] = "error_name_0=%s\n"
                "error_reason_0=Checked by "
                    "Squid SSL Certificate Validator\n"
                "error_cert_0=cert_%d\n";

            sprintf( sz, szFmtError, pszMsg, nCert );

            sprintf( szMsgBuf, "%d ERR %d %s\1", nEchoId,
                strlen( sz ), sz );
        }
        else
        {
            const char szFmtMessage[ ] = "message=\"%s\"";

            sprintf( sz, szFmtMessage, pszMsg );

            if ( nEchoId >= 0 )
                sprintf( szMsgBuf, "%d BH %s\1", nEchoId, sz );
            else
                sprintf( szMsgBuf, "BH %s\1", sz );
        }
    }

    write( STDOUT_FILENO, (void*) szMsgBuf, strlen( szMsgBuf ) );

    DEBUGOUTINT( nMsgType );
    DEBUGOUTINT( nCert );

    DEBUGOUT( szDbgMarkReturnMsgBegin );
    DEBUGOUT2( szMsgBuf, strlen( szMsgBuf ) - 1 );
    DEBUGOUT2( szEndTerm, strlen( szEndTerm ) );
    DEBUGOUT( szDbgMarkReturnMsgEnd );
}

int verifyCertificate( char* pszSslMsg )
{
    static char szGrabStdOut[ 4100 ];
    static char szGrabStdErr[ 4100 ];

    int pipefdin[ 2 ];
    int pipefdout[ 2 ];
    int pipefderr[ 2 ];

    pid_t cpid;

    if ( pipe( pipefdin ) == -1 )
        goto failPipeIn;

    DEBUGOUTINT( pipefdin[ 0 ] );
    DEBUGOUTINT( pipefdin[ 1 ] );

    if ( pipe( pipefdout ) == -1 )
        goto failPipeOut;

    DEBUGOUTINT( pipefdout[ 0 ] );
    DEBUGOUTINT( pipefdout[ 1 ] );

    if ( pipe( pipefderr ) == -1 )
        goto failPipeErr;

    DEBUGOUTINT( pipefderr[ 0 ] );
    DEBUGOUTINT( pipefderr[ 1 ] );

    cpid = fork( );
    if ( cpid == -1 )
        goto failFork;

    DEBUGOUTINT( cpid );

    if ( cpid == 0 )
    {                /* inside child fork */
        close( pipefdin[ 1 ] );
        close( pipefdout[ 0 ] );
        close( pipefderr[ 0 ] );

        dup2( pipefdin[ 0 ], STDIN_FILENO );
        close( pipefdin[ 0 ] );

        dup2( pipefdout[ 1 ], STDOUT_FILENO );
        close( pipefdout[ 1 ] );

        dup2( pipefderr[ 1 ], STDERR_FILENO );
        close( pipefderr[ 1 ] );

        if ( execl( "/usr/lib64/squid/ssl_crtvalid/verify.sh", "./verify.sh",
            szFnameCert, szFnameIssuer, szFnameChain, szSslHost,
            (char*) NULL ) == -1 )
        {
            exit( EXIT_FAILURE );
        }
    }
    else
    {                /* inside parent fork */
        char* psz;
        int n;

        close( pipefdin[ 0 ] );
        close( pipefdout[ 1 ] );
        close( pipefderr[ 1 ] );

        close( pipefdin[ 1 ] );

        n = 0, psz = szGrabStdOut;
        while ( ( n++ < 4096 ) && ( read( pipefdout[ 0 ], psz++, 1 ) > 0 ) )
            *psz = '\0';

        n = 0, psz = szGrabStdErr;
        while ( ( n++ < 4096 ) && ( read( pipefderr[ 0 ], psz++, 1 ) > 0 ) )
            *psz = '\0';

        close( pipefdout[ 0 ] );
        close( pipefderr[ 0 ] );

        wait( NULL );
    }

    /* this is only parent fork */

    DEBUGOUTSZ( szGrabStdOut );
    DEBUGOUTSZ( szGrabStdErr );

    {
        static char sz[ 260 ];

        char* psz = (char*) szGrabStdOut;

        sprintf( sz, "%s: OK", szFnameCert );
        if ( strncmp( psz, sz, strlen( sz ) ) == 0 )
        {
            psz += strlen( sz ) + 1;

            sprintf( sz, "%s: revoked", szFnameCert );
            if ( strncmp( psz, sz, strlen( sz ) ) == 0 )
            {
                strcpy( pszSslMsg, szSslMsgCertRevoked );
                return 1;
            }

            sprintf( sz, "%s: good", szFnameCert );
            if ( strncmp( psz, sz, strlen( sz ) ) == 0 );
            else
                goto invalidCert;
        }
        else
        {
invalidCert:
            strcpy( pszSslMsg, szSslMsgCertRejected );
            return 1;
        }
    }

    return 0;

failFork:
    close( pipefderr[ 0 ] );
    close( pipefderr[ 1 ] );   
failPipeErr:
    close( pipefdout[ 0 ] );
    close( pipefdout[ 1 ] );
failPipeOut:
    close( pipefdin[ 0 ] );
    close( pipefdin[ 1 ] );
failPipeIn:
    return -1;
}

int verifyHostName( const char* pszHostName )
{
    int nLen = (int) strlen( pszHostName );
    char* psz = (char*) ( pszHostName + nLen - 1 );

    if ( strspn( pszHostName, "0123456789." ) == nLen )
        return -1;

    if ( strspn( pszHostName, "0123456789abcdefghijklmnopqrstuvwxyz.-" ) < nLen )
        return -1;

    if ( *psz == ']' )
        return -1;

    if ( isdigit( (int) *psz ) )
        return -1;
}


#ifdef _DEBUG
void debugInit( int nLine )
{
    static char sz[ 260 ];

    time_t t = time( (time_t*) NULL );

    debugWrite( (const void*) szDbgMarkInit, strlen( szDbgMarkInit ) );

    strftime( sz, 80, "date/time: %a, %d-%b-%Y; %H:%M:%S\n", localtime( &t ) );
    debugOutputHlpr( nLine, (const void*) sz, strlen( sz ) );
}

void debugOutputHlpr( int nLine, const void* pvdBuf, int nBufLen )
{
    static char sz[ 130 ];
   
    pid_t pid = (pid_t) getpid( );
   
    sprintf( sz, "ssl_crtvalid/helper[pid=%d,line=%d] ", (int) pid, (int) nLine );

    debugWrite( (const void*) sz, strlen( sz ) );
    debugWrite( pvdBuf, nBufLen );
}

void debugOutputInt( int nLine, const char* pszName, int nVal )
{
    static char sz[ 260 ];
    sprintf( sz, "%s: %d\n", pszName, nVal );
    debugOutputHlpr( nLine, (const void*) sz, strlen( sz ) );
}

void debugOutputStr( int nLine, const char* pszName, const char* pszVal )
{
    static char sz[ 260 ];
    sprintf( sz, "%s: '%s'\n", pszName, pszVal );
    debugOutputHlpr( nLine, (const void*) sz, strlen( sz ) );
}

void debugWrite( const void* pvdBuf, int nBufLen )
{
    write( STDERR_FILENO, pvdBuf, nBufLen );
}
#endif
</helper.c>

<<attachment: smime.p7s>>

_______________________________________________
squid-users mailing list
squid-users@xxxxxxxxxxxxxxxxxxxxx
http://lists.squid-cache.org/listinfo/squid-users

[Index of Archives]     [Linux Audio Users]     [Samba]     [Big List of Linux Books]     [Linux USB]     [Yosemite News]

  Powered by Linux