static int recv_challenge_ack(int fd, 
			      unsigned our_challenge,
			      char cookie[], unsigned ms)
{
    char dbuf[DEFBUF_SIZ];
    char *buf = dbuf;
    int is_static = 1;
    int buflen = DEFBUF_SIZ;
    int rlen;
    char *s;
    char tag;
    char her_digest[16], expected_digest[16];
    
    erl_errno = EIO;		/* Default */

    if ((rlen = read_2byte_package(fd, &buf, &buflen, &is_static, ms)) != 17) {
	EI_TRACE_ERR1("recv_challenge_ack",
		      "<- RECV_CHALLENGE_ACK socket read failed (%d)",rlen);
	goto error;
    }
    
    s = buf;
    if ((tag = get8(s)) != 'a') {
	EI_TRACE_ERR2("recv_challenge_ack",
		      "<- RECV_CHALLENGE_ACK incorrect tag, "
		      "expected 'a' got '%c' (%u)",tag,tag);
	goto error;
    }
    memcpy(her_digest, s, 16);
    gen_digest(our_challenge, cookie, (unsigned char *)expected_digest);
    if (memcmp(her_digest, expected_digest, 16)) {
	EI_TRACE_ERR0("recv_challenge_ack",
		      "<- RECV_CHALLENGE_ACK authorization failure");
	goto error;
    }
    if (!is_static)
	free(buf);

    if (ei_tracelevel >= 3) {
	char buffer[33];	
	EI_TRACE_CONN1("recv_challenge_ack",
		   "<- RECV_CHALLENGE_ACK (ok) digest = %s",hex(her_digest,buffer));
    }
    erl_errno = 0;
    return 0;

error:
    if (!is_static)
	free(buf);
    return -1;
}
Beispiel #2
0
static int recv_name(int fd, 
		     unsigned *version,
		     unsigned *flags, ErlConnect *namebuf, unsigned ms)
{
    char dbuf[DEFBUF_SIZ];
    char *buf = dbuf;
    int is_static = 1;
    int buflen = DEFBUF_SIZ;
    int rlen;
    char *s;
    struct sockaddr_in sin;
    socklen_t sin_len = sizeof(sin);
    char tag;
    
    erl_errno = EIO;		/* Default */

    if ((rlen = read_2byte_package(fd, &buf, &buflen, &is_static, ms)) <= 0) {
	EI_TRACE_ERR1("recv_name","<- RECV_NAME socket read failed (%d)",rlen);
	goto error;
    }
    if ((rlen - 7) > MAXNODELEN) {
	EI_TRACE_ERR1("recv_name","<- RECV_NAME nodename too long (%d)",rlen-7);
	goto error;
    }
    s = buf;
    tag = get8(s);
    if (tag != 'n') {
	EI_TRACE_ERR2("recv_name","<- RECV_NAME incorrect tag, "
		      "expected 'n' got '%c' (%u)",tag,tag);
	goto error;
    }
    *version = get16be(s);
    *flags = get32be(s);

    if (!(*flags & DFLAG_EXTENDED_REFERENCES)) {
	EI_TRACE_ERR0("recv_name","<- RECV_NAME peer cannot handle"
		      "extended references");
	goto error;
    }

    if (!(*flags & DFLAG_EXTENDED_PIDS_PORTS)
	&& !ei_internal_use_r9_pids_ports()) {
	EI_TRACE_ERR0("recv_name","<- RECV_NAME peer cannot "
		      "handle extended pids and ports");
	erl_errno = EIO;
	goto error;
    }
	  
    if (getpeername(fd, (struct sockaddr *) &sin, &sin_len) < 0) {
	EI_TRACE_ERR0("recv_name","<- RECV_NAME can't get peername");
	erl_errno = errno;
	goto error;
    }
    memcpy(namebuf->ipadr, &(sin.sin_addr.s_addr), 
	sizeof(sin.sin_addr.s_addr));
    memcpy(namebuf->nodename, s, rlen - 7);
    namebuf->nodename[rlen - 7] = '\0';
    if (!is_static)
	free(buf);
    EI_TRACE_CONN3("recv_name",
		   "<- RECV_NAME (ok) node = %s, version = %u, flags = %u",
		   namebuf->nodename,*version,*flags);
    erl_errno = 0;
    return 0;
    
error:
    if (!is_static)
	free(buf);
    return -1;
}