コード例 #1
0
ファイル: store_sock.c プロジェクト: IIJ-NetBSD/netbsd-src
KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL
krb5_storage_from_socket(krb5_socket_t sock_in)
{
    krb5_storage *sp;
    int saved_errno;
    krb5_socket_t sock;

#ifdef _WIN32
    WSAPROTOCOL_INFO info;

    if (WSADuplicateSocket(sock_in, GetCurrentProcessId(), &info) == 0)
    {

	sock = WSASocket( FROM_PROTOCOL_INFO,
			  FROM_PROTOCOL_INFO,
			  FROM_PROTOCOL_INFO,
			  &info, 0, 0);
    }
#else
    sock = dup(sock_in);
#endif

    if (sock == rk_INVALID_SOCKET)
	return NULL;

    errno = ENOMEM;
    sp = malloc(sizeof(krb5_storage));
    if (sp == NULL) {
	saved_errno = errno;
	rk_closesocket(sock);
	errno = saved_errno;
	return NULL;
    }

    errno = ENOMEM;
    sp->data = malloc(sizeof(socket_storage));
    if (sp->data == NULL) {
	saved_errno = errno;
	rk_closesocket(sock);
	free(sp);
	errno = saved_errno;
	return NULL;
    }
    sp->flags = 0;
    sp->eof_code = HEIM_ERR_EOF;
    SOCK(sp) = sock;
    sp->fetch = socket_fetch;
    sp->store = socket_store;
    sp->seek = socket_seek;
    sp->trunc = socket_trunc;
    sp->fsync = socket_sync;
    sp->free = socket_free;
    sp->max_alloc = UINT_MAX/8;
    return sp;
}
コード例 #2
0
static void
accept_it (rk_socket_t s, rk_socket_t *ret_socket)
{
    rk_socket_t as;

    as = accept(s, NULL, NULL);
    if(rk_IS_BAD_SOCKET(as))
	err (1, "accept");

    if (ret_socket) {

	*ret_socket = as;

    } else {
	int fd = socket_to_fd(as, 0);

	/* We would use _O_RDONLY for the socket_to_fd() call for
	   STDIN, but there are instances where we assume that STDIN
	   is a r/w socket. */

	dup2(fd, STDIN_FILENO);
	dup2(fd, STDOUT_FILENO);

	rk_closesocket(as);
    }
}
コード例 #3
0
ファイル: daemon_com.c プロジェクト: sanchit-matta/openafs
/**
 * forcibly disconnect a sync client handle.
 *
 * @param[in] state  pointer to sync client handle
 *
 * @retval operation status
 *    @retval 0 success
 */
int
SYNC_disconnect(SYNC_client_state * state)
{
    rk_closesocket(state->fd);
    state->fd = OSI_NULLSOCKET;
    return 0;
}
コード例 #4
0
ファイル: kadm_conn.c プロジェクト: 2asoft/freebsd
static int
spawn_child(krb5_context contextp, int *socks,
	    unsigned int num_socks, int this_sock)
{
    int e;
    size_t i;
    struct sockaddr_storage __ss;
    struct sockaddr *sa = (struct sockaddr *)&__ss;
    socklen_t sa_size = sizeof(__ss);
    krb5_socket_t s;
    pid_t pid;
    krb5_address addr;
    char buf[128];
    size_t buf_len;

    s = accept(socks[this_sock], sa, &sa_size);
    if(rk_IS_BAD_SOCKET(s)) {
	krb5_warn(contextp, rk_SOCK_ERRNO, "accept");
	return 1;
    }
    e = krb5_sockaddr2address(contextp, sa, &addr);
    if(e)
	krb5_warn(contextp, e, "krb5_sockaddr2address");
    else {
	e = krb5_print_address (&addr, buf, sizeof(buf),
				&buf_len);
	if(e)
	    krb5_warn(contextp, e, "krb5_print_address");
	else
	    krb5_warnx(contextp, "connection from %s", buf);
	krb5_free_address(contextp, &addr);
    }

    pid = fork();
    if(pid == 0) {
	for(i = 0; i < num_socks; i++)
	    rk_closesocket(socks[i]);
	dup2(s, STDIN_FILENO);
	dup2(s, STDOUT_FILENO);
	if(s != STDIN_FILENO && s != STDOUT_FILENO)
	    rk_closesocket(s);
	return 0;
    } else {
	rk_closesocket(s);
    }
    return 1;
}
コード例 #5
0
ファイル: store_sock.c プロジェクト: IIJ-NetBSD/netbsd-src
static void
socket_free(krb5_storage * sp)
{
    int save_errno = errno;
    if (rk_IS_SOCKET_ERROR(rk_closesocket(SOCK(sp))))
        errno = rk_SOCK_ERRNO;
    else
        errno = save_errno;
}
コード例 #6
0
static void
slave_dead(krb5_context context, slave *s)
{
    krb5_warnx(context, "slave %s dead", s->name);

    if (!rk_IS_BAD_SOCKET(s->fd)) {
	rk_closesocket (s->fd);
	s->fd = rk_INVALID_SOCKET;
    }
    s->flags |= SLAVE_F_DEAD;
    slave_seen(s);
}
コード例 #7
0
ファイル: gssmask.c プロジェクト: Sp1l/heimdal
static int
HandleOP(SetLoggingSocket)
{
    int32_t portnum;
    krb5_socket_t sock;
    int ret;

    ret32(c, portnum);

    logmessage(c, __FILE__, __LINE__, 0,
	       "logging port on peer is: %d", (int)portnum);

    socket_set_port((struct sockaddr *)(&c->sa), htons(portnum));

    sock = socket(((struct sockaddr *)&c->sa)->sa_family, SOCK_STREAM, 0);
    if (sock == rk_INVALID_SOCKET)
	return 0;

    ret = connect(sock, (struct sockaddr *)&c->sa, c->salen);
    if (ret < 0) {
	logmessage(c, __FILE__, __LINE__, 0, "failed connect to log port: %s",
		   strerror(errno));
	rk_closesocket(sock);
	return 0;
    }

    if (c->logging)
	krb5_storage_free(c->logging);
    c->logging = krb5_storage_from_socket(sock);
    rk_closesocket(sock);

    krb5_store_int32(c->logging, eLogSetMoniker);
    store_string(c->logging, c->moniker);

    logmessage(c, __FILE__, __LINE__, 0, "logging turned on");

    return 0;
}
コード例 #8
0
static void
remove_slave (krb5_context context, slave *s, slave **root)
{
    slave **p;

    if (!rk_IS_BAD_SOCKET(s->fd))
	rk_closesocket (s->fd);
    if (s->name)
	free (s->name);
    if (s->ac)
	krb5_auth_con_free (context, s->ac);

    for (p = root; *p; p = &(*p)->next)
	if (*p == s) {
	    *p = s->next;
	    break;
	}
    free (s);
}
コード例 #9
0
ファイル: gssmask.c プロジェクト: Sp1l/heimdal
static struct client *
create_client(krb5_socket_t sock, int port, const char *moniker)
{
    struct client *c;
    int ret;

    c = ecalloc(1, sizeof(*c));

    if (moniker) {
	c->moniker = estrdup(moniker);
    } else {
	char hostname[MAXHOSTNAMELEN];
	gethostname(hostname, sizeof(hostname));
	ret = asprintf(&c->moniker, "gssmask: %s:%d", hostname, port);
	if (ret == -1)
	    c->moniker = NULL;
    }

    if (!c->moniker)
	errx(1, "out of memory");

    {
	c->salen = sizeof(c->sa);
	getpeername(sock, (struct sockaddr *)&c->sa, &c->salen);

	getnameinfo((struct sockaddr *)&c->sa, c->salen,
		    c->servername, sizeof(c->servername),
		    NULL, 0, NI_NUMERICHOST);
    }

    c->sock = krb5_storage_from_socket(sock);
    if (c->sock == NULL)
	errx(1, "krb5_storage_from_socket");

    rk_closesocket(sock);

    return c;
}
コード例 #10
0
void
start_server(krb5_context context, const char *port_str)
{
    int e;
    struct kadm_port *p;

    krb5_socket_t *socks = NULL, *tmp;
    unsigned int num_socks = 0;
    int i;

    if (port_str == NULL)
	port_str = "+";

    parse_ports(context, port_str);

    for(p = kadm_ports; p; p = p->next) {
	struct addrinfo hints, *ai, *ap;
	char portstr[32];
	memset (&hints, 0, sizeof(hints));
	hints.ai_flags    = AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;

	e = getaddrinfo(NULL, p->port, &hints, &ai);
	if(e) {
	    snprintf(portstr, sizeof(portstr), "%u", p->def_port);
	    e = getaddrinfo(NULL, portstr, &hints, &ai);
	}

	if(e) {
	    krb5_warn(context, krb5_eai_to_heim_errno(e, errno),
		      "%s", portstr);
	    continue;
	}
	i = 0;
	for(ap = ai; ap; ap = ap->ai_next)
	    i++;
	tmp = realloc(socks, (num_socks + i) * sizeof(*socks));
	if(tmp == NULL) {
	    krb5_warnx(context, "failed to reallocate %lu bytes",
		       (unsigned long)(num_socks + i) * sizeof(*socks));
	    continue;
	}
	socks = tmp;
	for(ap = ai; ap; ap = ap->ai_next) {
	    krb5_socket_t s = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
	    if(rk_IS_BAD_SOCKET(s)) {
		krb5_warn(context, rk_SOCK_ERRNO, "socket");
		continue;
	    }

	    socket_set_reuseaddr(s, 1);
	    socket_set_ipv6only(s, 1);

	    if (rk_IS_SOCKET_ERROR(bind (s, ap->ai_addr, ap->ai_addrlen))) {
		krb5_warn(context, rk_SOCK_ERRNO, "bind");
		rk_closesocket(s);
		continue;
	    }
	    if (rk_IS_SOCKET_ERROR(listen (s, SOMAXCONN))) {
		krb5_warn(context, rk_SOCK_ERRNO, "listen");
		rk_closesocket(s);
		continue;
	    }
	    socks[num_socks++] = s;
	}
	freeaddrinfo (ai);
    }
    if(num_socks == 0)
	krb5_errx(context, 1, "no sockets to listen to - exiting");

    wait_for_connection(context, socks, num_socks);
}
コード例 #11
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_auth_context ac = NULL;
    krb5_principal c1, c2;
    krb5_authenticator authent;
    krb5_keytab keytab;
    krb5_socket_t sock = rk_INVALID_SOCKET;
    HDB *db = NULL;
    int optidx = 0;
    char *tmp_db;
    krb5_log_facility *fac;
    int nprincs;

    setprogname(argv[0]);

    ret = krb5_init_context(&context);
    if(ret)
	exit(1);

    ret = krb5_openlog(context, "hpropd", &fac);
    if(ret)
	errx(1, "krb5_openlog");
    krb5_set_warn_dest(context, fac);

    if(getarg(args, num_args, argc, argv, &optidx))
	usage(1);

    if(local_realm != NULL)
	krb5_set_default_realm(context, local_realm);

    if(help_flag)
	usage(0);
    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    if (argc != 0)
	usage(1);

    if (database == NULL)
	database = hdb_default_db(context);

    if(from_stdin) {
	sock = STDIN_FILENO;
    } else {
	struct sockaddr_storage ss;
	struct sockaddr *sa = (struct sockaddr *)&ss;
	socklen_t sin_len = sizeof(ss);
	char addr_name[256];
	krb5_ticket *ticket;
	char *server;

	sock = STDIN_FILENO;
#ifdef SUPPORT_INETD
	if (inetd_flag == -1) {
	    if (getpeername (sock, sa, &sin_len) < 0) {
		inetd_flag = 0;
	    } else {
		inetd_flag = 1;
	    }
	}
#else
	inetd_flag = 0;
#endif
	if (!inetd_flag) {
	    mini_inetd (krb5_getportbyname (context, "hprop", "tcp",
					    HPROP_PORT), &sock);
	}
	sin_len = sizeof(ss);
	if(getpeername(sock, sa, &sin_len) < 0)
	    krb5_err(context, 1, errno, "getpeername");

	if (inet_ntop(sa->sa_family,
		      socket_get_address (sa),
		      addr_name,
		      sizeof(addr_name)) == NULL)
	    strlcpy (addr_name, "unknown address",
		     sizeof(addr_name));

	krb5_log(context, fac, 0, "Connection from %s", addr_name);

	ret = krb5_kt_register(context, &hdb_kt_ops);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_kt_register");

	if (ktname != NULL) {
	    ret = krb5_kt_resolve(context, ktname, &keytab);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_kt_resolve %s", ktname);
	} else {
	    ret = krb5_kt_default (context, &keytab);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_kt_default");
	}

	ret = krb5_recvauth(context, &ac, &sock, HPROP_VERSION, NULL,
			    0, keytab, &ticket);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_recvauth");

	ret = krb5_unparse_name(context, ticket->server, &server);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_unparse_name");
	if (strncmp(server, "hprop/", 5) != 0)
	    krb5_errx(context, 1, "ticket not for hprop (%s)", server);

	free(server);
	krb5_free_ticket (context, ticket);

	ret = krb5_auth_con_getauthenticator(context, ac, &authent);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_auth_con_getauthenticator");

	ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_make_principal");
	_krb5_principalname2krb5_principal(context, &c2,
					   authent->cname, authent->crealm);
	if(!krb5_principal_compare(context, c1, c2)) {
	    char *s;
	    ret = krb5_unparse_name(context, c2, &s);
	    if (ret)
		s = unparseable_name;
	    krb5_errx(context, 1, "Unauthorized connection from %s", s);
	}
	krb5_free_principal(context, c1);
	krb5_free_principal(context, c2);

	ret = krb5_kt_close(context, keytab);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_kt_close");
    }

    if(!print_dump) {
	asprintf(&tmp_db, "%s~", database);

	ret = hdb_create(context, &db, tmp_db);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_create(%s)", tmp_db);
	ret = db->hdb_open(context, db, O_RDWR | O_CREAT | O_TRUNC, 0600);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_open(%s)", tmp_db);
    }

    nprincs = 0;
    while(1){
	krb5_data data;
	hdb_entry_ex entry;

	if(from_stdin) {
	    ret = krb5_read_message(context, &sock, &data);
	    if(ret != 0 && ret != HEIM_ERR_EOF)
		krb5_err(context, 1, ret, "krb5_read_message");
	} else {
	    ret = krb5_read_priv_message(context, ac, &sock, &data);
	    if(ret)
		krb5_err(context, 1, ret, "krb5_read_priv_message");
	}

	if(ret == HEIM_ERR_EOF || data.length == 0) {
	    if(!from_stdin) {
		data.data = NULL;
		data.length = 0;
		krb5_write_priv_message(context, ac, &sock, &data);
	    }
	    if(!print_dump) {
		ret = db->hdb_close(context, db);
		if(ret)
		    krb5_err(context, 1, ret, "db_close");
		ret = db->hdb_rename(context, db, database);
		if(ret)
		    krb5_err(context, 1, ret, "db_rename");
	    }
	    break;
	}
	memset(&entry, 0, sizeof(entry));
	ret = hdb_value2entry(context, &data, &entry.entry);
	krb5_data_free(&data);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_value2entry");
	if(print_dump)
	    hdb_print_entry(context, db, &entry, stdout);
	else {
	    ret = db->hdb_store(context, db, 0, &entry);
	    if(ret == HDB_ERR_EXISTS) {
		char *s;
		ret = krb5_unparse_name(context, entry.entry.principal, &s);
		if (ret)
		    s = strdup(unparseable_name);
		krb5_warnx(context, "Entry exists: %s", s);
		free(s);
	    } else if(ret)
		krb5_err(context, 1, ret, "db_store");
	    else
		nprincs++;
	}
	hdb_free_entry(context, &entry);
    }
    if (!print_dump)
	krb5_log(context, fac, 0, "Received %d principals", nprincs);

    if (inetd_flag == 0)
	rk_closesocket(sock);

    exit(0);
}
コード例 #12
0
ファイル: init_c.c プロジェクト: tombibsd/netbsd-src
static kadm5_ret_t
kadm_connect(kadm5_client_context *ctx)
{
    kadm5_ret_t ret;
    krb5_principal server;
    krb5_ccache cc;
    rk_socket_t s = rk_INVALID_SOCKET;
    struct addrinfo *ai, *a;
    struct addrinfo hints;
    int error;
    char portstr[NI_MAXSERV];
    char *hostname, *slash;
    char *service_name;
    krb5_context context = ctx->context;

    memset (&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf (portstr, sizeof(portstr), "%u", ntohs(ctx->kadmind_port));

    hostname = ctx->admin_server;
    slash = strchr (hostname, '/');
    if (slash != NULL)
	hostname = slash + 1;

    error = getaddrinfo (hostname, portstr, &hints, &ai);
    if (error) {
	krb5_clear_error_message(context);
	return KADM5_BAD_SERVER_NAME;
    }

    for (a = ai; a != NULL; a = a->ai_next) {
	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
	if (s < 0)
	    continue;
	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
	    krb5_clear_error_message(context);
	    krb5_warn (context, errno, "connect(%s)", hostname);
	    rk_closesocket (s);
	    continue;
	}
	break;
    }
    if (a == NULL) {
	freeaddrinfo (ai);
	krb5_clear_error_message(context);
	krb5_warnx (context, "failed to contact %s", hostname);
	return KADM5_FAILURE;
    }
    ret = _kadm5_c_get_cred_cache(context,
				  ctx->client_name,
				  ctx->service_name,
				  NULL, ctx->prompter, ctx->keytab,
				  ctx->ccache, &cc);

    if(ret) {
	freeaddrinfo (ai);
	rk_closesocket(s);
	return ret;
    }

    if (ctx->realm)
	asprintf(&service_name, "%s@%s", KADM5_ADMIN_SERVICE, ctx->realm);
    else
	asprintf(&service_name, "%s", KADM5_ADMIN_SERVICE);

    if (service_name == NULL) {
	freeaddrinfo (ai);
	rk_closesocket(s);
	krb5_clear_error_message(context);
	return ENOMEM;
    }

    ret = krb5_parse_name(context, service_name, &server);
    free(service_name);
    if(ret) {
	freeaddrinfo (ai);
	if(ctx->ccache == NULL)
	    krb5_cc_close(context, cc);
	rk_closesocket(s);
	return ret;
    }
    ctx->ac = NULL;

    ret = krb5_sendauth(context, &ctx->ac, &s,
			KADMIN_APPL_VERSION, NULL,
			server, AP_OPTS_MUTUAL_REQUIRED,
			NULL, NULL, cc, NULL, NULL, NULL);
    if(ret == 0) {
	krb5_data params;
	kadm5_config_params p;
	memset(&p, 0, sizeof(p));
	if(ctx->realm) {
	    p.mask |= KADM5_CONFIG_REALM;
	    p.realm = ctx->realm;
	}
	ret = _kadm5_marshal_params(context, &p, &params);

	ret = krb5_write_priv_message(context, ctx->ac, &s, &params);
	krb5_data_free(&params);
	if(ret) {
	    freeaddrinfo (ai);
	    rk_closesocket(s);
	    if(ctx->ccache == NULL)
		krb5_cc_close(context, cc);
	    return ret;
	}
    } else if(ret == KRB5_SENDAUTH_BADAPPLVERS) {
	rk_closesocket(s);

	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
	if (s < 0) {
	    freeaddrinfo (ai);
	    krb5_clear_error_message(context);
	    return errno;
	}
	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
	    rk_closesocket (s);
	    freeaddrinfo (ai);
	    krb5_clear_error_message(context);
	    return errno;
	}
	ret = krb5_sendauth(context, &ctx->ac, &s,
			    KADMIN_OLD_APPL_VERSION, NULL,
			    server, AP_OPTS_MUTUAL_REQUIRED,
			    NULL, NULL, cc, NULL, NULL, NULL);
    }
    freeaddrinfo (ai);
    if(ret) {
	rk_closesocket(s);
	return ret;
    }

    krb5_free_principal(context, server);
    if(ctx->ccache == NULL)
	krb5_cc_close(context, cc);
    ctx->sock = s;

    return 0;
}
コード例 #13
0
ファイル: syslogc.c プロジェクト: Henauxg/minix
/******************************************************************************
 * openlog
 *
 * Open connection to system logger.
 */
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
openlog( char* ident, int option, int facility )
{
    BOOL failed = FALSE;
    SOCKADDR_IN sa_local;
    DWORD n;
    int size;

    if ( !initialized )
        return;

    EnterCriticalSection(&cs_syslog);

    if( syslog_opened )
        goto done;

    failed = TRUE;

    syslog_facility = facility? facility : LOG_USER;

    if( option & LOG_PID )
        sprintf_s( syslog_procid_str, sizeof(syslog_procid_str), "[%lu]", GetCurrentProcessId() );
    else
        syslog_procid_str[0] = '\0';

    /* FIXME: handle other options */

    n = sizeof(local_hostname);
    if( !GetComputerName( local_hostname, &n ) )
        goto done;

    syslog_socket = INVALID_SOCKET;

    init_logger_addr();

    for( n = 0;; n++ )
    {
        syslog_socket = socket( AF_INET, SOCK_DGRAM, 0 );
        if( INVALID_SOCKET == syslog_socket )
            goto done;

        memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
        sa_local.sin_family = AF_INET;
        if( bind( syslog_socket, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
            break;
        rk_closesocket( syslog_socket );
        syslog_socket = INVALID_SOCKET;
        if( n == 100 )
            goto done;
        Sleep(0);
    }

    /* get size of datagramm */
    size = sizeof(datagramm_size);
    if( getsockopt( syslog_socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &size ) )
        goto done;
    if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 )
        goto done;
    if( datagramm_size > SYSLOG_DGRAM_SIZE )
        datagramm_size = SYSLOG_DGRAM_SIZE;

    if (ident)
        strcpy_s(syslog_ident, sizeof(syslog_ident), ident);

    syslog_facility = (facility ? facility : LOG_USER);
    failed = FALSE;

 done:
    if( failed ) {
        if( syslog_socket != INVALID_SOCKET )
            rk_closesocket( syslog_socket );
    }
    syslog_opened = !failed;

    LeaveCriticalSection(&cs_syslog);
}
コード例 #14
0
ファイル: send_to_kdc.c プロジェクト: Henauxg/minix
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sendto (krb5_context context,
	     const krb5_data *send_data,
	     krb5_krbhst_handle handle,
	     krb5_data *receive)
{
     krb5_error_code ret;
     krb5_socket_t fd;
     size_t i;

     krb5_data_zero(receive);

     for (i = 0; i < context->max_retries; ++i) {
	 krb5_krbhst_info *hi;

	 while (krb5_krbhst_next(context, handle, &hi) == 0) {
	     struct addrinfo *ai, *a;

	     _krb5_debug(context, 2,
			 "trying to communicate with host %s in realm %s",
			 hi->hostname, _krb5_krbhst_get_realm(handle));

	     if (context->send_to_kdc) {
		 struct send_to_kdc *s = context->send_to_kdc;

		 ret = (*s->func)(context, s->data, hi,
				  context->kdc_timeout, send_data, receive);
		 if (ret == 0 && receive->length != 0)
		     goto out;
		 continue;
	     }

	     ret = send_via_plugin(context, hi, context->kdc_timeout,
				   send_data, receive);
	     if (ret == 0 && receive->length != 0)
		 goto out;
	     else if (ret != KRB5_PLUGIN_NO_HANDLE)
		 continue;

	     if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) {
		 if (send_via_proxy (context, hi, send_data, receive) == 0) {
		     ret = 0;
		     goto out;
		 }
		 continue;
	     }

	     ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
	     if (ret)
		 continue;

	     for (a = ai; a != NULL; a = a->ai_next) {
		 fd = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol);
		 if (rk_IS_BAD_SOCKET(fd))
		     continue;
		 rk_cloexec(fd);
		 if (timed_connect (fd, a, context->kdc_timeout) < 0) {
		     rk_closesocket (fd);
		     continue;
		 }
		 switch (hi->proto) {
		 case KRB5_KRBHST_HTTP :
		     ret = send_and_recv_http(fd, context->kdc_timeout,
					      "", send_data, receive);
		     break;
		 case KRB5_KRBHST_TCP :
		     ret = send_and_recv_tcp (fd, context->kdc_timeout,
					      send_data, receive);
		     break;
		 case KRB5_KRBHST_UDP :
		     ret = send_and_recv_udp (fd, context->kdc_timeout,
					      send_data, receive);
		     break;
		 }
		 rk_closesocket (fd);
		 if(ret == 0 && receive->length != 0)
		     goto out;
	     }
	 }
	 krb5_krbhst_reset(context, handle);
     }
     krb5_clear_error_message (context);
     ret = KRB5_KDC_UNREACH;
out:
     _krb5_debug(context, 2,
		 "result of trying to talk to realm %s = %d",
		 _krb5_krbhst_get_realm(handle), ret);
     return ret;
}
コード例 #15
0
ファイル: send_to_kdc.c プロジェクト: Henauxg/minix
static int
send_via_proxy (krb5_context context,
		const krb5_krbhst_info *hi,
		const krb5_data *send_data,
		krb5_data *receive)
{
    char *proxy2 = strdup(context->http_proxy);
    char *proxy  = proxy2;
    char *prefix = NULL;
    char *colon;
    struct addrinfo hints;
    struct addrinfo *ai, *a;
    int ret;
    krb5_socket_t s = rk_INVALID_SOCKET;
    char portstr[NI_MAXSERV];

    if (proxy == NULL)
	return ENOMEM;
    if (strncmp (proxy, "http://", 7) == 0)
	proxy += 7;

    colon = strchr(proxy, ':');
    if(colon != NULL)
	*colon++ = '\0';
    memset (&hints, 0, sizeof(hints));
    hints.ai_family   = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    snprintf (portstr, sizeof(portstr), "%d",
	      ntohs(init_port (colon, htons(80))));
    ret = getaddrinfo (proxy, portstr, &hints, &ai);
    free (proxy2);
    if (ret)
	return krb5_eai_to_heim_errno(ret, errno);

    for (a = ai; a != NULL; a = a->ai_next) {
	s = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol);
	if (s < 0)
	    continue;
	rk_cloexec(s);
	if (timed_connect (s, a, context->kdc_timeout) < 0) {
	    rk_closesocket (s);
	    continue;
	}
	break;
    }
    if (a == NULL) {
	freeaddrinfo (ai);
	return 1;
    }
    freeaddrinfo (ai);

    ret = asprintf(&prefix, "http://%s/", hi->hostname);
    if(ret < 0 || prefix == NULL) {
	close(s);
	return 1;
    }
    ret = send_and_recv_http(s, context->kdc_timeout,
			     prefix, send_data, receive);
    rk_closesocket (s);
    free(prefix);
    if(ret == 0 && receive->length != 0)
	return 0;
    return 1;
}