int SP_MatrixsslChannel :: init( int fd ) { SP_IOUtils::setBlock( fd ); int ret = sslAccept( &mConn, fd, mKeys, NULL, 0 ); SP_IOUtils::setNonblock( fd ); if( 0 != ret ) { sp_syslog( LOG_EMERG, "sslAccept fail" ); return -1; } return 0; }
int agentMain (rsComm_t *rsComm) { int status = 0; int retryCnt = 0; while (1) { if (rsComm->gsiRequest==1) { status = igsiServersideAuth(rsComm) ; rsComm->gsiRequest=0; } if (rsComm->gsiRequest==2) { status = ikrbServersideAuth(rsComm) ; rsComm->gsiRequest=0; } #ifdef USE_SSL if (rsComm->ssl_do_accept) { status = sslAccept(rsComm); rsComm->ssl_do_accept = 0; } if (rsComm->ssl_do_shutdown) { status = sslShutdown(rsComm); rsComm->ssl_do_shutdown = 0; } #endif status = readAndProcClientMsg (rsComm, READ_HEADER_TIMEOUT); #if 0 status = readAndProcClientMsg (rsComm, 0); #endif if (status >= 0) { retryCnt = 0; continue; } else { if (status == DISCONN_STATUS) { status = 0; break; } else { break; } } } return (status); }
int main(int argc, char **argv) #endif { sslConn_t *cp; sslKeys_t *keys; SOCKET listenfd, fd; WSADATA wsaData; unsigned char buf[1024]; unsigned char *response, *c; int responseHdrLen, acceptAgain, flags; int bytes, status, quit, again, rc, err; #if USE_MEM_CERTS unsigned char *servBin, *servKeyBin, *caBin; int servBinLen, caBinLen, servKeyBinLen; #endif cp = NULL; /* Initialize Windows sockets (no-op on other platforms) */ WSAStartup(MAKEWORD(1,1), &wsaData); /* Initialize the MatrixSSL Library, and read in the public key (certificate) and private key. */ if (matrixSslOpen() < 0) { fprintf(stderr, "matrixSslOpen failed, exiting..."); } #if USE_MEM_CERTS /* Example of DER binary certs for matrixSslReadKeysMem */ getFileBin("certSrv.der", &servBin, &servBinLen); getFileBin("privkeySrv.der", &servKeyBin, &servKeyBinLen); getFileBin("CACertCln.der", &caBin, &caBinLen); matrixSslReadKeysMem(&keys, servBin, servBinLen, servKeyBin, servKeyBinLen, caBin, caBinLen); free(servBin); free(servKeyBin); free(caBin); #else /* Standard PEM files */ if (matrixSslReadKeys(&keys, certfile, keyfile, NULL, NULL) < 0) { fprintf(stderr, "Error reading or parsing %s or %s.\n", certfile, keyfile); goto promptAndExit; } #endif /* USE_MEM_CERTS */ fprintf(stdout, "Run httpsClient or type https://127.0.0.1:%d into your local Web browser.\n", HTTPS_PORT); /* Create the listen socket */ if ((listenfd = socketListen(HTTPS_PORT, &err)) == INVALID_SOCKET) { fprintf(stderr, "Cannot listen on port %d\n", HTTPS_PORT); goto promptAndExit; } /* Set blocking or not on the listen socket */ setSocketBlock(listenfd); /* Loop control initalization */ quit = 0; again = 0; flags = 0; acceptAgain = 1; /* Main connection loop */ while (!quit) { if (acceptAgain) { /* sslAccept creates a new server session */ /* TODO - deadlock on blocking socket accept. Should disable blocking here */ if ((fd = socketAccept(listenfd, &err)) == INVALID_SOCKET) { fprintf(stdout, "Error accepting connection: %d\n", err); continue; } if ((rc = sslAccept(&cp, fd, keys, NULL, flags)) != 0) { socketShutdown(fd); continue; } flags = 0; acceptAgain = 0; } /* Read response < 0 return indicates an error. 0 return indicates an EOF or CLOSE_NOTIFY in this situation > 0 indicates that some bytes were read. Keep reading until we see the /r/n/r/n from the GET request. We don't actually parse the request, we just echo it back. */ c = buf; readMore: if ((rc = sslRead(cp, c, sizeof(buf) - (int)(c - buf), &status)) > 0) { c += rc; if (c - buf < 4 || memcmp(c - 4, "\r\n\r\n", 4) != 0) { goto readMore; } } else { if (rc < 0) { fprintf(stdout, "sslRead error. dropping connection.\n"); } if (rc < 0 || status == SSLSOCKET_EOF || status == SSLSOCKET_CLOSE_NOTIFY) { socketShutdown(cp->fd); sslFreeConnection(&cp); acceptAgain = 1; continue; } goto readMore; } /* Done reading. If the incoming data starts with the quitString, quit the application after this request */ if (memcmp(buf, quitString, min(c - buf, (int)strlen(quitString))) == 0) { quit++; fprintf(stdout, "Q"); } /* If the incoming data starts with the againString, we are getting a pipeline request on the same session. Don't close and wait for new connection in this case. */ if (memcmp(buf, againString, min(c - buf, (int)strlen(againString))) == 0) { again++; fprintf(stdout, "A"); } else { fprintf(stdout, "R"); again = 0; } /* Copy the canned response header and decoded data from socket as the response (reflector) */ responseHdrLen = (int)strlen(responseHdr); bytes = responseHdrLen + (int)(c - buf); response = malloc(bytes); memcpy(response, responseHdr, responseHdrLen); memcpy(response + responseHdrLen, buf, c - buf); /* Send response. < 0 return indicates an error. 0 return indicates not all data was sent and we must retry > 0 indicates that all requested bytes were sent */ writeMore: rc = sslWrite(cp, response, bytes, &status); if (rc < 0) { free(response); fprintf(stdout, "Internal sslWrite error\n"); socketShutdown(cp->fd); sslFreeConnection(&cp); continue; } else if (rc == 0) { goto writeMore; } free(response); /* If we saw an /again request, loop up and process another pipelined HTTP request. The /again request is supported in the httpsClient example code. */ if (again) { continue; } /* Send a closure alert for clean shutdown of remote SSL connection This is for good form, some implementations just close the socket */ sslWriteClosureAlert(cp); /* Close the socket and wait for next connection (new session) */ socketShutdown(cp->fd); sslFreeConnection(&cp); acceptAgain = 1; } /* Close listening socket, free remaining items */ if (cp && cp->ssl) { socketShutdown(cp->fd); sslFreeConnection(&cp); } socketShutdown(listenfd); matrixSslFreeKeys(keys); matrixSslClose(); WSACleanup(); promptAndExit: fprintf(stdout, "\n\nPress return to exit...\n"); getchar(); return 0; }
void proxyAccept(int srv_fd, struct proxyConnection *ncp) { SOCKET src_fd, dst_fd; // struct linger linger; int status; int res; struct timeval tv; int pc, sc; int ccount=0; ILOG("Accepting new connection."); if ((src_fd = socketAccept(srv_fd, &status)) == INVALID_SOCKET) { WLOG("Error accepting connection: %d", status); return; } #ifdef USE_FORK // fork here fd_set rs, ws, es; int fdmax; int pid=fork(); switch(pid) { case -1: /* error */ closesocket(ncp->plain); closesocket(ncp->secure->fd); break; case 0: /* child */ #endif ncp->inuse=1; if (!isClient) { DLOG("Trying to accept ssl connection"); if (sslAccept(&ncp->secure, src_fd, keys, cervalidator, 0)) { WLOG("Error could not establish ssl connection"); socketShutdown(src_fd); /* Gemtek add +++ */ #ifdef USE_FORK quit=1; #endif /* Gemtek add --- */ return; } } setSocketNonblock(src_fd); /* linger.l_onoff = 1; linger.l_linger = 1; setsockopt(src_fd, SOL_SOCKET, SO_LINGER, (char *) &linger,sizeof(linger)); */ /* try to connect to remote end of tunnel */ DLOG("Trying to connect server %s:%d", dst_host, dst_port); if ((dst_fd = socketConnect(dst_host, dst_port, &status)) == INVALID_SOCKET) { WLOG("Error connecting to server %s:%d", dst_host, dst_port); socketShutdown(src_fd); /* Gemtek add +++ */ #ifdef USE_FORK quit=1; #endif /* Gemtek add --- */ return; } if (isClient) { DLOG("Trying to establish an ssl connection to server %s:%d", dst_host, dst_port); if ((sslConnect(&ncp->secure, dst_fd, keys, ncp->sessionId, ncp->cipherSuite, cervalidator)) == INVALID_SOCKET) { WLOG("Error connecting to ssl server %s:%d", dst_host, dst_port); socketShutdown(src_fd); return; } } setSocketNonblock(dst_fd); /* linger.l_onoff = 1; linger.l_linger = 1; setsockopt(dst_fd, SOL_SOCKET, SO_LINGER, (char *) &linger,sizeof(linger)); */ ncp->plain = isClient ? src_fd : dst_fd; ncp->plain_up=1; ncp->secure_up=1; ILOG("Connection established. plain_fd:%d secure_fd:%d", ncp->plain, ncp->secure->fd); // handle remaining bytes in buffer. /* res=proxyReadwrite(ncp,1); if(res<0) { ncp->error=1; closeProxyConnection(ncp); } */ // fork here #ifdef USE_FORK closesocket(srv_fd); fdmax=ncp->plain > ncp->secure->fd ? ncp->plain : ncp->secure->fd; while (!quit) { FD_ZERO(&rs); FD_ZERO(&ws); FD_ZERO(&es); FD_SET(ncp->plain,&rs); FD_SET(ncp->plain,&ws); FD_SET(ncp->plain,&es); FD_SET(ncp->secure->fd,&rs); FD_SET(ncp->secure->fd,&ws); FD_SET(ncp->secure->fd,&es); tv.tv_sec=10; tv.tv_usec=0; DLOG("select on %d open connections. fdmax: %d", ccount, fdmax); res=select(fdmax+1,&rs,NULL,&es,&tv); // DLOG("select returned: %d", res); DLOG("proxyAccept->select returned: %d %s errno=%d", res , strerror(errno), errno ); if(res<0) { perror("select"); continue; } /* if(res==0) continue; */ if(FD_ISSET(ncp->secure->fd,&es) || FD_ISSET(ncp->plain,&es)) { ncp->error=1; break; } sc=proxyReadwrite(ncp,1); if(sc<0) break; pc=proxyReadwrite(ncp,0); if(pc<0) break; if(ncp->done) { quit=1; break; } } closeProxyConnection(ncp); DLOG("done. exiting..."); exit(0); break; default: closesocket(src_fd); /* server */ break; } #endif }
int agentMain( rsComm_t *rsComm ) { if ( !rsComm ) { return SYS_INTERNAL_NULL_INPUT_ERR; } int status = 0; // =-=-=-=-=-=-=- // capture server properties irods::server_properties& props = irods::server_properties::getInstance(); irods::error result = props.capture_if_needed(); if ( !result.ok() ) { irods::log( PASSMSG( "failed to read server configuration", result ) ); } // =-=-=-=-=-=-=- // compiler backwards compatibility hack // see header file for more details irods::dynamic_cast_hack(); while ( result.ok() && status >= 0 ) { // set default to the native auth scheme here. if ( rsComm->auth_scheme == NULL ) { rsComm->auth_scheme = strdup( "native" ); } // construct an auth object based on the scheme specified in the comm irods::auth_object_ptr auth_obj; irods::error ret = irods::auth_factory( rsComm->auth_scheme, &rsComm->rError, auth_obj ); if ( ( result = ASSERT_PASS( ret, "Failed to factory an auth object for scheme: \"%s\".", rsComm->auth_scheme ) ).ok() ) { irods::plugin_ptr ptr; ret = auth_obj->resolve( irods::AUTH_INTERFACE, ptr ); if ( ( result = ASSERT_PASS( ret, "Failed to resolve the auth plugin for scheme: \"%s\".", rsComm->auth_scheme ) ).ok() ) { irods::auth_ptr auth_plugin = boost::dynamic_pointer_cast< irods::auth >( ptr ); // Call agent start char* foo = ""; ret = auth_plugin->call < const char* > ( rsComm, irods::AUTH_AGENT_START, auth_obj, foo ); result = ASSERT_PASS( ret, "Failed during auth plugin agent start for scheme: \"%s\".", rsComm->auth_scheme ); } // =-=-=-=-=-=-=- // add the user info to the server properties for // reach by the operation wrapper for access by the // dynamic policy enforcement points set_rule_engine_globals( rsComm, props ); } if ( result.ok() ) { if ( rsComm->ssl_do_accept ) { status = sslAccept( rsComm ); if ( status < 0 ) { rodsLog( LOG_ERROR, "sslAccept failed in agentMain with status %d", status ); } rsComm->ssl_do_accept = 0; } if ( rsComm->ssl_do_shutdown ) { status = sslShutdown( rsComm ); if ( status < 0 ) { rodsLog( LOG_ERROR, "sslShutdown failed in agentMain with status %d", status ); } rsComm->ssl_do_shutdown = 0; } status = readAndProcClientMsg( rsComm, READ_HEADER_TIMEOUT ); if ( status < 0 ) { if ( status == DISCONN_STATUS ) { status = 0; break; } } } } if ( !result.ok() ) { irods::log( result ); status = result.code(); return status; } // =-=-=-=-=-=-=- // determine if we even need to connect, break the // infinite reconnect loop. if ( !resc_mgr.need_maintenance_operations() ) { return status; } // =-=-=-=-=-=-=- // find the icat host rodsServerHost_t *rodsServerHost = 0; status = getRcatHost( MASTER_RCAT, 0, &rodsServerHost ); if ( status < 0 ) { irods::log( ERROR( status, "getRcatHost failed." ) ); return status; } // =-=-=-=-=-=-=- // connect to the icat host status = svrToSvrConnect( rsComm, rodsServerHost ); if ( status < 0 ) { irods::log( ERROR( status, "svrToSvrConnect failed." ) ); return status; } // =-=-=-=-=-=-=- // call post disconnect maintenance operations before exit status = resc_mgr.call_maintenance_operations( rodsServerHost->conn ); return status; }