Esempio n. 1
0
static void test_network(void)
{
	resolve_server();

	if (_state.s_nt_ip.s_addr == INADDR_ANY) {
		xprintf(XP_ALWAYS, "Won't test network - can't resolve %s\n",
			_conf.cf_test_server);
		return;
	}

	xprintf(XP_ALWAYS, "Testing network via %s\n",
		inet_ntoa(_state.s_nt_ip));

	test_port(80);
	test_port(7777);
}
Esempio n. 2
0
krb5_error_code
k5_sendto(krb5_context context, const krb5_data *message,
          const krb5_data *realm, const struct serverlist *servers,
          k5_transport_strategy strategy,
          struct sendto_callback_info* callback_info, krb5_data *reply,
          struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
          int *server_used,
          /* return 0 -> keep going, 1 -> quit */
          int (*msg_handler)(krb5_context, const krb5_data *, void *),
          void *msg_handler_data)
{
    int pass;
    time_ms delay;
    krb5_error_code retval;
    struct conn_state *conns = NULL, *state, **tailptr, *next, *winner;
    size_t s;
    struct select_state *sel_state = NULL, *seltemp;
    char *udpbuf = NULL;
    krb5_boolean done = FALSE;

    *reply = empty_data();

    /* One for use here, listing all our fds in use, and one for
     * temporary use in service_fds, for the fds of interest.  */
    sel_state = malloc(2 * sizeof(*sel_state));
    if (sel_state == NULL) {
        retval = ENOMEM;
        goto cleanup;
    }
    seltemp = &sel_state[1];
    cm_init_selstate(sel_state);

    /* First pass: resolve server hosts, communicate with resulting addresses
     * of the preferred transport, and wait 1s for an answer from each. */
    for (s = 0; s < servers->nservers && !done; s++) {
        /* Find the current tail pointer. */
        for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next);
        retval = resolve_server(context, realm, servers, s, strategy, message,
                                &udpbuf, &conns);
        if (retval)
            goto cleanup;
        for (state = *tailptr; state != NULL && !done; state = state->next) {
            /* Contact each new connection, deferring those which use the
             * non-preferred RFC 4120 transport. */
            if (state->defer)
                continue;
            if (maybe_send(context, state, message, sel_state, realm,
                           callback_info))
                continue;
            done = service_fds(context, sel_state, 1000, conns, seltemp,
                               realm, msg_handler, msg_handler_data, &winner);
        }
    }

    /* Complete the first pass by contacting servers of the non-preferred RFC
     * 4120 transport (if given), waiting 1s for an answer from each. */
    for (state = conns; state != NULL && !done; state = state->next) {
        if (!state->defer)
            continue;
        if (maybe_send(context, state, message, sel_state, realm,
                       callback_info))
            continue;
        done = service_fds(context, sel_state, 1000, conns, seltemp,
                           realm, msg_handler, msg_handler_data, &winner);
    }

    /* Wait for two seconds at the end of the first pass. */
    if (!done) {
        done = service_fds(context, sel_state, 2000, conns, seltemp,
                           realm, msg_handler, msg_handler_data, &winner);
    }

    /* Make remaining passes over all of the connections. */
    delay = 4000;
    for (pass = 1; pass < MAX_PASS && !done; pass++) {
        for (state = conns; state != NULL && !done; state = state->next) {
            if (maybe_send(context, state, message, sel_state, realm,
                           callback_info))
                continue;
            done = service_fds(context, sel_state, 1000, conns, seltemp,
                               realm, msg_handler, msg_handler_data, &winner);
            if (sel_state->nfds == 0)
                break;
        }
        /* Wait for the delay backoff at the end of this pass. */
        if (!done) {
            done = service_fds(context, sel_state, delay, conns, seltemp,
                               realm, msg_handler, msg_handler_data, &winner);
        }
        if (sel_state->nfds == 0)
            break;
        delay *= 2;
    }

    if (sel_state->nfds == 0 || !done || winner == NULL) {
        retval = KRB5_KDC_UNREACH;
        goto cleanup;
    }
    /* Success!  */
    *reply = make_data(winner->in.buf, winner->in.pos);
    retval = 0;
    winner->in.buf = NULL;
    if (server_used != NULL)
        *server_used = winner->server_index;
    if (remoteaddr != NULL && remoteaddrlen != 0 && *remoteaddrlen > 0)
        (void)getpeername(winner->fd, remoteaddr, remoteaddrlen);
    TRACE_SENDTO_KDC_RESPONSE(context, reply->length, &winner->addr);

cleanup:
    for (state = conns; state != NULL; state = next) {
        next = state->next;
        if (state->fd != INVALID_SOCKET) {
            if (socktype_for_transport(state->addr.transport) == SOCK_STREAM)
                TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr);
            closesocket(state->fd);
            free_http_tls_data(context, state);
        }
        if (state->state == READING && state->in.buf != udpbuf)
            free(state->in.buf);
        if (callback_info) {
            callback_info->pfn_cleanup(callback_info->data,
                                       &state->callback_buffer);
        }
        free(state);
    }

    if (reply->data != udpbuf)
        free(udpbuf);
    free(sel_state);
    return retval;
}
Esempio n. 3
0
/*
Forwards a message to its' destination.
@param File descriptor of the message.   <---- change to char * and get FD off that
@param Destination server as a c string.
@return
*/
int forwardMessage(char * file_to_foward, char * dest_server_string)
{
  print_to_log("Forward message routine starting.", LOG_INFO);
  //Find MX record
  struct sockaddr_storage dest_sockaddr;
  int32_t file_to_foward_descriptor;
  uint32_t mx_family = -1;
  mx_family = resolve_server(dest_server_string, &dest_sockaddr);
  uint32_t temp_socket = 0;

  if ((mx_family!=AF_INET)&&(mx_family!=AF_INET6))
  {
    #ifdef DEBUG
    printf("Invalid mx_family. Cannot forward mail. mx_family = %d\n", mx_family);
    #endif /*DEBUG*/
    print_to_log("Invalid MX family on message forward. Cannot forward message.", LOG_INFO);
    return -1;
  }

  //IPv4 case
  if(mx_family==AF_INET)
  {
    temp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if ((connect(temp_socket, (struct sockaddr_in *)&dest_sockaddr, sizeof(struct sockaddr_in)))<0)
    {
      print_to_log("Connecting on send port has failed. Cannot forward message.", LOG_ERR);
      perror("connect");
      return -1;
    }

    //Write file to connected socket
    char temp_byte;
    if ((file_to_foward_descriptor = open(file_to_foward, O_RDONLY))<0)
    {
      print_to_log("Cannot open file for forwarding.", LOG_ERR);
      return -1;
    }
    while ((temp_byte=read(file_to_foward_descriptor, &temp_byte, 1))!=-1)
    {
      write(temp_socket, &temp_byte, 1);
    }
    #ifdef DEBUG
    printf("Message forwarded via IPv4\n");
    #endif /*DEBUG*/
    print_to_log("Forward message via IPv4 complete", LOG_INFO);
  }

  if(mx_family==AF_INET6)
  {
    temp_socket = socket(AF_INET6, SOCK_STREAM, 0);
    if ((connect(temp_socket, (struct sockaddr_in6 *)&dest_sockaddr, sizeof(struct sockaddr_in6)))<0)
    {
      print_to_log("Connecting on send port has failed. Cannot forward message.", LOG_ERR);
      perror("connect");
      return -1;
    }

    //Write file to connected socket
    char temp_byte;
    while ((temp_byte=read(file_to_foward_descriptor, &temp_byte, 1))!=-1)
    {
      write(temp_socket, &temp_byte, 1);
    }
    print_to_log("Forward message via IPv6 complete", LOG_INFO);
  }
  close(temp_socket);
  return 0;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
	int ch;

#ifdef __WIN32__
	WSADATA wsadata;
	if (WSAStartup(MAKEWORD(1,1), &wsadata) == SOCKET_ERROR)
		errx(1, "WSAStartup()");
#endif

	_conf.cf_port 	     = 666;
	_conf.cf_ctl  	     = TCPCRYPT_CTLPATH;
	_conf.cf_test 	     = -1;
	_conf.cf_test_server = "check.tcpcrypt.org";

	while ((ch = getopt(argc, argv, "hp:vdu:camnPt:T:S:Dx:NC:M:Rifs:V"))
	       != -1) {
		switch (ch) {
		case 'i':
			_conf.cf_disable_timers = 1;
			break;

		case 'R':
			_conf.cf_rsa_client_hack = 1;
			break;

		case 'M':
			_conf.cf_mac = atoi(optarg);
			break;

		case 'C':
			_conf.cf_cipher = atoi(optarg);
			break;

		case 'N':
			_conf.cf_nat = 1;
			break;

		case 'D':
			_conf.cf_debug = 1;
			break;

		case 'S':
			profile_setopt(PROFILE_TIME_SOURCE, atoi(optarg));
			break;

		case 'x':
			add_param(&_conf.cf_divert_params, optarg);
			break;

		case 'T':
			add_param(&_conf.cf_test_params, optarg);
			break;

		case 't':
			_conf.cf_test = atoi(optarg);
			break;

		case 'P':
			_conf.cf_profile++;
			break;

		case 'n':
			_conf.cf_dummy = 1;
			break;

		case 'a':
			_conf.cf_accept = 1;
			break;

		case 'm':
			_conf.cf_modify = 1;
			break;

		case 'c':
			_conf.cf_nocache = 1;
			break;

		case 'u':
			_conf.cf_ctl = atoi(optarg);
			break;

		case 'd':
			_conf.cf_disable = 1;
			break;

		case 'p':
			_conf.cf_port = atoi(optarg);
			break;

		case 'v':
			_conf.cf_verbose++;
			break;

		case 'V':
			printf("tcpcrypt version %s\n", TCPCRYPT_VERSION);
			exit(0);

		case 'f':
			_conf.cf_disable_network_test = 1;
			break;

		case 's':
			_conf.cf_test_server = optarg;
			break;

		case 'h':
		default:
			usage(argv[0]);
			exit(0);
			break;
		}
	}

	resolve_server();

	if (signal(SIGINT, sig) == SIG_ERR)
		err(1, "signal()");

	if (signal(SIGTERM, sig) == SIG_ERR)
		err(1, "signal()");
#ifndef __WIN32__
	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
		err(1, "signal()");
#endif
	profile_setopt(PROFILE_DISCARD, 3);
	profile_setopt(PROFILE_ENABLE, _conf.cf_profile);

	pwn();
	cleanup();

	exit(0);
}
Esempio n. 5
0
krb5_error_code
k5_sendto(krb5_context context, const krb5_data *message,
          const struct serverlist *servers, int socktype1, int socktype2,
          struct sendto_callback_info* callback_info, krb5_data *reply,
          struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
          int *server_used,
          /* return 0 -> keep going, 1 -> quit */
          int (*msg_handler)(krb5_context, const krb5_data *, void *),
          void *msg_handler_data)
{
    int pass, delay;
    krb5_error_code retval;
    struct conn_state *conns = NULL, *state, **tailptr, *next, *winner;
    size_t s;
    struct select_state *sel_state = NULL, *seltemp;
    char *udpbuf = NULL;
    krb5_boolean done = FALSE;

    reply->data = 0;
    reply->length = 0;

    /* One for use here, listing all our fds in use, and one for
     * temporary use in service_fds, for the fds of interest.  */
    sel_state = malloc(2 * sizeof(*sel_state));
    if (sel_state == NULL) {
        retval = ENOMEM;
        goto cleanup;
    }
    seltemp = &sel_state[1];
    sel_state->max = 0;
    sel_state->nfds = 0;
    sel_state->end_time.tv_sec = sel_state->end_time.tv_usec = 0;
    FD_ZERO(&sel_state->rfds);
    FD_ZERO(&sel_state->wfds);
    FD_ZERO(&sel_state->xfds);

    /* First pass: resolve server hosts, communicate with resulting addresses
     * of the preferred socktype, and wait 1s for an answer from each. */
    for (s = 0; s < servers->nservers && !done; s++) {
        /* Find the current tail pointer. */
        for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next);
        retval = resolve_server(context, servers, s, socktype1, socktype2,
                                message, &udpbuf, &conns);
        if (retval)
            goto cleanup;
        for (state = *tailptr; state != NULL && !done; state = state->next) {
            /* Contact each new connection whose socktype matches socktype1. */
            if (state->socktype != socktype1)
                continue;
            if (maybe_send(context, state, sel_state, callback_info))
                continue;
            done = service_fds(context, sel_state, 1, conns, seltemp,
                               msg_handler, msg_handler_data, &winner);
        }
    }

    /* Complete the first pass by contacting servers of the non-preferred
     * socktype (if given), waiting 1s for an answer from each. */
    for (state = conns; state != NULL && !done; state = state->next) {
        if (state->socktype != socktype2)
            continue;
        if (maybe_send(context, state, sel_state, callback_info))
            continue;
        done = service_fds(context, sel_state, 1, state, seltemp, msg_handler,
                           msg_handler_data, &winner);
    }

    /* Wait for two seconds at the end of the first pass. */
    if (!done) {
        done = service_fds(context, sel_state, 2, conns, seltemp, msg_handler,
                           msg_handler_data, &winner);
    }

    /* Make remaining passes over all of the connections. */
    delay = 4;
    for (pass = 1; pass < MAX_PASS && !done; pass++) {
        for (state = conns; state != NULL && !done; state = state->next) {
            if (maybe_send(context, state, sel_state, callback_info))
                continue;
            done = service_fds(context, sel_state, 1, conns, seltemp,
                               msg_handler, msg_handler_data, &winner);
            if (sel_state->nfds == 0)
                break;
        }
        /* Wait for the delay backoff at the end of this pass. */
        if (!done) {
            done = service_fds(context, sel_state, delay, conns, seltemp,
                               msg_handler, msg_handler_data, &winner);
        }
        if (sel_state->nfds == 0)
            break;
        delay *= 2;
    }

    if (sel_state->nfds == 0 || !done || winner == NULL) {
        retval = KRB5_KDC_UNREACH;
        goto cleanup;
    }
    /* Success!  */
    TRACE_SENDTO_KDC_RESPONSE(context, winner);
    reply->data = winner->x.in.buf;
    reply->length = winner->x.in.pos - winner->x.in.buf;
    retval = 0;
    winner->x.in.buf = NULL;
    if (server_used != NULL)
        *server_used = winner->server_index;
    if (remoteaddr != NULL && remoteaddrlen != 0 && *remoteaddrlen > 0)
        (void)getpeername(winner->fd, remoteaddr, remoteaddrlen);

cleanup:
    for (state = conns; state != NULL; state = next) {
        next = state->next;
        if (state->fd != INVALID_SOCKET)
            closesocket(state->fd);
        if (state->state == READING && state->x.in.buf != udpbuf)
            free(state->x.in.buf);
        if (callback_info) {
            callback_info->pfn_cleanup(callback_info->context,
                                       &state->callback_buffer);
        }
        free(state);
    }

    if (reply->data != udpbuf)
        free(udpbuf);
    free(sel_state);
    return retval;
}