On 04.10.2015 21:08, Walter H. wrote:
Hello, 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_REJECTEDit 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