示例#1
0
文件: net.c 项目: Abysim/NyanLion
/* Return a free entry in the socket entry for a tcl socket
 *
 * alloctclsock() can be called by Tcl threads
 */
int alloctclsock(register int sock, int mask, Tcl_FileProc *proc, ClientData cd)
{
  int f = -1;
  register int i;
  struct threaddata *td = threaddata();

  for (i = 0; i < td->MAXSOCKS; i++) {
    if (td->socklist[i].flags & SOCK_UNUSED) {
      if (f == -1)
        f = i;
    } else if ((td->socklist[i].flags & SOCK_TCL) &&
               td->socklist[i].sock == sock) {
      f = i;
      break;
    }
  }
  if (f != -1) {
    td->socklist[f].sock = sock;
    td->socklist[f].flags = SOCK_TCL;
    td->socklist[f].handler.tclsock.mask = mask;
    td->socklist[f].handler.tclsock.proc = proc;
    td->socklist[f].handler.tclsock.cd = cd;
    return f;
  }
  /* Try again if enlarging socketlist works */
  if (increase_socks_max())
    return -1;
  else
    return alloctclsock(sock, mask, proc, cd);
}
示例#2
0
文件: tls.c 项目: ArNz8o8/Fr3shness
/* Get the certificate, corresponding to the connection
 * identified by sock.
 *
 * Return value: pointer to a X509 certificate or NULL if we couldn't
 * look up the certificate.
 */
static X509 *ssl_getcert(int sock)
{
  int i;
  struct threaddata *td = threaddata();
  
  i = findsock(sock);
  if (i == -1 || !td->socklist[i].ssl)
    return NULL;
  return SSL_get_peer_certificate(td->socklist[i].ssl);
}
示例#3
0
文件: tls.c 项目: ArNz8o8/Fr3shness
/* Count allocated memory for SSL. This excludes memory allocated by OpenSSL's
 * family of malloc functions.
 */
int expmem_tls()
{
  int i, tot;
  struct threaddata *td = threaddata();

  /* currently it's only the appdata structs allocated by ssl_handshake() */
  for (i = 0, tot = 0; i < td->MAXSOCKS; i++)
    if (!(td->socklist[i].flags & (SOCK_UNUSED | SOCK_TCL)))
      if (td->socklist[i].ssl && SSL_get_app_data(td->socklist[i].ssl))
        tot += sizeof(ssl_appdata);
  return tot;
}
示例#4
0
int expmem_dccutil()
{
  int tot, i;

  tot = sizeof(struct dcc_t) * max_dcc;
  tot += sizeof(sock_list) * threaddata()->MAXSOCKS;

  for (i = 0; i < dcc_total; i++) {
    if (dcc[i].type && dcc[i].type->expmem)
      tot += dcc[i].type->expmem(dcc[i].u.other);
  }
  return tot;
}
示例#5
0
文件: net.c 项目: Abysim/NyanLion
int expmem_net()
{
  int i, tot = 0;
  struct threaddata *td = threaddata();

  for (i = 0; i < td->MAXSOCKS; i++) {
    if (!(td->socklist[i].flags & (SOCK_UNUSED | SOCK_TCL))) {
      if (td->socklist[i].handler.sock.inbuf != NULL)
        tot += strlen(td->socklist[i].handler.sock.inbuf) + 1;
      if (td->socklist[i].handler.sock.outbuf != NULL)
        tot += td->socklist[i].handler.sock.outbuflen;
    }
  }
  return tot;
}
示例#6
0
文件: net.c 项目: Abysim/NyanLion
/* Done with a tcl socket
 *
 * killtclsock() can be called by Tcl threads
 */
void killtclsock(register int sock)
{
  register int i;
  struct threaddata *td = threaddata();

  if (sock < 0)
    return;

  for (i = 0; i < td->MAXSOCKS; i++) {
    if ((td->socklist[i].flags & SOCK_TCL) && td->socklist[i].sock == sock) {
      td->socklist[i].flags = SOCK_UNUSED;
      return;
    }
  }
}
示例#7
0
文件: net.c 项目: Abysim/NyanLion
/* Sets/Unsets options for a specific socket.
 *
 * Returns:  0   - on success
 *           -1  - socket not found
 *           -2  - illegal operation
 */
int sockoptions(int sock, int operation, int sock_options)
{
  int i;
  struct threaddata *td = threaddata();

  for (i = 0; i < td->MAXSOCKS; i++)
    if ((td->socklist[i].sock == sock) &&
        !(td->socklist[i].flags & SOCK_UNUSED)) {
      if (operation == EGG_OPTION_SET)
        td->socklist[i].flags |= sock_options;
      else if (operation == EGG_OPTION_UNSET)
        td->socklist[i].flags &= ~sock_options;
      else
        return -2;
      return 0;
    }
  return -1;
}
示例#8
0
文件: net.c 项目: Abysim/NyanLion
/* Return a free entry in the socket entry
 */
int allocsock(int sock, int options)
{
  int i;
  struct threaddata *td = threaddata();

  for (i = 0; i < td->MAXSOCKS; i++) {
    if (td->socklist[i].flags & SOCK_UNUSED) {
      /* yay!  there is table space */
      td->socklist[i].handler.sock.inbuf = NULL;
      td->socklist[i].handler.sock.outbuf = NULL;
      td->socklist[i].handler.sock.inbuflen = 0;
      td->socklist[i].handler.sock.outbuflen = 0;
      td->socklist[i].flags = options;
      td->socklist[i].sock = sock;
      return i;
    }
  }
  /* Try again if enlarging socketlist works */
  if (increase_socks_max())
    return -1;
  else
    return allocsock(sock, options);
}
示例#9
0
/* This function is called to enlarge the static sockettable in a thread.
 * It keeps the mainthread dcc table enlarging with the main thread sockettable
 * If this fails because the upper limit max_socks is reached, -1 is returned.
 * If this was called from the main thread, it updates the socklist variable
 *
 * increase_socks_max() can be called by Tcl threads
 */
int increase_socks_max()
{
  struct threaddata *td = threaddata();
  int osock = td->MAXSOCKS;

  if (max_socks < 1)
    max_socks = 1;

  if (td->MAXSOCKS == max_socks) {
    putlog(LOG_MISC, "*", "Maximum socket limit reached. Consider raising max-socks.");
    return -1;
  }

  td->MAXSOCKS += 10;
  if (td->MAXSOCKS > max_socks)
    td->MAXSOCKS = max_socks;

  if (td->socklist)
    td->socklist = nrealloc(td->socklist, sizeof(sock_list) * td->MAXSOCKS);
  else
    td->socklist = nmalloc(sizeof(sock_list) * td->MAXSOCKS);
  for (; osock < td->MAXSOCKS; osock++)
    td->socklist[osock].flags = SOCK_UNUSED;

  if (td->mainthread) {
    max_dcc = td->MAXSOCKS - 10;
    if (max_dcc < 1)
      max_dcc = 1;
    if (dcc)
      dcc = nrealloc(dcc, sizeof(struct dcc_t) * max_dcc);
    else
      dcc = nmalloc(sizeof(struct dcc_t) * max_dcc);
    socklist = td->socklist;
  }

  return 0;
}
示例#10
0
文件: net.c 项目: Abysim/NyanLion
/* Request a normal socket for i/o
 */
void setsock(int sock, int options)
{
  int i = allocsock(sock, options), parm;
  struct threaddata *td = threaddata();

  if (i == -1) {
    putlog(LOG_MISC, "*", "Sockettable full.");
    return;
  }
  if (((sock != STDOUT) || backgrd) && !(td->socklist[i].flags & SOCK_NONSOCK)) {
    parm = 1;
    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &parm, sizeof(int));

    parm = 0;
    setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &parm, sizeof(int));
  }
  if (options & SOCK_LISTEN) {
    /* Tris says this lets us grab the same port again next time */
    parm = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &parm, sizeof(int));
  }
  /* Yay async i/o ! */
  fcntl(sock, F_SETFL, O_NONBLOCK);
}
示例#11
0
/* Dump status info out to dcc
 */
void tell_verbose_status(int idx)
{
  char s[256], s1[121], s2[81];
  char *vers_t, *uni_t;
  int i;
  time_t now2 = now - online_since, hr, min;
  float cputime;
#ifdef HAVE_UNAME
  struct utsname un;

  if (uname(&un) < 0) {
#endif
    vers_t = " ";
    uni_t  = "*unknown*";
#ifdef HAVE_UNAME
  } else {
    vers_t = un.release;
    uni_t  = un.sysname;
  }
#endif

  i = count_users(userlist);
  dprintf(idx, "I am %s, running %s: %d user%s (mem: %uk).\n",
          botnetnick, ver, i, i == 1 ? "" : "s",
          (int) (expected_memory() / 1024));

  s[0] = 0;
  if (now2 > 86400) {
    /* days */
    sprintf(s, "%d day", (int) (now2 / 86400));
    if ((int) (now2 / 86400) >= 2)
      strcat(s, "s");
    strcat(s, ", ");
    now2 -= (((int) (now2 / 86400)) * 86400);
  }
  hr = (time_t) ((int) now2 / 3600);
  now2 -= (hr * 3600);
  min = (time_t) ((int) now2 / 60);
  sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
  s1[0] = 0;
  if (backgrd)
    strcpy(s1, MISC_BACKGROUND);
  else {
    if (term_z)
      strcpy(s1, MISC_TERMMODE);
    else if (con_chan)
      strcpy(s1, MISC_STATMODE);
    else
      strcpy(s1, MISC_LOGMODE);
  }
  cputime = getcputime();
  if (cputime < 0)
    sprintf(s2, "CPU: unknown");
  else {
    hr = cputime / 60;
    cputime -= hr * 60;
    sprintf(s2, "CPU: %02d:%05.2f", (int) hr, cputime); /* Actally min/sec */
  }
  dprintf(idx, "%s %s (%s) - %s - %s: %4.1f%%\n", MISC_ONLINEFOR,
          s, s1, s2, MISC_CACHEHIT,
          100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));

  dprintf(idx, "Configured with: " EGG_AC_ARGS "\n");
  if (admin[0])
    dprintf(idx, "Admin: %s\n", admin);

  dprintf(idx, "Config file: %s\n", configfile);
  dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
  dprintf(idx, "Process ID: %d (parent %d)\n", getpid(), getppid());

  /* info library */
  dprintf(idx, "%s %s\n", MISC_TCLLIBRARY,
          ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
          tcl_resultstring() : "*unknown*");

  /* info tclversion/patchlevel */
  dprintf(idx, "%s %s (%s %s)\n", MISC_TCLVERSION,
          ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
          tcl_resultstring() : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
          tcl_resultstring() : "*unknown*", MISC_TCLHVERSION,
          TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL : "*unknown*");

  if (tcl_threaded())
    dprintf(idx, "Tcl is threaded.\n");
#ifdef TLS
  dprintf(idx, "TLS support is enabled.\n");
  dprintf(idx, "TLS library: %s\n", SSLeay_version(SSLEAY_VERSION));
#else
  dprintf(idx, "TLS support is not available.\n");
#endif
#ifdef IPV6
  dprintf(idx, "IPv6 support is enabled.\n");
#else
  dprintf(idx, "IPv6 support is not available.\n");
#endif
  dprintf(idx, "Socket table: %d/%d\n", threaddata()->MAXSOCKS, max_socks);
}
示例#12
0
/* Dump status info out to dcc
 */
void tell_verbose_status(int idx)
{
  char s[256], s1[121], s2[81];
  char *vers_t, *uni_t;
  int i;
  time_t now2 = now - online_since, hr, min;
#ifdef HAVE_GETRUSAGE
  struct rusage ru;
#else
#  ifdef HAVE_CLOCK
  clock_t cl;
#  endif
#endif
#ifdef HAVE_UNAME
  struct utsname un;

  if (!uname(&un) < 0) {
#endif
    vers_t = " ";
    uni_t  = "*unknown*";
#ifdef HAVE_UNAME
  } else {
    vers_t = un.release;
    uni_t  = un.sysname;
  }
#endif

  i = count_users(userlist);
  dprintf(idx, "I am %s, running %s: %d user%s (mem: %uk).\n",
          botnetnick, ver, i, i == 1 ? "" : "s",
          (int) (expected_memory() / 1024));
#ifdef IPV6
  dprintf(idx, "Unofficial IPv6 patch for v1.6.21 based on the v1.6.18 IPv6 patch \n");
#endif  

  s[0] = 0;
  if (now2 > 86400) {
    /* days */
    sprintf(s, "%d day", (int) (now2 / 86400));
    if ((int) (now2 / 86400) >= 2)
      strcat(s, "s");
    strcat(s, ", ");
    now2 -= (((int) (now2 / 86400)) * 86400);
  }
  hr = (time_t) ((int) now2 / 3600);
  now2 -= (hr * 3600);
  min = (time_t) ((int) now2 / 60);
  sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
  s1[0] = 0;
  if (backgrd)
    strcpy(s1, MISC_BACKGROUND);
  else {
    if (term_z)
      strcpy(s1, MISC_TERMMODE);
    else if (con_chan)
      strcpy(s1, MISC_STATMODE);
    else
      strcpy(s1, MISC_LOGMODE);
  }
#ifdef HAVE_GETRUSAGE
  getrusage(RUSAGE_SELF, &ru);
  hr = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) / 60);
  min = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) - (hr * 60));
  sprintf(s2, "CPU: %02d:%02d", (int) hr, (int) min);    /* Actally min/sec */
#else
#  ifdef HAVE_CLOCK
  cl = (clock() / CLOCKS_PER_SEC);
  hr = (int) (cl / 60);
  min = (int) (cl - (hr * 60));
  sprintf(s2, "CPU: %02d:%02d", (int) hr, (int) min);    /* Actually min/sec */
#  else
  sprintf(s2, "CPU: unknown");
#  endif
#endif
  dprintf(idx, "%s %s (%s) - %s - %s: %4.1f%%\n", MISC_ONLINEFOR,
          s, s1, s2, MISC_CACHEHIT,
          100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));

  dprintf(idx, "Configured with: " EGG_AC_ARGS "\n");
  if (admin[0])
    dprintf(idx, "Admin: %s\n", admin);

  dprintf(idx, "Config file: %s\n", configfile);
  dprintf(idx, "OS: %s %s\n", uni_t, vers_t);

  /* info library */
  dprintf(idx, "%s %s\n", MISC_TCLLIBRARY,
          ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
          tcl_resultstring() : "*unknown*");

  /* info tclversion/patchlevel */
  dprintf(idx, "%s %s (%s %s)\n", MISC_TCLVERSION,
          ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
          tcl_resultstring() : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
          tcl_resultstring() : "*unknown*", MISC_TCLHVERSION,
          TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL : "*unknown*");

  if (tcl_threaded())
    dprintf(idx, "Tcl is threaded.\n");
  dprintf(idx, "Socket table: %d/%d\n", threaddata()->MAXSOCKS, max_socks);
}
示例#13
0
文件: tls.c 项目: ArNz8o8/Fr3shness
/* Switch a socket to SSL communication
 *
 * Creates a SSL data structure for the connection;
 * Sets up callbacks and initiates a SSL handshake with the peer;
 * Reports error conditions and performs cleanup upon failure.
 *
 * flags: ssl flags, i.e connect or listen
 * verify: peer certificate verification flags
 * loglevel: is the level to output information about the connection
 * and certificates.
 * host: contains the dns name or ip address of the peer. Used for
 * verification.
 * cb: optional callback, this function will be called after the
 * handshake completes.
 *
 * Return value: 0 on success, !=0 on failure.
 */
int ssl_handshake(int sock, int flags, int verify, int loglevel, char *host,
                  IntFunc cb)
{
  int i, err, ret;
  ssl_appdata *data;
  struct threaddata *td = threaddata();

  debug0("TLS: attempting SSL negotiation...");
  if (!ssl_ctx && ssl_init()) {
    debug0("TLS: Failed. OpenSSL not initialized properly.");
    return -1;
  }
  /* find the socket in the list */
  i = findsock(sock);
  if (i == -1) {
    debug0("TLS: socket not in socklist");
    return -2;
  }
  if (td->socklist[i].ssl) {
    debug0("TLS: handshake not required - SSL session already established");
    return 0;
  }
  td->socklist[i].ssl = SSL_new(ssl_ctx);
  if (!td->socklist[i].ssl ||
      !SSL_set_fd(td->socklist[i].ssl, td->socklist[i].sock)) {
    debug1("TLS: cannot initiate SSL session - %s",
           ERR_error_string(ERR_get_error(), 0));
    return -3;
  }

  /* Prepare a ssl appdata struct for the verify callback */
  data = nmalloc(sizeof(ssl_appdata));
  egg_bzero(data, sizeof(ssl_appdata));
  data->flags = flags & (TLS_LISTEN | TLS_CONNECT);
  data->verify = flags & ~(TLS_LISTEN | TLS_CONNECT);
  data->loglevel = loglevel;
  data->cb = cb;
  strncpyz(data->host, host ? host : "", sizeof(data->host));
  SSL_set_app_data(td->socklist[i].ssl, data);
  SSL_set_info_callback(td->socklist[i].ssl, (void *) ssl_info);
  /* We set this +1 to be able to report extra long chains properly.
   * Otherwise, OpenSSL will break the verification reporting about
   * missing certificates instead. The rest of the fix is in
   * ssl_verify()
   */
  SSL_set_verify_depth(td->socklist[i].ssl, tls_maxdepth + 1);

  SSL_set_mode(td->socklist[i].ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  if (data->flags & TLS_CONNECT) {
    SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
    ret = SSL_connect(td->socklist[i].ssl);
    if (!ret)
      debug0("TLS: connect handshake failed.");
  } else {
    if (data->flags & TLS_VERIFYPEER)
      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER |
                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify);
    else
      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
    ret = SSL_accept(td->socklist[i].ssl);
    if (!ret)
      debug0("TLS: accept handshake failed");
  }

  err = SSL_get_error(td->socklist[i].ssl, ret);
  /* Normal condition for async I/O, similar to EAGAIN */
  if (ret > 0 || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
    debug0("TLS: handshake in progress");
    return 0;
  }
  if (ERR_peek_error())
    debug0("TLS: handshake failed due to the following errors: ");
  while ((err = ERR_get_error()))
    debug1("TLS: %s", ERR_error_string(err, NULL));

  /* Attempt failed, cleanup and abort */
  SSL_shutdown(td->socklist[i].ssl);
  SSL_free(td->socklist[i].ssl);
  td->socklist[i].ssl = NULL;
  nfree(data);
  return -4;
}