Example #1
0
int dns_forward_query_tcp(event_entry_t *general_entry) {
	struct event_tcp_entry *entry = &general_entry->tcp;

	if (!ip_tcp_open(&entry->intsock, &global_target_address)) {
		debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to open TCP socket\n");
		goto wrong;
	}
	
	// randomizing port is not really necessary, as TCP is invulnerable to cache poisoning
	// however, the source IP address is set in ip_bind_random...
	if (!ip_bind_random(entry->intsock)) {
		// if this fails, let the kernel handle it (would mean source IP address is not guaranteed...)
		debug_log(DEBUG_WARN, "dns_forward_query_tcp(): unable to bind to source IP address and/or random port\n");
	}

	if (!ip_connect(entry->intsock, &global_target_address)) {
		debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to connect to authoritative name server (%s)\n", strerror(errno));
		goto wrong;
	}

	// Now generate a new TXID to forecome any poisoning:
	entry->buffer[0] = misc_crypto_random(256);
	entry->buffer[1] = misc_crypto_random(256);
	// XXX: do this platform safe (i.e. ntoh)
	entry->dns.dsttxid = (entry->buffer[0] << 8) + entry->buffer[1];

	debug_log(DEBUG_INFO, "dns_forward_query_tcp(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n",
			entry->dns.srctxid, entry->dns.dsttxid);

	return 1;

wrong:
	return 0;
}
Example #2
0
/*******************************************************************************
 *
 * Open interface
 */
int16_t
stk500v2_open(const char *interface, int port, int flag)
{
	if (interface[0] == '/') {
		stk_fsock = serial_open(interface, serial_speed(p.baudrate));
	} else {
		if (flag == STK_CONNECT) {
			stk_fsock = ip_connect(interface, port);
		} else { /* STK _LISTEN */
			stk_fsock = ip_listen(interface, port);
		}
	}
	return stk_fsock;
}
Example #3
0
File: ip.c Project: LTD-Beget/exim
/* Create a socket and connect to host (name or number, ipv6 ok)
   at one of port-range.

Arguments:
  type          SOCK_DGRAM or SOCK_STREAM
  af            AF_INET6 or AF_INET for the socket type
  address       the remote address, in text form
  portlo,porthi the remote port range
  timeout       a timeout
  connhost	if not NULL, host_item filled in with connection details
  errstr        pointer for allocated string on error

Return:
  socket fd, or -1 on failure (having allocated an error string)
*/
int
ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi,
	int timeout, host_item * connhost, uschar ** errstr)
{
int namelen, port;
host_item shost;
host_item *h;
int af = 0, fd, fd4 = -1, fd6 = -1;

shost.next = NULL;
shost.address = NULL;
shost.port = portlo;
shost.mx = -1;

namelen = Ustrlen(hostname);

/* Anything enclosed in [] must be an IP address. */

if (hostname[0] == '[' &&
    hostname[namelen - 1] == ']')
  {
  uschar * host = string_copy(hostname);
  host[namelen - 1] = 0;
  host++;
  if (string_is_ip_address(host, NULL) == 0)
    {
    *errstr = string_sprintf("malformed IP address \"%s\"", hostname);
    return -1;
    }
  shost.name = shost.address = host;
  }

/* Otherwise check for an unadorned IP address */

else if (string_is_ip_address(hostname, NULL) != 0)
  shost.name = shost.address = string_copy(hostname);

/* Otherwise lookup IP address(es) from the name */

else
  {
  shost.name = string_copy(hostname);
  if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
      FALSE) != HOST_FOUND)
    {
    *errstr = string_sprintf("no IP address found for host %s", shost.name);
    return -1;
    }
  }

/* Try to connect to the server - test each IP till one works */

for (h = &shost; h != NULL; h = h->next)
  {
  fd = (Ustrchr(h->address, ':') != 0)
    ? (fd6 < 0) ? (fd6 = ip_socket(type, af = AF_INET6)) : fd6
    : (fd4 < 0) ? (fd4 = ip_socket(type, af = AF_INET )) : fd4;

  if (fd < 0)
    {
    *errstr = string_sprintf("failed to create socket: %s", strerror(errno));
    goto bad;
    }

  for(port = portlo; port <= porthi; port++)
    if (ip_connect(fd, af, h->address, port, timeout) == 0)
      {
      if (fd != fd6) close(fd6);
      if (fd != fd4) close(fd4);
      if (connhost) {
	h->port = port;
	*connhost = *h;
	connhost->next = NULL;
	}
      return fd;
      }
  }

*errstr = string_sprintf("failed to connect to any address for %s: %s",
  hostname, strerror(errno));

bad:
  close(fd4); close(fd6); return -1;
}
Example #4
0
int
initialize_client_stage1(ClientRealm* cr, SSL_CTX* ctx, unsigned char* buff, char wanttoexit,
    char ignorePublicKeys)
{
  int n, nlen, elen, len, tmp;
  unsigned int olen;
  X509* server_cert;
  const EVP_MD *md;
  EVP_PKEY* pkey;
  EVP_MD_CTX md_ctx;
  unsigned char *encoded = NULL;
  char b64_encoded[100];
  unsigned char *key_buf = NULL;
  assert((ClientRealm_get_tunnelType(cr) == 0) || (ClientRealm_get_tunnelType(cr) == 1));
  switch (ClientRealm_get_tunnelType(cr)) {
    case 0: {
      if (ip_connect(&tmp, ClientRealm_get_serverName(cr),
            ClientRealm_get_managePort(cr),
            ClientRealm_get_ipFamily(cr),
            ClientRealm_get_localName(cr),
            ClientRealm_get_localPort(cr))) {
#ifdef AF_INET6
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "tcp_connect_%s error for %s, %s",
            (ClientRealm_get_ipFamily(cr) & 0x02) ?
              "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
                "ipv6":"unspec", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
#else
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "tcp_connect error for %s, %s", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
#endif
        if (wanttoexit) {
          exit(1);
        }
        else {
          return 1;
        }
      } 
      SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
      break;
            }
#ifdef HAVE_LIBPTHREAD 
    case 1: {
      if (initialize_http_proxy_client(&tmp, cr, ctx)) {
#ifdef AF_INET6
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "http_proxy_connect_%s error for %s, %s (proxy: %s, %s)",
            (ClientRealm_get_ipFamily(cr) & 0x02) ?
              "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
                "ipv6":"unspec", ClientRealm_get_serverName(cr),
                ClientRealm_get_managePort(cr),
                HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
                HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
#else 
        aflog(LOG_T_INIT, LOG_I_CRIT,
            "http_proxy_connect error for %s, %s (proxy: %s, %s)", ClientRealm_get_serverName(cr),
            ClientRealm_get_managePort(cr),
            HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
            HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
#endif 
        if (wanttoexit) {
          exit(1);
        }
        else {
          return 1;
        }
      }
      SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
      break;
            }
#endif
    default: {
               aflog(LOG_T_INIT, LOG_I_CRIT,
                   "Unknown tunnel type");
               if (wanttoexit) {
                 exit(1);
               }
               else {
                 return 1;
               }
               break;
             }
  }
  
  SslFd_set_ssl(ClientRealm_get_masterSslFd(cr), SSL_new(ctx));
  if (SSL_set_fd(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)),
        SslFd_get_fd(ClientRealm_get_masterSslFd(cr))) != 1) {
    aflog(LOG_T_INIT, LOG_I_CRIT,
        "Problem with initializing ssl... exiting");
    if (wanttoexit) {
      exit(1);
    }
    else {
      close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
      return 2;
    }
  }

  alarm(60);
  
  aflog(LOG_T_INIT, LOG_I_INFO,
      "Trying SSL_connect");
  if ((n = SSL_connect(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == 1) {
    if ((server_cert = SSL_get_peer_certificate(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Server did not present a certificate... exiting");
      exit(1);
    }
    /* FIXME: change almost everything here */
    pkey = X509_get_pubkey(server_cert);
    if (pkey == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Server's public key is invalid... exiting");
      exit(1);
    }
    nlen = BN_num_bytes(pkey->pkey.rsa->n);
    elen = BN_num_bytes(pkey->pkey.rsa->e);
    len = nlen + elen;
    key_buf = malloc(len);
    if (key_buf == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Cannot allocate memory for server's public key checking... exiting");
      exit(1);
    }
    BN_bn2bin(pkey->pkey.rsa->n, key_buf);
    BN_bn2bin(pkey->pkey.rsa->e, key_buf + nlen);
    md = EVP_md5();
    EVP_DigestInit(&md_ctx, md);
    EVP_DigestUpdate(&md_ctx, key_buf, len);
    encoded = calloc(1, EVP_MAX_MD_SIZE+1);
    if (encoded == NULL) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Cannot allocate memory for server's public key checking... exiting");
      exit(1);
    }
    EVP_DigestFinal(&md_ctx, encoded, &olen);

    if (b64_ntop(encoded, olen, b64_encoded, 100) == -1) {
      aflog(LOG_T_MAIN, LOG_I_CRIT,
          "Problem with base64 encoding... exiting");
      exit(1);
    }
    
    switch (check_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded)) {
      case SSL_PUBLIC_KEY_VALID:
        /* public key is ok - do nothing */
        break;
      case SSL_PUBLIC_KEY_NOT_KNOWN:
        aflog(LOG_T_MAIN, LOG_I_WARNING,
            "WARNING: implicitly added new server's public key to the list of known hosts");
        add_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded);
        break;
      default:
        if (ignorePublicKeys) {
          aflog(LOG_T_MAIN, LOG_I_WARNING,
              "WARNING: Invalid server's public key... ignoring");
        }
        else {
          aflog(LOG_T_MAIN, LOG_I_CRIT,
              "Invalid server's public key... exiting");
          aflog(LOG_T_MAIN, LOG_I_CRIT,
              "Please delete conflicting entry in %s or use '--ignorepkeys' option",
              get_store_filename());
          exit(1);
        }
    }

    memset(key_buf, 0, len);
    free(key_buf);
    free(encoded);

    aflog(LOG_T_INIT, LOG_I_INFO,
        "SSL_connect successful");
  }
  else {
    alarm(0);
    aflog(LOG_T_INIT, LOG_I_CRIT,
        "SSL_connect has failed (%d | %d)... exiting", n,
        SSL_get_error(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)), n));
    if (wanttoexit) {
      exit(1);
    }
    else {
      close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
      return 3;
    }
  }
  alarm(0);

  buff[0] = AF_S_LOGIN;
  buff[1] = ClientRealm_get_password(cr)[0];
  buff[2] = ClientRealm_get_password(cr)[1];
  buff[3] = ClientRealm_get_password(cr)[2];
  buff[4] = ClientRealm_get_password(cr)[3];

  return 0;
}
Example #5
0
int main(int argc, char * argv[]) {
    openlog("transparent", LOG_CONS | LOG_PERROR, LOG_USER);

    const char * copyright_notice =
        "\n"
        "ReDemPtion Transparent Proxy " VERSION ".\n"
        "Copyright (C) Wallix 2010-2015.\n"
        "Christophe Grosjean, Raphael Zhou.\n"
        "\n"
        ;

    std::string input_filename;
    std::string output_filename;
    std::string target_device;
    uint32_t    target_port;
    std::string username;
    std::string password;
    std::string record_filename;
    std::string play_filename;
    std::string persistent_key_list_filename;

    persistent_key_list_filename = "./PersistentKeyList.bin";
    target_port                  = 3389;

    program_options::options_description desc({
        {'h', "help",    "produce help message"},
        {'v', "version", "show software version"},

        {'i', "input-file",    &input_filename,               "input ini file name"},
        {'o', "output-file",   &output_filename,              "output int file name"},
        {'t', "target-device", &target_device,                "target device[:port]"},
        {'u', "username",      &username,                     "username"},
        {'p', "password",      &password,                     "password"},
        {'k', "key-list-file", &persistent_key_list_filename, "persistent key list file name"},

        {'r', "record-file",   &record_filename,              "record file name"},
        {'d', "play-file",     &play_filename,                "play file name"},
    });

    auto options = program_options::parse_command_line(argc, argv, desc);

    if (options.count("help") > 0) {
        std::cout << copyright_notice;
        std::cout << "Usage: rdptproxy [options]\n\n";
        std::cout << desc << endl;
        exit(0);
    }

    if (options.count("version") > 0) {
        std::cout << copyright_notice;
        exit(0);
    }

    if (   target_device.empty()
        && play_filename.empty()) {
        std::cerr << "Missing target device or play file name: use -t target or -d filename\n\n";
        exit(-1);
    }

    if (   !target_device.empty()
        && !play_filename.empty()) {
        std::cerr << "Use -t target or -d filename\n\n";
        exit(-1);
    }

    if (   !output_filename.empty()
        && !play_filename.empty()) {
        std::cerr << "Use -o filename or -d filename\n\n";
        exit(-1);
    }

    if (   !record_filename.empty()
        && !play_filename.empty()) {
        std::cerr << "Use -r filename or -d filename\n\n";
        exit(-1);
    }

    if (   !input_filename.empty()
        && !output_filename.empty()) {
        std::cerr << "Use -i filename or -o filename\n\n";
        exit(-1);
    }

    if (!target_device.empty()) {
        size_t pos = target_device.find(':');
        if (pos != string::npos) {
            target_port = atoi(target_device.substr(pos + 1).c_str());
            target_device.resize(pos);
        }

        if (username.c_str()[0] == 0) {
            std::cerr << "Missing username : use -u username\n\n";
            exit(-1);
        }
    }

    if (password.empty()) {
        password = "";
    }


    // This server only support one incoming connection before closing listener
    class ServerOnce : public Server {
    public:
        int  sck;
        char ip_source[256];

        ServerOnce() : sck(0) {
           this->ip_source[0] = 0;
        }

        virtual Server_status start(int incoming_sck) {
            union {
                struct sockaddr s;
                struct sockaddr_storage ss;
                struct sockaddr_in s4;
                struct sockaddr_in6 s6;
            } u;
            unsigned int sin_size = sizeof(u);
            memset(&u, 0, sin_size);
            this->sck = accept(incoming_sck, &u.s, &sin_size);
            strcpy(this->ip_source, inet_ntoa(u.s4.sin_addr));
            LOG(LOG_INFO, "Incoming socket to %d (ip=%s)\n", this->sck, this->ip_source);
            return START_WANT_STOP;
        }
    } one_shot_server;
    Listen listener(one_shot_server, 0, 3389, true, 5);  // 25 seconds to connect, or timeout
    listener.run();

    Inifile             ini;
    ConfigurationLoader cfg_loader(ini, CFG_PATH "/" RDPPROXY_INI);

    int nodelay = 1;
    if (-1 == setsockopt( one_shot_server.sck, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay
                        , sizeof(nodelay))) {
        LOG(LOG_ERR, "Failed to set socket TCP_NODELAY option on client socket");
    }
    SocketTransport front_trans( "RDP Client", one_shot_server.sck, "0.0.0.0", 0
                               , ini.debug.front, 0);
    wait_obj front_event;

    LCGRandom gen(0);

    // Remove existing Persistent Key List file.
    unlink(persistent_key_list_filename.c_str());

    OutFileTransport * persistent_key_list_oft = NULL;
    int                persistent_key_list_ofd;

    persistent_key_list_ofd = open(persistent_key_list_filename.c_str(),
                                   O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
    if (persistent_key_list_ofd != -1) {
        persistent_key_list_oft = new OutFileTransport(persistent_key_list_ofd);
    }
    else {
        LOG(LOG_ERR, "Failed to open Persistent Key List file to writing: name=\"%s\"",
            persistent_key_list_filename.c_str());
    }

    const bool fastpath_support = true;
    const bool mem3blt_support  = true;
    Front front(front_trans, SHARE_PATH "/" DEFAULT_FONT_NAME, gen, ini,
        fastpath_support, mem3blt_support, input_filename.c_str(), persistent_key_list_oft);
    null_mod no_mod(front);

    while (front.up_and_running == 0) {
        front.incoming(no_mod);
    }

    LOG(LOG_INFO, "hostname=\"%s\"", front.client_info.hostname);


    try {
        if (target_device.empty()) {
            TransparentReplayMod mod(front, play_filename.c_str(),
                front.client_info.width, front.client_info.height, NULL, ini.font);

            run_mod(mod, front, front_event, nullptr, &front_trans);
        }
        else {
            OutFileTransport * record_oft = NULL;
            int                record_fd  = -1;

            if (!record_filename.empty()) {
                record_fd = open(record_filename.c_str(), O_CREAT | O_TRUNC | O_WRONLY,
                                   S_IRUSR | S_IWUSR | S_IRGRP);
                if (record_fd != -1) {
                    record_oft = new OutFileTransport(record_fd);
                }
                else {
                    LOG(LOG_ERR, "Failed to open record file to writing: name=\"%s\"",
                        record_filename.c_str());
                }
            }

            InFileTransport * persistent_key_list_ift = NULL;
            int               persistent_key_list_ifd;

            persistent_key_list_ifd = open(persistent_key_list_filename.c_str(), O_RDONLY);
            if (persistent_key_list_ifd != -1) {
                persistent_key_list_ift = new InFileTransport(persistent_key_list_ifd);
            }
            else {
                LOG(LOG_ERR, "Failed to open Persistent Key List file to reading: name=\"%s\"",
                    persistent_key_list_filename.c_str());
            }

            int client_sck = ip_connect(target_device.c_str(), target_port, 3, 1000, ini.debug.mod_rdp);
            SocketTransport mod_trans( "RDP Server", client_sck, target_device.c_str(), target_port
                                     , ini.debug.mod_rdp, &ini.context.auth_error_message);

            ClientInfo client_info = front.client_info;

            ModRDPParams mod_rdp_params( username.c_str()
                                       , password.c_str()
                                       , target_device.c_str()
                                       , "0.0.0.0"   // client ip is silenced
                                       , front.keymap.key_flags
                                       , ini.debug.mod_rdp
                                       );
            //mod_rdp_params.enable_tls                          = true;
            mod_rdp_params.enable_nla                          = ini.mod_rdp.enable_nla;
            mod_rdp_params.enable_krb                          = ini.mod_rdp.enable_kerberos;
            //mod_rdp_params.enable_fastpath                     = true;
            //mod_rdp_params.enable_mem3blt                      = true;
            mod_rdp_params.enable_bitmap_update                = ini.globals.enable_bitmap_update;
            //mod_rdp_params.enable_new_pointer                  = true;
            mod_rdp_params.enable_transparent_mode             = true;
            mod_rdp_params.output_filename                     = (output_filename.empty() ? "" : output_filename.c_str());
            mod_rdp_params.persistent_key_list_transport       = persistent_key_list_ift;
            mod_rdp_params.transparent_recorder_transport      = record_oft;
            mod_rdp_params.auth_channel                        = ini.globals.auth_channel;
            mod_rdp_params.alternate_shell                     = ini.globals.alternate_shell.get_cstr();
            mod_rdp_params.shell_working_directory             = ini.globals.shell_working_directory.get_cstr();
            mod_rdp_params.rdp_compression                     = ini.mod_rdp.rdp_compression;
            mod_rdp_params.disconnect_on_logon_user_change     = ini.mod_rdp.disconnect_on_logon_user_change;
            mod_rdp_params.open_session_timeout                = ini.mod_rdp.open_session_timeout;
            mod_rdp_params.certificate_change_action           = ini.mod_rdp.certificate_change_action;
            mod_rdp_params.extra_orders                        = ini.mod_rdp.extra_orders.c_str();
            mod_rdp_params.enable_persistent_disk_bitmap_cache = ini.mod_rdp.persistent_disk_bitmap_cache;
            mod_rdp_params.enable_cache_waiting_list           = ini.mod_rdp.cache_waiting_list;
            mod_rdp_params.password_printing_mode              = ini.debug.password;
            mod_rdp_params.cache_verbose                       = ini.debug.cache;

            mod_rdp_params.allow_channels                      = &(ini.mod_rdp.allow_channels);
            mod_rdp_params.deny_channels                       = &(ini.mod_rdp.deny_channels);

            mod_rdp mod(mod_trans, front, client_info, ini.mod_rdp.redir_info,
                        gen, mod_rdp_params);

            run_mod(mod, front, front_event, &mod_trans, &front_trans);

            if (client_sck != -1) {
                shutdown(client_sck, 2);
                close(client_sck);
            }

            if (persistent_key_list_ifd != -1) {
                delete persistent_key_list_ift;

                close(persistent_key_list_ifd);
            }

            if (record_fd != -1) {
                delete record_oft;

                close(record_fd);
            }
        }
    }   // try
    catch (Error & e) {
        LOG(LOG_ERR, "errid = %d", e.id);
    }

    front.disconnect();

    if (persistent_key_list_ofd != -1) {
        delete persistent_key_list_oft;

        close(persistent_key_list_ofd);
    }

    shutdown(one_shot_server.sck, 2);
    close(one_shot_server.sck);

    LOG(LOG_INFO, "Listener closed\n");
    LOG(LOG_INFO, "Incoming socket %d (ip=%s)\n", one_shot_server.sck, one_shot_server.ip_source);

    return 0;
}