Page suivante Page précédente Table des matières

8. Hacks 6 à 8 : Divers hacks

Introduction par Michael Driscoll fenris@lightspeed.net
Code directement de Ryan R. Klems klems@primenet.com

Voici un peu de C envoyé par Ryan R. Klems rklems@primenet.com.

Il y a trois programmes, le premier mail.c, est un CGI qui parcourt votre fichier de mail pour trouver votre nouvelle adresse IP donnée par le hack 1. Ensuite, il utilise l'adresse IP pour mettre en place une page qui contient un lien vers cette adresse IP.

Le second, pppdm.c, peut probablement prendre la place du hack 1, car il cherche une connection PPP, redémarre pppd s'il est mort, et envoie votre nouvelle adresse au serveur de mail de votre FAI.

Le troisième, portmsg.c, attend une connection telnet sur un port précis. Dès qu'une connection s'établie, il va récupérer votre adresse dans votre fichier de mail, et enverra un message la contenant.

Ces sources auront besoin d'un peu de personnalisation, alors, vous feriez mieux de ne pas y toucher si vous ne savez pas ce que vous faites :-)

Oh, oui, et Ryan m'a écrit pour me dire que ça ne le dérangerais pas de vous aider à mettre en place ce code chez vous si vous lui demandez gentiment :-)

8.1 mail.c


/*
 * mail.c written by Ryan R. Klems (rklems@primenet.com)
 * Copyright 1996, Author releases this source freely, allowing
 * copying and modification, so long as the original copyright notice
 * is maintained.
 *
 * I request that if you use this file you mail me... Thats all I ask =)
 *
 * A CGI for reading through your mailfile and finding an IP
 * address that you had your computer mail to you.
 *
 * Compiling:
 *    gcc mail.c -o mail.cgi
 *
 * Make sure to 'chmod +s mail.cgi' afterwards...must run with set uid
 * bit on to be able to open the mail file.
 */

#include <stdio.h>
#include <string.h>
#define MAILFILE "/var/mail/rklems" /* your mailfile */

main(void)
{
  FILE *mail;   /* file pointer for mail file */
  char bob[80], location[80];

  printf("Content-type: text/html\n\n");
  printf("<HTML><HEAD><TITLE>IP Address</TITLE></HEAD>\n");
  printf("<BODY><BASEFONT SIZE=4>\n");
  printf("<H1>IP Address</H1>\n");
  strcpy(bob, "42.**");
  if((mail = fopen(MAILFILE, "r")) == NULL)
    printf("Mail file is empty or does not exist.\n");
  else
  {
    /*
     * loop continues till end of file because you want most recent IP
     * 198.68. is the domain of my ISP, change to yours...
     */
    while(!feof(mail)) /* until reaching EOF, do this */
    {
      fgets(location, 80, mail); /* Grab a line, from mail */
      sscanf(location, "198.68.%s", bob); /* look for domain */
    }
    strcpy(location, "198.68.");
    strcat(location, bob);
    printf("The IP Address of your computer is: %s\n", location);
  }
  printf("</BODY></HTML>\n");
}

8.2 pppdm.c


/*
 * pppdm.c created by Ryan R. Klems (rklems@primenet.com)
 *   Released freely by the author to use/modify/copy/reditribute
 *   My only request is that if you use it...mail me and let me know =)
 *
 * This program keeps your link dialed up to an ISP and mails you
 * the newest IP address.  Useful for people with Dynamically allocated
 * IP addresses
 * uses the following files...
 * /root/ip        :   Outputs the IP to this file
 * /root/log       :   If logging is defined
 * /root/pppchat   :   The chat file set up for chat.
 *     My chat file looks like:
 *       ""  ATDT7917777 CONNECT "" "ogin:" "rklems" "assword:" "<password>"
 *  <password> is YOUR password of course (like I'm gonna give you mine ;)
 *  *NOTE* for silent dialing do ATMDT
 *
 *  Compiling...
 *    gcc pppdm.c -o pdm
 *  *NOTE* Don't call it anything like pppdm b/c it looks for pppd
 *  might accidentally kill itself off ;)
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#define DOLOG

void main(void)
{
  FILE *fin,            /* multiuse file pointer */
       *popen();        /* proto of popen() */
#ifdef DOLOG
  FILE *log;            /* log file pointer */
#endif
  char line[80],        /* a line of a file */
       bah[80],         /* just stuff, also used for holding IP addr */
       crap[80],        /* just stuff */
       bob;             /* single char placeholder, not used for anything */
  int j,                /* flag for if a link was found */
      k,                /* flag for if this is a new link */
      pid;              /* pid of pppd process to kill off */
#ifdef DOLOG
  time_t now;           /* thing for time logging */
#endif

  for(;;) /* Loop forever... */
  {
    /* look at ifconfig for IP addr */
    if ((fin = popen("ifconfig", "r")) != NULL)
      while(fgets(line, 80, fin) != NULL)
        if(sscanf(line, "ppp0 %s", bah))
        {
          fgets(line, 80, fin);
          sscanf(line, "          inet addr:%15s", bah);
          j=1;
        }
    fclose(fin);
    if (!j) /* no link */
    {
      if((fin = popen("ps -a -x", "r")) == NULL)
      {
        fprintf(stderr, "PPPdm error: cannot open file.\n");
        exit(1);
      }
      /* scan through processes & kill off any zombie pppd processes */
      while(fgets(line, 80, fin) != NULL)
        if (sscanf(line, "%d  ?  %c     %4s pppd%s", &pid, &bob, crap, bah) == 4)
          kill(pid, SIGKILL);
      fclose(fin);
      k=0; /* new dial attempt */
      system("pppd connect 'chat -v -f /root/pppchat'"); /* try again */
#ifdef DOLOG
      now = time(NULL);
      if ((log = fopen("/root/log", "a")) == NULL)
      {
        fprintf(stderr, "Error in opening log file.\n");
        exit(1);
      }
      fprintf(log, "Initiating ppp-link. %s\n", ctime(&now));
      fclose(log);
#endif
      sleep(60); /* wait 1 min and check again */
    }
    if(j && !k) /* first time with new address */
    {
      if ((fin = fopen("/root/ip", "w")) == NULL)
      {
        fprintf(stderr, "Error in opening output file.\n");
        exit(1);
      }
      fprintf(fin, "%s\n", bah); /* write out addr */
      fclose(fin);
      /* mail it to yourself */
      system("mail -s IP joker@your.moma.com < /root/ip");
      k=1;
    }
    else /* take a nap and check again when we wake up */
    {
      j = 0;
      sleep(300); /* wait 5 minutes to check again */
    }
  }
}

8.3 portmsg.c


/*
 * Portmsg.c written by Ryan R. Klems (rklems@primenet.com)
 * Copyright 1996, Author releases this source freely, allowing
 * copying and modification, so long as the original copyright notice
 * is maintained.
 *
 * I request that if you use this program that you mail me.  Thats
 * all I ask.
 *
 * This program sets up a port on a server to accept telnets.  Upon
 * accepting a telnet, the program outputs a message, and then closes
 * the connection.
 *
 * address of message would be xxx.xxx.xxx.xxx yyyy where the x's
 * s the IP number or IP name, and yyyy is the port number set up
 * within this program.
 *
 * Compiling instructions:
 *      Linux : gcc portmsg_gen.c -o <your_file_name>
 *      SunOS : gcc portmsg_gen.c -lsocket -lnsl -o <your_file_name>
 * ***Note***
 *  I don't have access to any other operating systems, so if you
 *  compile this program on an OS I don't have listed, and use
 *  compiler options I didn't mention...please email me =)
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <errno.h>
#include <netinet/in.h>
#include <strings.h>
#include <netdb.h>
#include <unistd.h>
#define HOSTNAME "ares" /* hostname of computer */
#define PORT 3000       /* tcp port to bind to */
/* #define GETHOSTNAME */ /* uncomment if your server has gethostname() */

void get_location(void);        /* proto of my mail reading function */
char location[80];              /* The IP address */

void main(void)
{
  struct in_addr host_ip_number;
  struct sockaddr_in host_ip_addr;
  struct sockaddr_in addr;
  char host_name[100];
  struct hostent *hp;
  int s, new_sock;
  int tmp, length;

  /*
   * The server I wrote this for doesn't have gethostname()
   * so, I put in a little fix...
   */
#ifdef GETHOSTNAME
  gethostname(host_name, sizeof(host_name));
#else
  strcpy(host_name, HOSTNAME);
#endif
  hp = gethostbyname(host_name);
  bzero((char *)&host_ip_addr, sizeof(host_ip_addr));
  memcpy((char *)&host_ip_addr.sin_addr, hp->h_addr, hp->h_length);
  host_ip_addr.sin_family = hp->h_addrtype;
  host_ip_number = host_ip_addr.sin_addr;
  host_ip_addr.sin_port = htons(PORT);
  host_ip_addr.sin_addr.s_addr = INADDR_ANY;
  /* open a socket s */
  s = socket(host_ip_addr.sin_family, SOCK_STREAM, 0);
  if ((int)s==-1)
  {
    fprintf(stderr, "Error in opening socket.\n");
    exit(1);
  }
  tmp = 1;
  if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp))<0)
  {
    fprintf(stderr, "Error in setsockopt.\n");
    exit(1);
  }
  /* bind the socket to the server */
  if (bind(s, (struct sockaddr *)&host_ip_addr, sizeof(host_ip_addr))  == -1)
  {
    if(errno == EADDRINUSE)
    {
      fprintf(stderr, "Socket already bound!\n");
      exit(1);
    }
    else
    {
      fprintf(stderr, "Other error binding socket.\n");
      exit(1);
    }
  }
  /* tell the server to listen to the port */
  if (listen(s, 1) == -1)
/* 1 is the maximum size of the connection queue */
  {
    fprintf(stderr, "Error in listen.\n");
    exit(1);
  }
 while(1) /* just keep looping */
 {
   length = sizeof(addr);
   /*
    * port has been opened with socket(), bound with bind(), and set
    * active with listen(), now accept() watches the port for
    * connections, it will wait here until it has one...
    * new_sock is the file descriptor for the new socket
    */
   new_sock = accept(s, (struct sockaddr *)&addr, &length);
/*
 * The function get_location() and the send()'s are what I did to
 * suit my particular needs.  Put your own messages in here...
 */
   get_location();
   /* send just sends a string foo of length strlen(foo) with flags */
   send(new_sock, "Location:\n", 11, 0);
   send(new_sock, location, strlen(location), 0);
   close(new_sock); /* Close connection after message printed */
 }
}

void get_location(void)
{
  FILE *mail;   /* file pointer for mail file */
  char a[80];   /* char array for holding ip addr */

/*
 * FYI, this just opens my mail file, looks for a line with
 * 198.68.(the domain of my ISP), takes the last part, puts
 * the 198.68. in location, then cats the rest on the end
 */
  strcpy(a, "42.**");
  /* open /var/mail/ryan for read, and check to see there is a file */
  if((mail = fopen("/var/mail/ryan", "r")) == NULL)
  {
    strcpy(location, "Error in obtaining information.\n");
    return;
  }
  else
  {
    while(!feof(mail)) /* until reaching EOF, do this */
    {
      fgets(location, 80, mail); /* Grab a line, from mail */
      sscanf(location, "198.68.%s", a); /* look for domain */
    }
    strcpy(location, "198.68.");
    strcat(location, a);
    /* loops continues till end of file because I want most recent IP */
  }
}


Page suivante Page précédente Table des matières