ok, start using the curl interface in NeoStats

This commit is contained in:
Fish 2003-12-22 11:17:30 +00:00
parent cf30337f78
commit 8d7450b159
8 changed files with 56 additions and 952 deletions

2
.gitattributes vendored
View file

@ -17,8 +17,6 @@
/configure.in -text
/exempts.c -text
/html.css -text
/http.c eol=lf
/http.h eol=lf
/install-sh -text
/modconfig.h.in -text
/scan.c -text

View file

@ -8,12 +8,12 @@ INSTALL_DATA = @INSTALL_DATA@
DIRECTORY=@DIRINST@/dl/
INCLUDES=-I@DIRINST@/include/ -I.
SOURCES= SecureServ.c SecureServ_help.c http.c OnJoinBot.c FloodCheck.c Helpers.c scan.c exempts.c update.c
OBJECTS= SecureServ.o SecureServ_help.o http.o OnJoinBot.o FloodCheck.o Helpers.o scan.o exempts.o update.o
SOURCES= SecureServ.c SecureServ_help.c OnJoinBot.c FloodCheck.c Helpers.c scan.c exempts.c update.c
OBJECTS= SecureServ.o SecureServ_help.o OnJoinBot.o FloodCheck.o Helpers.o scan.o exempts.o update.o
TARGET= secureserv.so
DOCS=README.SecureServ SecureServ.settings README.SecureServ.html html.css
DATA=viri.dat customviri.dat
DISTFILES = $(SOURCES) $(DATA) $(DOCS) modconfig.h.in configure install-sh ChangeLog Makefile.in http.h SecureServ.h RelNotes.txt
DISTFILES = $(SOURCES) $(DATA) $(DOCS) modconfig.h.in configure install-sh ChangeLog Makefile.in SecureServ.h RelNotes.txt
distdir = @PACKAGE@-@VERSION@
all: module

View file

@ -35,7 +35,6 @@
#include "log.h"
#include "conf.h"
#include "SecureServ.h"
#include "http.h"
static int ScanNick(char **av, int ac);
void LoadConfig(void);
@ -801,7 +800,7 @@ static int Online(char **av, int ac)
/* every sixty seconds should keep the list small, and not put *too* much load on NeoStats */
add_mod_timer("CleanNickFlood", "CleanNickFlood", __module_info.module_name, 60);
add_mod_timer("CheckLockChan", "CheckLockedChans", __module_info.module_name, 10);
dns_lookup(HTTPHOST, adns_r_a, GotHTTPAddress, "SecureServ Update Server");
dns_lookup("secure.irc-chat.net", adns_r_a, GotHTTPAddress, "SecureServ Update Server");
SecureServ.inited = 1;
LoadMonChans();

View file

@ -36,7 +36,6 @@
#include "log.h"
#include "conf.h"
#include "SecureServ.h"
#include "http.h"
/* this is the size of the exempt list */
#define MAX_EXEMPTS 100

783
http.c
View file

@ -1,783 +0,0 @@
/* NeoStats - IRC Statistical Services Copyright
** Copyright (c) 1999-2003 Justin Hammond
** http://www.neostats.net/
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
/***************************************************************************
*
* Library: libhttp
*
* Description: library for generic http data transfers
*
***************************************************************************
*
* HTTPGET/libhttp
*
* Copyright (C) 1994 by Sami Tikka <sti@iki.fi>
* Copyright (C) 2001 by Alan DuBoff <aland@SoftOrchestra.com>
*
* Last change: 8/27/2001
*
* The right to use, modify and redistribute this code is allowed
* provided the above copyright notice and the below disclaimer appear
* on all copies.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
* Compile with (g)cc -o httpget httpget.c (-lsocket)
*
***************************************************************************/
#include <ctype.h>
#include "stats.h"
#include "log.h"
#include "http.h"
#ifdef DEBUG
#define debug(path, args...) fprintf(path, ## args)
#define debug2(ptr, args...) fwrite(ptr, ## args)
#else
#define debug(path, args...)
#define debug2(ptr, args...)
#endif
typedef struct http_details {
char path[8192];
int port;
char host[MAXHOST];
HTTP_Response *response;
int method;
char *pRequest;
void (*callback)(HTTP_Response *response);
struct sockaddr_in addr;
char *pData;
char *pBase;
unsigned long total_bytes;
unsigned long bytes;
unsigned long data_size;
unsigned long alloc_size;
int in_header;
} http_details;
struct http_details *hd;
char *find_header_end( char *buf, int bytes )
{
char *end = buf + bytes;
while( buf < end && !(*buf++ == '\n'
&& (*buf == '\n'
|| (*buf++ == '\r'
&& *buf == '\n'))) ) ;
if( *buf == '\n' )
return( buf + 1 );
return( NULL );
}
#ifdef HF_FIND_HEADER
/*
* This function try to find the HTTP header specified and return its value.
* The 'buf' contains the header is assumed to be terminated by a blank line.
* The 'type' must be terminated by a colon, such as "Content-Type:".
*/
char *find_header( char *buf, int buflen, char *type, char *value, int vsize )
{
char *end;
char *eol;
int tl = strlen(type);
/* Find the end (in case input is not NULL terminated) */
if(buflen <= 0)
buflen = strlen(buf);
end = buf + buflen;
do /* For each line of header */
{
/* Note : 'type' *must* be terminated by a ':', otherwise you may
* match the wrong header */
if( ! strncasecmp( buf, type, tl ) )
{
buf += tl; /* Skip header type */
while( isspace( *buf ) ) /* Skip spaces */
buf++;
/* We keep the blank line at the end of the header, we are safe */
eol = strchr(buf, '\r');
/* Unlikely to fail, but let be safe */
if( ( eol != NULL ) && ( (eol - buf) < (vsize - 1) ) )
{
/* Copy, NULL terminate, return */
memcpy( value, buf, (eol - buf) );
value[(eol - buf)] = '\0';
debug( stderr, "Found header %s: %s\n", type, value );
return( value );
}
}
} /* Go to start of next line, if any */
while( ( ( buf = strchr( buf, '\n' ) ) != NULL ) && ( ++buf < end ) );
return( NULL );
}
#endif /* HF_FIND_HEADER */
/* Separate an URL in its different components.
* Note that GET/POST form data is not removed from the "path", and therefore
* it can be quite big. That's why we return it and don't copy it.
* Jean II */
char *parse_url( char *url, char *scheme, char *host, int *port )
{
char *slash, *colon;
char *delim;
char *turl;
char *t;
char *pRet;
/* All operations on turl so as not to mess contents of url */
turl = (char *)calloc( 1, strlen( url ) + 1 );
if( turl == NULL )
return (char *)"";
strcpy( turl, url );
delim = "://";
if( (colon = strstr( turl, delim )) == NULL )
{
debug( stderr, "Warning: URL is not in format <scheme>://<host>/<path>.\nAssuming scheme = http.\n" );
strcpy( scheme, "http" );
t = turl;
}
else
{
*colon = '\0';
strcpy( scheme, turl );
t = colon + strlen( delim );
}
/* Now t points to the beginning of host name */
if( (slash = strchr( t, '/' )) == NULL )
{
/* If there isn't even one slash, the path must be empty */
debug( stderr, "Warning: no slash character after the host name. Empty path. Adding slash.\n" );
strcpy( host, t );
slash = "/";
}
else
{
memcpy( host, t, slash - t);
host[slash - t] = '\0';
}
/* Check if the hostname includes ":portnumber" at the end */
if( (colon = strchr( host, ':' )) == NULL )
{
*port = 80; /* HTTP standard */
}
else
{
*colon = '\0';
*port = atoi( colon + 1 );
}
pRet = (char *)calloc( 1, strlen( slash ) + 1 );
strcpy( pRet, slash );
if( turl ) free( turl );
/* Return the path + arguments */
return( pRet );
}
/*
* Function Name: http_request
*
* Parameters: char *in_URL http URL to request
* int in_Method enum for method type
* (see http.h)
* Description: handle a request to an http server. this is being kept
* simple for a purpose, call the function with an http URL
* and have return the response inside HTTP_Response.
*
* Returns: HTTP_Response struct
*
* NOTE: the memory is allocated for the data transfered,
* and it is the responsibility of the *CALLER* to free
* the memory. it's very easy to accumulate several
* megabytes of data.
*
*/
int http_request( char *in_URL, HTTP_Method in_Method, unsigned long in_Flags, void (*callback)(HTTP_Response *response))
{
char scheme[50], host[MAXPATHLEN];
char *proxy;
char *path;
int port;
struct sockaddr_in addr;
#ifdef HF_DO_FILE
// CRH It's a file or directory
if(in_Method == kHMethodGet && !strncasecmp(in_URL, "file://", 7))
return do_file( in_URL );
#endif /* HF_DO_FILE */
hd = malloc(sizeof(http_details));
hd->response = malloc(sizeof(HTTP_Response));
hd->response->lSize = 0;
hd->response->iError = 1;
memset( hd->response->szHCode, '\0', HCODESIZE );
memset( hd->response->szHMsg, '\0', HMSGSIZE );
#if 0
memset( hd->host, '\0', MAXPATHLEN );
memset( scheme, '\0', 50 );
#endif
hd->method = in_Method;
hd->callback = callback;
// the GET and POST as of 9/4/2001
if( in_Method == kHMethodPost )
{
// add 1024 bytes for the header
hd->pRequest = (char *)calloc( 1, strlen( in_URL ) + 1024 );
if( hd->pRequest == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
return(-1);
}
}
else // allocate enough for the
{
if( strlen( in_URL ) < GETLEN ) // compare against max request
{
// allocate the size of the URL
// add 1024 bytes for the header
hd->pRequest = (char *)calloc( 1, strlen( in_URL ) + 1024 );
if( hd->pRequest == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
return(-1);
}
}
else
{
*(in_URL + 8192) = '\0';
hd->pRequest = (char *)calloc( 1, GETLEN + 1024 );
if( hd->pRequest == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
return(-1);
}
}
}
// the http_proxy environment setting is common use for a proxy server,
// and the way it was setup per httpget.
if( (proxy = getenv( "http_proxy" )) == NULL )
{
path = parse_url( in_URL, scheme, host, &port );
// if (path) free(path);
// check for http scheme to be safe.
if( strcasecmp(scheme, "http") != 0 )
{
nlog(LOG_WARNING, LOG_MOD, "http_request cannot operate on %s URLs without a proxy\n", scheme );
hd->response->iError = -1 ;
hd->callback(hd->response);
free(hd->response);
if( path ) free( path );
if( hd->pRequest ) free( hd->pRequest );
return(-1);
}
}
else
{
path = parse_url( proxy, scheme, host, &port );
// if( path ) free( path ); // free it, in_URL will be assigned to it
// add jjsa 2/17/2002
path = (char *)calloc( 1, strlen( in_URL) + 1 );
if( path == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
if( hd->pRequest ) free( hd->pRequest );
return(-1);
}
path = in_URL;
}
/* -- Note : --
* After this point, in_URL is no longer used and you should only
* use "path". - Jean II
*/
strncpy(hd->path, path, 8192);
strncpy(hd->host, host, MAXHOST);
hd->port = port;
nlog(LOG_DEBUG1, LOG_MOD, "HTTP_Request: %s:%d/%s and Request %s", hd->host, hd->port, hd->path, hd->pRequest);
addr.sin_addr.s_addr = inet_addr( host );
if( (int)addr.sin_addr.s_addr == -1 )
{
nlog(LOG_CRITICAL, LOG_MOD, "Host %s is not a valid IP address", hd->host);
hd->response->iError = -1;
hd->callback(hd->response);
free(hd->response);
if( hd->pRequest ) free( hd->pRequest );
return(-1);
} else {
/* do connect, as the host, was an IP address */
sock_connect(SOCK_STREAM, addr.sin_addr.s_addr, hd->port, "SecureServ", "SecureServ", "http_read", "http_write", "http_error");
}
return(1);
}
extern int http_read(int socknum, char *sockname) {
int i;
char buf[BUFLEN];
char *h_end_ptr, *pHCode, *pHMsgEnd;
unsigned long header_size = 0UL;
// buf = malloc(BUFLEN);
bzero(buf, BUFLEN);
i = recv(socknum, buf, BUFLEN, 0);
if (i < 0) {
nlog(LOG_NOTICE, LOG_MOD, "HttpGet Error in Read %s", strerror(errno));
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
if (hd->pRequest) free(hd->pRequest);
sock_disconnect(sockname);
free(hd->response);
// free(buf);
return -1;
} else if (i == 0) {
// free(buf);
nlog(LOG_DEBUG1, LOG_MOD, "HttpGet Successful");
h_end_ptr = find_header_end( hd->pBase, hd->total_bytes );
if( h_end_ptr != NULL )
{
// we'll get response and response message
pHCode = strchr( hd->pBase, ' ' );
if( pHCode != NULL )
{
pHCode++;
strncpy( hd->response->szHCode, pHCode, 3 );
// now get message
pHCode += 4; // increment past code
// and search for new line
pHMsgEnd = strchr( pHCode, '\n' );
if( pHMsgEnd != NULL ) // get the rest of line for the response message
{
strncpy( hd->response->szHMsg, pHCode,
(pHMsgEnd - pHCode) <= (HMSGSIZE - 1) ? (pHMsgEnd - pHCode ) : (HMSGSIZE - 1) );
}
}
}
else
{
header_size = hd->total_bytes;
h_end_ptr = hd->pBase + hd->total_bytes;
}
// now we'll store the size of the header, since we'll need to
// subtract that from the total of bytes downloaded to get the
// real size of the data.
header_size = (unsigned long)(h_end_ptr - hd->pBase);
if( hd->method == kHMethodHead )
{
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
hd->pBase = realloc( hd->pBase, header_size );
if( hd->pBase == NULL ) {
sock_disconnect(sockname);
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
if( hd->pBase ) free( hd->pBase );
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
free(hd->response);
// free(buf);
return(-1);
}
hd->response->lSize = (long)header_size;
hd->response->pData = hd->pBase;
sock_disconnect(sockname);
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
if( hd->pBase ) free( hd->pBase );
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
free(hd->response);
// free(buf);
/* callback */
return(-1);
}
/* Delete HTTP headers */
memcpy(hd->pBase, h_end_ptr, hd->total_bytes - header_size);
hd->pBase[hd->total_bytes - header_size] = '\0';
// realloc the data if we've gotten anything. chances are
// we'll have more allocated than we've transfered. ajd 8/27/2001
if( (hd->total_bytes - header_size) > 0 )
{
hd->pBase = realloc( hd->pBase, (hd->total_bytes - header_size) +1);
if( hd->pBase == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
if( hd->pBase ) free( hd->pBase );
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
sock_disconnect(sockname);
free(hd->response);
// free(buf);
/* callback */
return( -1);
}
} // now, if we've gotten this far we must
// have our data, so store the size and
// the pointer to the data in our response
// structure for return.
if( hd->method != kHMethodHead ) // HEAD would be set already
{
hd->response->lSize = (long)(hd->total_bytes - header_size);
hd->response->pData = hd->pBase;
}
#ifdef DEBUG
// printf("HTTP Data:\n%s\n %d = %d\n", hd->response->pData, hd->response->lSize, strlen(hd->response->pData));
#endif
hd->callback(hd->response);
if( hd->pBase ) free( hd->pBase );
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
if ( hd->response) free(hd->response);
sock_disconnect(sockname);
return -1;
/* end of succesfull get */
}
/* if we are here, we wer still downloading */
hd->total_bytes += i;
if( (hd->data_size + i ) > hd->alloc_size )
{
/* make sure that pBase has enough memory for the file */
hd->pBase = realloc( hd->pBase, (hd->alloc_size + XFERLEN) );
if( hd->pBase == NULL )
{
// get outta dodge and free the
// the allocated memory...there
// could be a chance that we ran
// out of resource, and we'll
// free it.
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
if( hd->path ) free( hd->path );
if( hd->pBase ) free( hd->pBase );
if( hd->pRequest ) free( hd->pRequest );
// free(buf);
sock_disconnect(sockname);
return(-1);
}
hd->pData = hd->pBase + hd->data_size;
hd->alloc_size += XFERLEN;
}
memcpy( hd->pData, buf, i ); // copy data
hd->pData += i; // increment pointer
hd->data_size += i; // increment size of data
// free(buf);
/* we are continuing, so just return 1 */
return 1;
}
extern int http_write(int socknum, char *sockname) {
int i;
char szContent[32];
char *pContent;
if (strlen(hd->pRequest) > 0) {
return 1;
}
// at this point we can construct our actual request. I'm trying to
// incorporate more methods than the GET method supported by httpget
switch( hd->method )
{
case kHMethodPost:
{
int pathlen;
debug( stderr, "top of post\n" );
// a post URL should include some type of
// data appended with a '?', so we will
// require a '?' be present to continue.
pContent = strchr( hd->path, '?' );
if( pContent != NULL )
{
/* Real lenght of the path.
* We will split the "path" into two parts.
* The arguments (after '?') will go in the body of the
* request. It's size will be in Content-Length
* The real "path" will go in the first line of the request.
* Jean II */
pathlen = pContent - hd->path;
pContent++; // increment to first char of content
}
else
{
hd->response->iError = errno;
hd->response->pError = "ERROR, invalid URL for POST request";
hd->callback(hd->response);
free(hd->response);
if( hd->pRequest ) free( hd->pRequest );
return(1);
}
sprintf( hd->pRequest, "POST %.*s HTTP/1.0\r\nHost: %s\r\n",
pathlen, hd->path, HTTPHOST );
// the following Content-Type may need to be changed
// depending on what type of data you are sending,
// and/or if the data is encoded. ajd 8/28/2001
sprintf( szContent, "%s%d\r\n", "Content-Length: ", strlen( pContent ) );
strcat( hd->pRequest, szContent );
strcat( hd->pRequest, "User-Agent: SecureServ/1.0\r\n" );
strcat( hd->pRequest, "Pragma: no-cache\r\n" );
strcat( hd->pRequest, "Accept: */*\r\n\r\n" );
strcat( hd->pRequest, pContent );
break;
}
case kHMethodHead:
{
sprintf( hd->pRequest, "HEAD %s HTTP/1.0\r\nHost: %s\r\n", hd->path, HTTPHOST );
strcat( hd->pRequest, "User-Agent: SecureServ/1.0\r\n" );
strcat( hd->pRequest, "Pragma: no-cache\r\n" );
strcat( hd->pRequest, "Accept: */*\r\n\r\n" );
break;
}
case kHMethodGet:
default: // currently GET is default!
{
// added in the Host: header entity
// as that was preventing some servers
// from responding properly.
sprintf( hd->pRequest, "GET %s HTTP/1.0\r\nHost: %s\r\n", hd->path, HTTPHOST );
strcat( hd->pRequest, "User-Agent: SecureServ/1.0\r\n" );
strcat( hd->pRequest, "Pragma: no-cache\r\n" );
strcat( hd->pRequest, "Accept: */*\r\n\r\n" );
break;
}
}
nlog(LOG_DEBUG2, LOG_MOD, "HTTP Request: %s", hd->pRequest);
i = write( socknum, hd->pRequest, strlen( hd->pRequest) );
if (i < 0) {
nlog(LOG_NOTICE, LOG_MOD, "HTTP_Get: Write Error: %s", strerror(errno));
hd->response->iError = errno;
hd->response->pError = strerror( errno );
hd->callback(hd->response);
free(hd->response);
if( hd->pRequest ) free( hd->pRequest );
sock_disconnect(sockname);
return -1;
}
/* if we get here, we can allocate some space, and setup the temp buffer */
hd->in_header = 1;
hd->total_bytes = 0UL;
// first we'll allocate a 64k chunk of memory. we don't know the exact size of the
// response. Most web pages fit in 64k of memory, and the is practical. for larger
// transfer I typically like to allocate more up front. Alter to your preference.
// I have tested this transfering a 32mb image using 64k allocations of memory and
// 8k of read buffer.
// ajd 8/27/2001
hd->data_size = 0UL;
hd->pBase = (char *)malloc( XFERLEN );
if( hd->pBase == NULL )
{
hd->response->iError = errno;
hd->response->pError = strerror( errno );
if( hd->path ) free( hd->path );
if( hd->pRequest ) free( hd->pRequest );
hd->callback(hd->response);
free(hd->response);
sock_disconnect(sockname);
return(-1);
}
hd->pData = hd->pBase;
hd->alloc_size = XFERLEN;
return 1;
}
extern int http_error(int socknum, char *sockname) {
return -1;
}
#ifdef HF_DO_FILE
/*
* Function Name: do_file
*
* Parameters: char *in_URL file://URL to request
*
* Description: read and format a file or directory as HTML
*
* Returns: HTTP_Response struct
*
* NOTE: the memory is allocated for the data transfered,
* and it is the responsibility of the *CALLER* to free
* the memory. it's very easy to accumulate several
* megabytes of data.
*
*/
int do_file(char *in_URL)
{
HTTP_Response hResponse = { 0,0,0,0,"","" };
struct stat status;
char temp[BUFLEN];
char *buff;
FILE *doit;
int path;
int count;
int size;
int i;
memset( hResponse.szHCode, '\0', HCODESIZE );
memset( hResponse.szHMsg, '\0', HMSGSIZE );
in_URL += 7;
if(stat(in_URL, &status) || !status.st_mode & S_IRGRP)
{
hResponse.iError = errno;
hResponse.pError = strerror(errno);
return(hResponse);
}
if(S_ISREG(status.st_mode) || S_ISLNK(status.st_mode))
{
buff = (char *)malloc(status.st_size);
if(buff == NULL)
return(hResponse);
if(-1 == (path = open(in_URL, O_RDONLY)))
{
if(buff) free(buff);
hResponse.iError = errno;
hResponse.pError = strerror(errno);
return(hResponse);
}
read(path, buff, status.st_size);
close(path);
buff = realloc(buff, status.st_size);
hResponse.lSize = (long)(status.st_size);
hResponse.pData = buff;
return(hResponse);
}
if(S_ISDIR(status.st_mode))
{
buff = (char *)malloc(XFERLEN);
if(buff == NULL)
return(hResponse);
size = XFERLEN;
count = sprintf(buff, "<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\n<BODY BGCOLOR=\"#99cc99\"><H4>Index of %s</H4>\n<PRE>\n", in_URL, in_URL);
strcpy(temp, in_URL);
i = strlen(temp) - 2;
while(temp[i] != '/' && i > 0)
temp[i--] = '\0';
count += sprintf(&buff[count], "<A HREF=\"file://%s\">Parent Directory</A><P>\n", temp);
(void) sprintf(temp, "ls -lgF '%s' | tail +2 | sed -e 's/^\\([^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]*\\) *\\(.*\\)$/\\1 |\\2/' -e '/ -> /!s,|\\([^*]*\\)$,|<A HREF=\"\\1\">\\1</A>,' -e '/ -> /!s,|\\(.*\\)\\([*]\\)$,|<A HREF=\"\\1\">\\1</A>\\2,' -e '/ -> /s,|\\([^@]*\\)\\(@* -> \\),|<A HREF=\"\\1\">\\1</A>\\2,' -e 's/|//'", in_URL);
doit = popen(temp, "r");
while((i = fread(temp, 1, BUFLEN - 1, doit)) > 0)
{
if(count + i > size)
{
buff = realloc(buff, size + XFERLEN);
if(buff == NULL)
{
hResponse.iError = errno;
hResponse.pError = strerror( errno );
fprintf(stderr, "ERROR (realloc): (errno = %d = %s)\n",
errno, strerror(errno));
fflush( stderr );
return( hResponse );
}
size += XFERLEN;
}
memcpy(&buff[count], temp, i); // copy data
count += i;
}
pclose(doit);
count += sprintf(&buff[count], "</PRE>\n</BODY></HTML>\n");
buff = realloc(buff, count);
hResponse.lSize = count;
hResponse.pData = buff;
return(hResponse);
}
return(hResponse);
}
#endif /* HF_DO_FILE */

129
http.h
View file

@ -1,129 +0,0 @@
/* NeoStats - IRC Statistical Services Copyright
** Copyright (c) 1999-2003 Justin Hammond
** http://www.neostats.net/
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
/***************************************************************************
*
* Library: http
*
* Description: header for libhttp
*
***************************************************************************
*
* Copyright (C) 1994 by Sami Tikka <sti@iki.fi>
* Copyright (C) 2001 by Alan DuBoff <aland@SoftOrchestra.com>
*
* The right to use, modify and redistribute this code is allowed
* provided the above copyright notice and the below disclaimer appear
* on all copies.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <memory.h>
#include <errno.h>
/* this is the DATFILE location */
#define DATFILE "/defs.php"
/* this is the DATFILE Version Location */
#define DATFILEVER "/vers.php"
/* this is the HostName */
#define HTTPHOST "secure.irc-chat.net"
/* Compile time options.
* Allow you to disable library functionality you don't need. - Jean II
*/
#define HF_FIND_HEADER /* find_header() function */
#undef HF_DO_FILE /* do_file() function & functionality */
#define BUFLEN 8192
#define GETLEN 8192
#define XFERLEN 65536
#define HCODESIZE 4
#define HMSGSIZE 32
/* Flags is a mask with the xor of the various options - Jean II */
#define HFLAG_NONE 0x0000 /* No flags */
#define HFLAG_RETURN_HEADER 0x0001 /* Return HTTP headers */
#define HFLAG_POST_USER_TYPE 0x0002 /* Do not add post type */
/* Maybe FORCE_PROXY/FORCE_NO_PROXY , and HFLAG_USER_ACCEPT */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
char *pData; // pointer to data
long lSize; // size of data allocated
char *pHdr; // pointer to header, if requested
int iError; // error upon failures
char *pError; // text description of error
char szHCode[HCODESIZE]; // http response code
char szHMsg[HMSGSIZE]; // message/description of http code
} HTTP_Response, *PHTTP_Response;
typedef enum
{
kHMethodOptions = 1,
kHMethodGet,
kHMethodHead,
kHMethodPost,
kHMethodPut,
kHMethodDelete,
kHMethodTrace
}HTTP_Method;
char *find_header_end( char *buf, int bytes );
char *parse_url( char *url, char *scheme, char *host, int *port );
int http_request( char *in_URL, HTTP_Method in_Method, unsigned long in_Flags,void (*callback)(HTTP_Response *response) );
#ifdef HF_DO_FILE
int do_file(char *in_URL);
#endif /* HF_DO_FILE */
#ifdef HF_FIND_HEADER
char *find_header( char *buf, int bytes, char *type, char *value, int maxv );
#endif /* HF_FIND_HEADER */
#ifdef __cplusplus
}
#endif

4
scan.c
View file

@ -126,10 +126,12 @@ void load_dat() {
if(i)
{
/* We do not really care if the custom file is not present so don't report it except in debug */
nlog(LOG_DEBUG1, LOG_MOD, "No custom.dat file found. %s is disabled", s_SecureServ);
/* as the comment says, we don't care about custom.dat, so don't fool users into thinking SecureSer is disabled by telling them it is! */
nlog(LOG_DEBUG1, LOG_MOD, "No custom.dat file found.", s_SecureServ);
}
else
{
/* we *HAVE* to have a viri.dat file. Otherwise, no go */
nlog(LOG_WARNING, LOG_MOD, "TS: Error, No viri.dat file found. %s is disabled", s_SecureServ);
chanalert(s_SecureServ, "Error not viri.dat file found, %s is disabled", s_SecureServ);
}

View file

@ -29,35 +29,38 @@
#else
#include <unistd.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "stats.h"
#include "dl.h"
#include "log.h"
#include "conf.h"
#include "SecureServ.h"
#include "http.h"
void datver(HTTP_Response *response);
void datdownload(HTTP_Response *response);
void datver(void *data, int status, char *ver, int versize);
void datdownload(void *data, int status, char *ver, int versize);
void GotHTTPAddress(char *data, adns_answer *a);
int AutoUpdate(void);
void DownLoadDat();
static char ss_buf[SS_BUF_SIZE];
/* @brief this is the automatic dat file updater callback function. Checks whats on the website with
** whats local, and if website is higher, either prompts for an upgrade, or does an automatic one :)
**
** NOTE: we can't call http_request from this function as its NOT recursive
** It just compares version numbers of the dat file, and if they are different, starts a new download.
*/
void datver(HTTP_Response *response)
void datver(void *data, int status, char *ver, int versize)
{
int myversion;
SET_SEGV_LOCATION();
SET_SEGV_INMODULE("SecureServ");
/* check there was no error */
if ((response->iError > 0) && (!strcasecmp(response->szHCode, "200"))) {
myversion = atoi(response->pData);
if (status == NS_SUCCESS) {
myversion = atoi(ver);
if (myversion <= 0) {
nlog(LOG_NORMAL, LOG_MOD, "When Trying to Check Dat File Version, we got Permission Denied: %d", myversion);
chanalert(s_SecureServ, "Permission Denied when trying to check Dat File Version: %d", myversion);
@ -67,31 +70,41 @@ void datver(HTTP_Response *response)
if (myversion > SecureServ.viriversion) {
if (SecureServ.autoupgrade > 0) {
SecureServ.doUpdate = 1;
add_mod_timer("DownLoadDat", "DownLoadNewDat", __module_info.module_name, 1);
DownLoadDat();
} else
chanalert(s_SecureServ, "A new DatFile Version %d is available. You should /msg %s update", myversion, s_SecureServ);
}
} else {
nlog(LOG_DEBUG1, LOG_MOD, "Virus Definition check Failed. %s", response->szHCode);
nlog(LOG_DEBUG1, LOG_MOD, "Virus Definition check Failed. %s", ver);
chanalert(s_SecureServ, "Virus Definition Check failed: %s", ver);
return;
}
CLEAR_SEGV_INMODULE();
}
void DownLoadDat()
{
char *tmpname;
SET_SEGV_LOCATION();
/* dont keep trying to download !*/
if (SecureServ.doUpdate == 1) {
del_mod_timer("DownLoadNewDat");
SecureServ.doUpdate = 2;
ircsnprintf(ss_buf, SS_BUF_SIZE, "http://%s%s?u=%s&p=%s", SecureServ.updateurl, DATFILE, SecureServ.updateuname, SecureServ.updatepw);
http_request(ss_buf, 2, HFLAG_NONE, datdownload);
bzero(ss_buf, SS_BUF_SIZE);
ircsnprintf(ss_buf, SS_BUF_SIZE, "u=%s&p=%s", SecureServ.updateuname, SecureServ.updatepw);
tmpname = tempnam(NULL, NULL);
if (new_transfer("http://secure.irc-chat.net/defs.php", ss_buf, NS_MEMORY, "", NULL, datdownload) != NS_SUCCESS) {
nlog(LOG_WARNING, LOG_MOD, "Definition download failed.");
chanalert(s_SecureServ, "Definition Download failed. Check log files");
}
}
return;
}
/* @brief this downloads a dat file and loads the new version into memory if required
*/
void datdownload(HTTP_Response *response)
void datdownload(void *unuseddata, int status, char *data, int datasize)
{
char tmpname[32];
char *tmp, *tmp1;
@ -103,11 +116,11 @@ void datdownload(HTTP_Response *response)
/* clear this flag */
SecureServ.doUpdate = 0;
}
if ((response->iError > 0) && (!strcasecmp(response->szHCode, "200"))) {
if (status == NS_SUCCESS) {
/* check response code */
tmp = malloc(response->lSize);
strlcpy(tmp, response->pData, response->lSize);
tmp = malloc(datasize);
strlcpy(tmp, data, datasize);
tmp1 = tmp;
i = atoi(strtok(tmp, "\n"));
free(tmp1);
@ -121,7 +134,7 @@ void datdownload(HTTP_Response *response)
/* make a temp file and write the contents to it */
strlcpy(tmpname, "viriXXXXXX", 32);
i = mkstemp(tmpname);
write(i, response->pData, response->lSize);
write(i, data, datasize);
close(i);
/* rename the file to the datfile */
rename(tmpname, VIRI_DAT_NAME);
@ -130,8 +143,8 @@ void datdownload(HTTP_Response *response)
nlog(LOG_NOTICE, LOG_MOD, "Successfully Downloaded DatFile Version %d", SecureServ.viriversion);
chanalert(s_SecureServ, "DatFile Version %d has been downloaded and installed", SecureServ.viriversion);
} else {
nlog(LOG_DEBUG1, LOG_MOD, "Virus Definition Download Failed. %s", response->szHCode);
chanalert(s_SecureServ, "Virus Definition Download Failed. %s", response->szHCode);
nlog(LOG_DEBUG1, LOG_MOD, "Virus Definition Download Failed. %s", data);
chanalert(s_SecureServ, "Virus Definition Download Failed. %s", data);
return;
}
@ -155,14 +168,9 @@ void GotHTTPAddress(char *data, adns_answer *a)
strlcpy(SecureServ.updateurl, url, SS_BUF_SIZE);
nlog(LOG_NORMAL, LOG_MOD, "Got DNS for Update Server: %s", url);
if ((SecureServ.updateuname[0] != 0) && SecureServ.updatepw[0] != 0) {
ircsnprintf(ss_buf, SS_BUF_SIZE, "http://%s%s?u=%s&p=%s", url, DATFILEVER, SecureServ.updateuname, SecureServ.updatepw);
http_request(ss_buf, 2, HFLAG_NONE, datver);
/* add a timer for autoupdate. If its disabled, doesn't do anything anyway */
add_mod_timer("AutoUpdate", "AutoUpdateDat", __module_info.module_name, 86400);
AutoUpdate();
} else {
if (SecureServ.verbose) {
chanalert(s_SecureServ, "No Valid Username/Password configured for update Checking. Aborting Update Check");
}
chanalert(s_SecureServ, "No Valid Username/Password configured for update Checking. Aborting Update Check");
}
} else {
chanalert(s_SecureServ, "DNS error Checking for Updates: %s", adns_strerror(ri));
@ -178,8 +186,12 @@ int AutoUpdate(void)
{
SET_SEGV_LOCATION();
if ((SecureServ.autoupgrade > 0) && SecureServ.updateuname[0] != 0 && SecureServ.updatepw[0] != 0 ) {
ircsnprintf(ss_buf, SS_BUF_SIZE, "http://%s%s?u=%s&p=%s", SecureServ.updateurl, DATFILEVER, SecureServ.updateuname, SecureServ.updatepw);
http_request(ss_buf, 2, HFLAG_NONE, datver);
bzero(ss_buf, SS_BUF_SIZE);
ircsnprintf(ss_buf, SS_BUF_SIZE, "u=%s&p=%s", SecureServ.updateuname, SecureServ.updatepw);
if (new_transfer("http://secure.irc-chat.net/vers.php", ss_buf, NS_MEMORY, "", NULL, datver) != NS_SUCCESS) {
nlog(LOG_WARNING, LOG_MOD, "Definition version check failed.");
chanalert(s_SecureServ, "Definition version check failed. Check log files");
}
}
return 0;
}
@ -192,8 +204,14 @@ int do_update(User *u, char **av, int ac)
chanalert(s_SecureServ, "%s tried to update, but Permission was denied", u->nick);
return -1;
}
ircsnprintf(ss_buf, SS_BUF_SIZE, "http://%s%s?u=%s&p=%s", SecureServ.updateurl, DATFILE, SecureServ.updateuname, SecureServ.updatepw);
http_request(ss_buf, 2, HFLAG_NONE, datdownload);
bzero(ss_buf, SS_BUF_SIZE);
ircsnprintf(ss_buf, SS_BUF_SIZE, "u=%s&p=%s", SecureServ.updateuname, SecureServ.updatepw);
if (new_transfer("http://secure.irc-chat.net/vers.php", ss_buf, NS_MEMORY, "", NULL, datver) != NS_SUCCESS) {
prefmsg(u->nick, s_SecureServ, "Definition Download Failed. Check Log Files");
nlog(LOG_WARNING, LOG_MOD, "Definition Download failed.");
chanalert(s_SecureServ, "Definition Download failed. Check log files");
return NS_FAILURE;
}
prefmsg(u->nick, s_SecureServ, "Requesting New Dat File. Please Monitor the Services Channel for Success/Failure");
chanalert(s_SecureServ, "%s requested an update to the Dat file", u->nick);
return 1;