1. Instalação e execução
O meu IMsniff também parava constantemente, então pesquisando encontrei uma solução: substituir algumas linhas nos arquivos msn_conntrack.cpp e util.cpp. Como não lembro qual parte deve ser substituída, aí vão os arquivos: (Vale lembrar que o programa deve ser recompilado)
msn_conntrack.cpp
/* THE CODE HERE TAKES CARE OF KEEPING TRACKING OF THE INFORMATION WE
COLLECT ABOUT ONGOING TCP CONNECTIONS */
#include "imsniff.h"
struct msn_connection *msn_conns_first = NULL;
struct msn_connection *msn_conns_last = NULL;
void add_user_to_sb (struct msn_connection *conn, u_char *user)
{
if (conn!=NULL && conn->users!=NULL)
{
int i=0;
while (i<conn->num_users)
{
if (strcmp ((char *) conn->users[i], (char *) user)==0)
return; // Don't duplicate
i++;
}
}
log_debug (5, "Adding user [%s] to SB",user);
if (!conn)
{
conn = (struct msn_connection *) malloc (sizeof (struct msn_connection));
if (!conn)
return;
if (msn_conns_first==NULL)
msn_conns_first=conn;
memset (conn,0,sizeof (struct msn_connection)); // All zeros is fine
if (msn_conns_last != NULL)
{
msn_conns_last->next=conn;
conn->previous=msn_conns_last;
}
msn_conns_last=conn;
conn->users=NULL;
conn->num_users=0;
conn->log_full_path=NULL;
}
conn->users=(u_char **) realloc (conn->users, sizeof (u_char *) * (conn->num_users+1));
log_debug (5, "Done realloc");
if (conn->users!=NULL)
{
conn->users[conn->num_users]=(u_char *) malloc (strlen ((char *) user) +1 );
log_debug (5, "Done malloc");
strcpy ((char *) conn->users[conn->num_users],(char *) user);
log_debug (5, "Done strcpy");
conn->num_users++;
}
log_debug (5, "Done, number of users now = %d",conn->num_users);
}
void clear_msn_connection (struct msn_connection *conn)
{
log_debug (3, "Clearing connection %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d",
conn->IP_A.byte1,conn->IP_A.byte2,conn->IP_A.byte3,conn->IP_A.byte4,
conn->port_A, conn->IP_B.byte1,
conn->IP_B.byte2,conn->IP_B.byte3,conn->IP_B.byte4,conn->port_B);
if (conn->owner!=NULL)
{
free (conn->owner);
conn->owner=NULL;
}
conn->conn_type=type_unknown;
if (conn->users!=NULL)
{
int i=0;
while (i<conn->num_users)
{
free (conn->users[i]);
i++;
}
free (conn->users);
conn->num_users=0;
}
if (conn->pending_A!=NULL)
free (conn->pending_A);
if (conn->pending_B!=NULL)
free (conn->pending_B);
if (conn->log_full_path!=NULL)
free (conn->log_full_path);
conn->pending_A_length=0;
conn->pending_B_length=0;
conn->pending_A=NULL;
conn->pending_B=NULL;
conn->log_full_path=NULL;
conn->whowserver=unknown;
}
void set_owner (struct msn_connection *conn, u_char *owner)
{
if (conn==NULL || owner==NULL)
{
log_debug (0, "Entry in set_owner() with NULL parameter(s)");
return;
}
log_debug (5, "Setting owner [%s] to connection %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d",
owner, conn->IP_A.byte1,conn->IP_A.byte2,conn->IP_A.byte3,conn->IP_A.byte4,
conn->port_A, conn->IP_B.byte1,
conn->IP_B.byte2,conn->IP_B.byte3,conn->IP_B.byte4,conn->port_B);
if (conn->owner != NULL)
{
if (strcmp ((char *) conn->owner, (char *) owner))
{
log_debug (0, "Warning: Owner change in MSN connection, this looks like a bug");
}
else
{
log_debug (5, "set_owner(): Owner match, all OK");
}
}
else
{
log_debug (5, "(no previous owner)");
}
strcpymalloc (&conn->owner, owner);
}
int is_from_A (struct msn_connection *conn, ip_address *ip, int port)
{
if (conn==NULL)
return -1;
if (conn->IP_A.byte1 == ip->byte1 &&
conn->IP_A.byte2 == ip->byte2 &&
conn->IP_A.byte3 == ip->byte3 &&
conn->IP_A.byte4 == ip->byte4 &&
conn->port_A == port)
{
return 1;
}
if (conn->IP_B.byte1 == ip->byte1 &&
conn->IP_B.byte2 == ip->byte2 &&
conn->IP_B.byte3 == ip->byte3 &&
conn->IP_B.byte4 == ip->byte4 &&
conn->port_B == port)
{
return 0;
}
return -1; // Not from any of them */
}
int is_from_server (struct msn_connection *conn, ip_address *ip, int port)
{
if (conn==NULL)
return -1;
if (conn->IP_A.byte1 == ip->byte1 &&
conn->IP_A.byte2 == ip->byte2 &&
conn->IP_A.byte3 == ip->byte3 &&
conn->IP_A.byte4 == ip->byte4 &&
conn->port_A == port)
{
if (conn->whowserver==endpointA)
return 1;
else
return 0;
}
if (conn->IP_B.byte1 == ip->byte1 &&
conn->IP_B.byte2 == ip->byte2 &&
conn->IP_B.byte3 == ip->byte3 &&
conn->IP_B.byte4 == ip->byte4 &&
conn->port_B == port)
{
if (conn->whowserver==endpointB)
return 1;
else
return 0;
}
return -1; // Not server and not user?
}
void set_as_server (struct msn_connection *conn, ip_address *ip, int port)
{
if (conn==NULL)
return;
if (conn->IP_A.byte1 == ip->byte1 &&
conn->IP_A.byte2 == ip->byte2 &&
conn->IP_A.byte3 == ip->byte3 &&
conn->IP_A.byte4 == ip->byte4 &&
conn->port_A == port)
{
if (conn->whowserver==endpointB)
{
log_debug (0, "Warning: In this connection, the server was previously misidentified");
}
conn->whowserver=endpointA;
}
else
{
if (conn->whowserver==endpointA)
{
log_debug (0, "Warning: In this connection, the server was previously misidentified");
}
conn->whowserver=endpointB;
}
}
int remove_msn_connection (struct msn_connection *conn)
{
if (conn)
{
log_debug (5, "Removing connection from linked list");
clear_msn_connection (conn);
if (conn->previous!=NULL)
conn->previous->next=conn->next;
if (conn->next!=NULL)
conn->next->previous=conn->previous;
if (msn_conns_first == conn)
msn_conns_first = conn->next;
if (msn_conns_last == conn)
msn_conns_last = conn->previous;
free (conn);
}
return 0;
}
struct msn_connection *get_or_create_msn_connection (ip_address *source_ip, int source_port,
ip_address *target_ip, int target_port,
enum e_msn_conn_create create)
{
struct msn_connection * ipa = msn_conns_first;
log_debug (5,"get_or_create_msn_connection: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d",
source_ip->byte1,source_ip->byte2,source_ip->byte3,source_ip->byte4,source_port,
target_ip->byte1,target_ip->byte2,target_ip->byte3,target_ip->byte4,target_port);
int i=0;
while (ipa)
{
log_debug (6,"%d - IPA: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d",i,
ipa->IP_A.byte1,ipa->IP_A.byte2,ipa->IP_A.byte3,ipa->IP_A.byte4,ipa->port_A,
ipa->IP_B.byte1,ipa->IP_B.byte2,ipa->IP_B.byte3,ipa->IP_B.byte4,ipa->port_B);
if ((ipa->IP_A.byte1 == source_ip->byte1 &&
ipa->IP_A.byte2 == source_ip->byte2 &&
ipa->IP_A.byte3 == source_ip->byte3 &&
ipa->IP_A.byte4 == source_ip->byte4 &&
ipa->port_A == source_port &&
ipa->IP_B.byte1 == target_ip->byte1 &&
ipa->IP_B.byte2 == target_ip->byte2 &&
ipa->IP_B.byte3 == target_ip->byte3 &&
ipa->IP_B.byte4 == target_ip->byte4 &&
ipa->port_B == target_port) ||
(ipa->IP_A.byte1 == target_ip->byte1 &&
ipa->IP_A.byte2 == target_ip->byte2 &&
ipa->IP_A.byte3 == target_ip->byte3 &&
ipa->IP_A.byte4 == target_ip->byte4 &&
ipa->port_A == target_port &&
ipa->IP_B.byte1 == source_ip->byte1 &&
ipa->IP_B.byte2 == source_ip->byte2 &&
ipa->IP_B.byte3 == source_ip->byte3 &&
ipa->IP_B.byte4 == source_ip->byte4 &&
ipa->port_B == source_port))
{
log_debug (6, "Match");
if (create==create_replace)
clear_msn_connection(ipa);
log_debug (5, "Connection requested found");
return ipa;
}
else
{
log_debug (5, "No match");
}
i++;
ipa=ipa->next;
}
if (create==create_yes)
{
struct msn_connection * ipa = (struct msn_connection *) malloc (sizeof (struct msn_connection));
log_debug (5, "Creating new connection, %d", i);
if (ipa!=NULL)
{
if (msn_conns_first==NULL)
msn_conns_first=ipa;
memset (ipa,0,sizeof (struct msn_connection)); // All zeros is fine
if (msn_conns_last != NULL)
{
msn_conns_last->next=ipa;
ipa->previous=msn_conns_last;
}
msn_conns_last=ipa;
memcpy (&ipa->IP_A,source_ip,sizeof (struct ip_address));
ipa->port_A=source_port;
memcpy (&ipa->IP_B,target_ip,sizeof (struct ip_address));
ipa->port_B=target_port;
ipa->whowserver=unknown;
ipa->num_users=0;
ipa->users=NULL;
ipa->log_full_path=NULL;
return ipa;
}
}
return NULL;
}
util.cpp
#include "imsniff.h"
#include <stdarg.h>
#include <time.h>
#include <ctype.h>
int debug_level = 2;
char *gettimestring4log (char *store)
{
time_t now=time (NULL);
#ifdef WIN32
struct tm *stm;
stm = localtime (&now);
strncpy (store, asctime(stm), 24);
#else
struct tm stm;
localtime_r (&now, &stm);
asctime_r (&stm, store);
#endif
store[24]=0;
return store;
}
int createdir4nick (u_char *nick)
{
if (nick && nick[0])
{
char dir[1024];
strcpy (dir, chatlogdir);
if (dir[strlen (dir)-1]!='/')
strcat (dir,"/");
strcat (dir,(char *) nick);
#ifdef WIN32
mkdir (dir);
#else
mkdir (dir,0755);
#endif
}
return 0;
}
int log_switchboard_end (struct msn_connection *conn)
{
if (conn!=NULL && conn->log_full_path!=NULL)
{
FILE *o=fopen (conn->log_full_path, "a+t");
if (o!=NULL)
{
fprintf (o, "********************* CHAT END *************************\n");
fclose (o);
}
}
return 0;
}
int log_switchboard_event (struct msn_connection *conn, const char *fmt, ...)
{
char strtme[27];
char *result;
int firsttime = 0;
if (conn == NULL || conn->owner == NULL)
{
log_debug (0, "No switchboard or unknown owner, can't log");
return -1;
}
if (conn->log_full_path==NULL && chatlogdir[0]!=0)
{
if (conn->users==NULL || conn->users[0]==NULL)
{
log_debug (0, "No known partipants in SB owned by %s, can't log", conn->owner);
return -1;
}
size_t l=strlen (chatlogdir)+1+strlen ((char *) conn->owner)+1+
strlen ((char *) conn->users[0])+5;
conn->log_full_path=(char *) malloc (l);
if (conn->log_full_path==NULL)
return -1;
sprintf (conn->log_full_path,"%s/%s/%s.txt",chatlogdir,conn->owner,conn->users[0]);
log_debug (0, "Set SB log name to: %s",conn->log_full_path);
firsttime = 1;
}
gettimestring4log (strtme);
va_list ap;
#ifdef WIN32
result=(char *) malloc (MAX_VPRINTF);
if (result)
{
va_start(ap, fmt);
vsnprintf (result, MAX_VPRINTF, fmt, ap);
va_end (ap);
}
#else
va_start (ap, fmt);
vasprintf (&result,fmt,ap);
va_end (ap);
#endif
if (conn->log_full_path!=NULL)
{
FILE *o=fopen (conn->log_full_path, "a+t");
if (o!=NULL)
{
if (firsttime)
fprintf (o, "********************* CHAT START *************************\n");
fprintf (o, "%s | %s\n", strtme, result);
fclose (o);
}
else
{
log_debug (0, "Failed to create/append SB event file at [%s]", conn->log_full_path);
}
}
else
{
log_debug (0, "SB event: %s", result);
}
free (result);
return 0;
}
int delete_profile (u_char *nick)
{
if (nick && nick[0]!=0 && chatlogdir[0]!=0)
{
log_debug (3, "Deleting profile [%s]", nick);
char fn[1024];
sprintf (fn, "%s/%s/profile.txt", chatlogdir, nick);
unlink (fn);
}
return 0;
}
int delete_contact_list (u_char *nick)
{
if (nick && nick[0]!=0 && chatlogdir[0]!=0)
{
log_debug (3, "Deleting contact list for [%s]", nick);
char fn[1024];
sprintf (fn, "%s/%s/contact_list.txt", chatlogdir, nick);
unlink (fn);
}
return 0;
}
int log_profile (u_char *nick, u_char *payload, int length)
{
char strtme[27];
gettimestring4log (strtme);
log_debug (5, "Entry in log_profile");
if (nick && nick[0]==0)
log_debug (3, "Profile for an unknown user, not logged");
else
{
u_char *prof = (u_char *) malloc (length + 1);
if (prof == NULL)
return OUT_OF_MEMORY;
memcpy (prof, payload, length);
prof[length]=0;
if (chatlogdir[0]==0)
{
log_debug (1, "%s | %s | %s", strtme, nick, prof);
}
else
{
createdir4nick (nick);
char fn[1024];
sprintf (fn, "%s/%s/profile.txt", chatlogdir, nick);
FILE *o=fopen (fn, "w");
// printf ("%s\n",fn);
if (o!=NULL)
{
fwrite (prof, 1, length, o);
fclose (o);
}
else
{
log_debug (0, "Failed to create profile file [%s]", fn);
}
}
free (prof);
}
return 0;
}
int log_contact (u_char *nick, u_char *contact)
{
char strtme[27];
gettimestring4log (strtme);
log_debug (5, "Entry in log_contact");
if (nick && nick[0]==0)
log_debug (3, "Contact [%s] for an unknown user, not logged", contact);
else
{
if (chatlogdir[0]==0)
{
log_debug (1, "%s | %s | Contact: %s", strtme, nick, contact);
}
else
{
createdir4nick (nick);
char fn[1024];
sprintf (fn, "%s/%s/contact_list.txt", chatlogdir, nick);
FILE *o=fopen (fn, "a+t");
// printf ("%s\n",fn);
if (o!=NULL)
{
fprintf (o, "%s | %s\n", strtme, contact);
fclose (o);
}
else
{
log_debug (0, "Failed to create contact file [%s]", fn);
}
}
}
return 0;
}
int log_debug (int level, const char *fmt, ...)
{
char *result;
char strtme[27];
if (level<=debug_level)
{
gettimestring4log (strtme);
va_list ap;
#ifdef WIN32
result=(char *) malloc (MAX_VPRINTF);
if (result)
{
va_start(ap, fmt);
vsnprintf (result, MAX_VPRINTF, fmt, ap);
va_end (ap);
}
#else
va_start (ap, fmt);
vasprintf (&result,fmt,ap);
va_end (ap);
#endif
if (debuglogdir[0]==0)
{
if (!daemonize)
printf ("%s | %d | %s\n", strtme, level, result);
}
else
{
char fn[1024];
time_t now=time (NULL);
#ifdef WIN32
struct tm *stm;
stm= localtime (&now);
sprintf (fn, "%s/imsniff_%04d-%02d-%02d.txt", debuglogdir, stm->tm_year, stm->tm_mon, stm->tm_mday);
#else
struct tm stm;
localtime_r (&now, &stm);
sprintf (fn, "%s/imsniff_%04d-%02d-%02d.txt", debuglogdir, stm.tm_year, stm.tm_mon, stm.tm_mday);
#endif
FILE *o=fopen (fn, "a+t");
if (o!=NULL)
{
fprintf (o, "%s | %d | %s\n", strtme, level, result);
fclose (o);
}
}
free (result);
}
return 0;
}
int log_event (u_char *nick, const char *fmt, ...)
{
char *result;
va_list ap;
char strtme[27];
#ifdef WIN32
result=(char *) malloc (MAX_VPRINTF);
if (result)
{
va_start(ap, fmt);
vsnprintf (result, MAX_VPRINTF, fmt, ap);
va_end (ap);
}
#else
va_start (ap, fmt);
vasprintf (&result,fmt,ap);
va_end (ap);
#endif
gettimestring4log (strtme);
if (nick==NULL || nick[0]==0)
log_debug (1, "Event for an unknown nick: %s", result);
else
{
if (chatlogdir[0]==0)
{
log_debug (1, "Nick [%s] Event: [%s]", nick, result);
}
else
{
createdir4nick (nick);
char fn[1024];
sprintf (fn, "%s/%s/events.txt", chatlogdir, nick);
FILE *o=fopen (fn, "a+t");
// printf ("%s\n",fn);
if (o!=NULL)
{
fprintf (o, "%s | %s\n", strtme, result);
fclose (o);
}
}
}
free (result);
return 0;
}
int get_new_line_malloc (u_char **target, u_char *source, int length)
{
int must_free=0;
if (length<2) // No room for \r\n
{
log_debug (5, "get_new_line_malloc: line too short.");
return LINE_INCOMPLETE;
}
if (target!=NULL)
{
if (*target != NULL)
free (*target);
*target = (u_char *) malloc (length + 1);
if (*target == NULL)
return OUT_OF_MEMORY;
memset (*target, 0, length+1);
}
u_char *now = source; // Where we are copying from
u_char *work = (target==NULL)?NULL:*target; // Where, if anywhere, we are copying to
int skipped=0;
while (skipped<length-2 && *now!='\n' && *now!='\r')
{
if (work!=NULL && *now>=' ')
{
*work=*now;
*work++;
}
skipped++;
*now++;
}
if ( *(now)!='\r' || *(now+1)!='\n') // No \r\n? Not MSN or incomplete
{
log_debug (5, "get_new_line_malloc: Incomplete\n");
log_debug (5, "get_new_line_malloc: Source was: %s\n",source); // TODO: Fix not null-terminated!
return -1;
}
return skipped+2; // Skip \r\n too
}
/* Note: *line must be zero-terminated (as returned by get_new_line_malloc) */
void dump_tokens (u_char **tokens)
{
if (tokens==NULL)
return;
int i=0;
while (tokens[i]!=NULL)
{
log_debug (0, "Token %d: %s",i, tokens[i]);
i++;
}
}
u_char *strcpymalloc (u_char **target, u_char * src)
{
if (target==NULL)
return NULL;
if (*target!=NULL)
free (*target);
*target=(u_char *) malloc (strlen ((char *) src)+1);
if (*target!=NULL)
{
strcpy ((char *) *target,(char *) src);
}
return *target;
}
void free_array (u_char ***tokens)
{
if (*tokens!=NULL)
{
int i=0;
while ((*tokens)[i]!=NULL)
{
free ((*tokens)[i]);
i++;
}
/* ...free the array itself */
free (*tokens);
}
}
int get_tokens (u_char *line, u_char ***tokens, int max_tokens)
{
log_debug (5, "entry in get_tokens");
int capacity = (max_tokens==0)?50:max_tokens;
/* First, delete the tokens if there are any ... */
free_array(tokens);
*tokens=(u_char **) malloc (sizeof (u_char *) * (capacity +1)); // Final one is NULL
if (*tokens==NULL)
return OUT_OF_MEMORY;
int num=0; /* Number of tokens added so far */
u_char *now = line;
u_char *newtoken;
for (;;)
{
size_t i;
/* Skip spaces and control stuff */
while (*now<=' ' && *now!=0)
{
now++;
}
if (*now==0) /* End of line */
break;
i=0;
if (max_tokens==num+1 && max_tokens!=0)
i=strlen ((char *) now);
else
{
while (now[i]>' ') /* Look ahead, how long is the next token? */
i++;
}
newtoken=(u_char *) malloc (i+1);
memcpy (newtoken, now, i);
now = now + i;
newtoken[i]=0;
if (num==capacity)
{
capacity += 10;
*tokens = (u_char **) realloc (*tokens, sizeof (u_char *) * (capacity +1));
if (*tokens==NULL) /* A bit unstable now I'm afraid */
return OUT_OF_MEMORY;
}
(*tokens)[num]=newtoken;
if (num==7)
{
break;
}
num++;
}
(*tokens)[num]=NULL;
return num;
}
int get_value_from_hex (char c)
{
c=toupper (c);
if (c>='0' && c<='9')
return c-'0';
if (c>='A' && c<='F')
return c-'A';
return -1;
}
u_char *urldecode (u_char *src)
{
u_char *tmp = (u_char *) malloc (strlen ((char *) src) + 1);
u_char *c = src;
if (tmp==NULL)
return src;
memset (tmp, 0, strlen ((char *) src) +1);
u_char *now = tmp;
while (*c)
{
if (*c!='%')
{
*now = *c;
now++;
c++;
}
else
{
if (*(c+1)==0 || *(c+2)==0) // ?? Doesn't look good.
{
free (tmp);
return src;
}
int v1 = get_value_from_hex (* (c+1));
int v2 = get_value_from_hex (* (c+2));
if (v1==-1 || v2==-1)
{
free (tmp);
return src;
}
*now = (v1*16+v2);
now++;
c+=3;
}
}
strcpy ((char *) src, (char *) tmp);
free (tmp);
return src;
}