ip_irc_pxy.c revision 381a2a9a387f449fab7d0c7e97c4184c26963abf
/*
* Copyright (C) 2000-2003 Darren Reed
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* $Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp $
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define IPF_IRC_PROXY
int ippr_irc_init __P((void));
void ippr_irc_fini __P((void));
int irc_proxy_init = 0;
/*
* Initialize local structures.
*/
int ippr_irc_init()
{
irc_proxy_init = 1;
return 0;
}
void ippr_irc_fini()
{
if (irc_proxy_init == 1) {
irc_proxy_init = 0;
}
}
char *ippr_irc_dcctypes[] = {
"CHAT ", /* CHAT chat ipnumber portnumber */
"SEND ", /* SEND filename ipnumber portnumber */
"MOVE ",
"TSEND ",
"SCHAT ",
NULL,
};
/*
* :A PRIVMSG B :^ADCC CHAT chat 0 0^A\r\n
* PRIVMSG B ^ADCC CHAT chat 0 0^A\r\n
*/
char *buf;
{
register char *s, c;
register size_t i;
u_32_t l;
int j, k;
if (len < 31)
return 0;
s = buf;
c = *s++;
i = len - 1;
if ((c != ':') && (c != 'P'))
return 0;
if (c == ':') {
/*
* Loosely check that the source is a nickname of some sort
*/
s++;
c = *s;
if (!ISALPHA(c))
return 0;
i--;
for (c = *s; !ISSPACE(c) && (i > 0); i--)
c = *s++;
if (i < 31)
return 0;
if (c != 'P')
return 0;
} else
/*
* Check command string
*/
return 0;
i -= 8;
s += 8;
c = *s;
/*
* Loosely check that the destination is a nickname of some sort
*/
if (!ISALPHA(c))
return 0;
for (; !ISSPACE(c) && (i > 0); i--)
c = *s++;
if (i < 20)
return 0;
s++,
i--;
/*
* Look for a ^A to start the DCC
*/
c = *s;
if (c == ':') {
s++;
c = *s;
}
return 0;
i -= 4;
s += 4;
/*
* Check for a recognised DCC command
*/
for (j = 0, k = 0; ippr_irc_dcctypes[j]; j++) {
if (!strncmp(ippr_irc_dcctypes[j], s, k))
break;
}
if (!ippr_irc_dcctypes[j])
return 0;
i -= k;
s += k;
if (i < 11)
return 0;
/*
* Check for the arg
*/
c = *s;
if (ISSPACE(c))
return 0;
for (; (c != ' ') && (c != '\001') && (i > 0); i--)
c = *s++;
if (c == '\001') /* In reality a ^A can quote another ^A...*/
return 0;
if (i < 5)
return 0;
s++;
i--;
c = *s;
if (!ISDIGIT(c))
return 0;
/*
* Get the IP#
*/
for (l = 0; ISDIGIT(c) && (i > 0); i--) {
l *= 10;
l += c - '0';
c = *s++;
}
if (i < 4)
return 0;
if (c != ' ')
return 0;
s++;
i--;
c = *s;
if (!ISDIGIT(c))
return 0;
/*
* Get the port#
*/
for (l = 0; ISDIGIT(c) && (i > 0); i--) {
l *= 10;
l += c - '0';
c = *s++;
}
if (i < 3)
return 0;
return 0;
s += 3;
return 1;
}
{
return -1;
return 0;
}
{
mb_t *m;
#ifdef MENTAT
#endif
#ifdef __sgi
#else
#endif
if (dlen <= 0)
return 0;
if (dlen <= 0)
return 0;
*newbuf = '\0';
return 0;
/*
* sender of the command - prevents using PORT for port scanning.
*/
return 0;
/*
* Calculate new address parts for the DCC command
*/
i++;
/* DO NOT change these! */
#else
#endif
return 0;
#ifdef MENTAT
;
/* alloc enough to keep same trailer space for lower driver */
("ippr_irc_out: cannot handle fragmented data block"));
} else {
# endif
}
#else
if (inc < 0)
/* the mbuf chain will be extended if necessary by m_copyback() */
#endif
if (inc != 0) {
/* Because ~1 == -2, We really need ~1 == -1 */
sum2--;
#endif
}
/*
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
/*
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
return 0;
/*
* The server may not make the connection back from port 20, but
* it is the most likely so use it here to check for a conflicting
* mapping.
*/
}
}
return inc;
}
{
}