Beispiel #1
0
bool rch_push_data_block(rch_t *rch, data_block_t *data_blk)
{
    if (!data_frame_push_data_block(rch->data_fr, data_blk)) {
        LOG(DBG, "RCH: block fail");
        return false;
    }

    if (data_frame_blocks(rch->data_fr) != 1) {
        LOG(WTF, "block lenght != 1");
        return false;
    }

    uint8_t data[(92 + 7) / 8];
    const int size = data_frame_get_bytes(rch->data_fr, data);
    if (size != 64) {
        LOG(WTF, "invalid frame lenght");
        return false;
    }

    if (!check_fcs(data, size)) {
        LOG(DBG, "invalid FCS");
        return false;
    }

    rch->rch_data.naddrs = 0;
    for (int i = 0; i < ARRAY_LEN(rch->rch_data.addrs); ++i) {
        addr_parse(&rch->rch_data.addrs[rch->rch_data.naddrs], data + 2*i, 0);
        if (!addr_is_tti_no_st(&rch->rch_data.addrs[rch->rch_data.naddrs], true)) {
            ++rch->rch_data.naddrs;
        }
    }

    return true;
}
Beispiel #2
0
int net_bind(
	const char name[],
	const char addr[],
	const char port[],
	const char ifce[],
	int protocol, int af
) {
	char addrbuf[FULL_ADDSTRLEN+1];
	const int opt_on = 1;
	int sock;
	socklen_t addrlen;
	IP sockaddr;

	if( af == AF_INET ) {
		addrlen = sizeof(IP4);
	} else if( af == AF_INET6 ) {
		addrlen = sizeof(IP6);
	} else {
		log_err( "%s: Unknown address family value.", name );
		return -1;
	}

	if( addr_parse( &sockaddr, addr, port, af ) != 0 ) {
		log_err( "%s: Failed to parse IP address '%s' and port '%s'.", name, addr, port );
		return -1;
	}

	if( (sock = net_socket( name, ifce, protocol, af )) < 0 ) {
		return -1;
	}

	if( af == AF_INET6 ) {
		if( setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt_on, sizeof(opt_on) ) < 0 ) {
			close( sock );
			log_err( "%s: Failed to set socket option IPV6_V6ONLY: %s", name, strerror( errno ));
			return -1;
		}
	}

	if( bind( sock, (struct sockaddr*) &sockaddr, addrlen ) < 0 ) {
		close( sock );
		log_err( "%s: Failed to bind socket to address: '%s'", name, strerror( errno ) );
		return -1;
	}

	if( protocol == IPPROTO_TCP && listen( sock, 5 ) < 0 ) {
		close( sock );
		log_err( "%s: Failed to listen on socket: '%s'", name, strerror( errno ) );
		return -1;
	}

	log_info( ifce ? "%s: Bind to %s, interface %s" : "%s: Bind to %s",
		name, str_addr( &sockaddr, addrbuf ), ifce
	);

	return sock;
}
Beispiel #3
0
/*! \brief Check if query fits the template requirements. */
static int template_match(int state, synth_template_t *tpl, knot_pkt_t *pkt, struct query_data *qdata)
{
	/* Parse address from query name. */
	char addr_str[SOCKADDR_STRLEN] = { '\0' };
	int ret = addr_parse(qdata, tpl, addr_str);
	if (ret != KNOT_EOK) {
		return state; /* Can't identify addr in QNAME, not applicable. */
	}

	/* Match against template netblock. */
	struct sockaddr_storage query_addr = { '\0' };
	int provided_af = tpl->subnet.ss.ss_family;
	ret = sockaddr_set(&query_addr, provided_af, addr_str, 0);
	if (ret == KNOT_EOK) {
		ret = netblock_match(&tpl->subnet, &query_addr);
	}
	if (ret != 0) {
		return state; /* Out of our netblock, not applicable. */
	}

	/* Check if the request is for an available query type. */
	uint16_t qtype = knot_pkt_qtype(qdata->query);
	switch (tpl->type) {
	case SYNTH_FORWARD:
		if (!query_satisfied_by_family(qtype, provided_af)) {
			qdata->rcode = KNOT_RCODE_NOERROR;
			return NODATA;
		}
		break;
	case SYNTH_REVERSE:
		if (qtype != KNOT_RRTYPE_PTR && qtype != KNOT_RRTYPE_ANY) {
			qdata->rcode = KNOT_RCODE_NOERROR;
			return NODATA;
		}
		break;
	default:
		break;
	}

	/* Synthetise record from template. */
	knot_rrset_t *rr = synth_rr(addr_str, tpl, pkt, qdata);
	if (rr == NULL) {
		qdata->rcode = KNOT_RCODE_SERVFAIL;
		return ERROR;
	}

	/* Insert synthetic response into packet. */
	if (knot_pkt_put(pkt, 0, rr, KNOT_PF_FREE) != KNOT_EOK) {
		return ERROR;
	}

	/* Authoritative response. */
	knot_wire_set_aa(pkt->wire);

	return HIT;
}
Beispiel #4
0
/* handle 'GET /blacklist?1.2.3.4' */
void handle_blacklist( char *reply_buf, char *params ) {
	IP addr;

	if( addr_parse( &addr, params, NULL, AF_UNSPEC ) == 0 ) {
		kad_blacklist( &addr );
		sprintf( reply_buf , "done\n" );
	} else {
		sprintf( reply_buf , "failed\n" );
	}
}
Beispiel #5
0
void on_lookup_handle(const char *line, PurpleConnection *gc, PurpleBuddy *buddy)
{
	purple_debug_info("plainprpl", "on_lookup_handle: %s\n", line);

	plain_plugin_state *pstate;
	plain_buddy_state *bstate;

	pstate = purple_connection_get_protocol_data(gc);
	bstate = purple_buddy_get_protocol_data(buddy);

	addr_parse(&bstate->addr, line, PLAIN_DEFAULT_PORT_STR, pstate->sockaf);
}
Beispiel #6
0
int cmd_blacklist( REPLY *r, const char *addr_str ) {
	char addrbuf[FULL_ADDSTRLEN+1];
	IP addr;

	if( addr_parse( &addr, addr_str, NULL, gconf->af ) != 0 ) {
		r_printf( r, "Invalid address.\n" );
		return 1;
	} else {
		kad_blacklist( &addr );
		r_printf( r, "Added to blacklist: %s\n", str_addr( &addr, addrbuf ) );
		return 0;
	}
}
Beispiel #7
0
void lpd_setup( void ) {
	int sock;

	g_packet_limit = PACKET_LIMIT_MAX;

	if( addr_parse( &g_lpd_addr, gconf->lpd_addr, LPD_PORT, gconf->af ) != 0 ) {
		log_err( "BOOT: Failed to parse IP address for '%s'.", gconf->lpd_addr );
	}

	if( gconf->lpd_disable ) {
		return;
	}

	sock = create_receive_socket();
	net_add_handler( sock, &handle_mcast );
}
Beispiel #8
0
void lpd_setup( void ) {

	g_packet_limit = PACKET_LIMIT_MAX;
	if( addr_parse( &g_lpd_addr, gconf->lpd_addr, DHT_PORT_MCAST, gconf->af ) != 0 ) {
		log_err( "BOOT: Failed to parse IP address for '%s'.", gconf->lpd_addr );
	}

	if( gconf->lpd_disable ) {
		return;
	}

	/*
	* Use different sockets for sending and receiving because
	* MacOSX does not seem to allow it to be the same.
	*/
	g_sock_send = create_send_socket();
	g_sock_recv = create_receive_socket();

	net_add_handler( g_sock_recv, &bootstrap_handle_mcast );
}
Beispiel #9
0
/* 
from_strip() -- Transforms "Name <login@host>" into "login@host" or "login@host (Real name)"
*/
char *from_strip(char *str)
{
	char *p;

#if 0
	(void)fprintf(stderr, "*** from_strip(): str = [%s]\n", str);
#endif

	if(strncmp("From:", str, 5) == 0) {
		str += 5;
	}

	/* Remove the real name if necessary - just send the address */
	if((p = addr_parse(str)) == (char *)NULL) {
		die("from_strip() -- addr_parse() failed");
	}
#if 0
	(void)fprintf(stderr, "*** from_strip(): p = [%s]\n", p);
#endif

	return(strdup(p));
}
Beispiel #10
0
int ot_tunneling_udp(int lfd) {
	fd_set initfds;
	fd_set rfds;
	int fd, nfds, ret, rcvlen;
	size_t buflen;
	unsigned char rcvbuf[65535];	/// Maxinum of UDP packet size is 65535
	void* buf;
	udp_session_t* s;
	struct sockaddr_in caddr;	/// Client address
	struct sockaddr_in raddr;	/// Remote host address
	socklen_t raddr_len;
	socklen_t caddr_len;
	time_t curtime, gctime;
	struct timeval to;

	gctime = time(NULL);

	/// 1. Waiting client data or server data
	/// 2. Tunneling data
	/// 	2.1 Got cilent data
	/// 		2.1.1 Client is newly connected
	/// 			2.1.1.1 Create an UDP session for it, then
	/// 			2.1.1.2 Add relate fd to fdset, then
	/// 			2.1.1.3 Tunneling data.
	/// 		2.1.2 Client is exists in UDP session, just tunneling data
	/// 	2.2 Got server data, get the related client addr, then tunneling data

	FD_ZERO(&initfds);
	FD_SET(lfd, &initfds);
	nfds = lfd;

	while (1) {
		/// Cleaning up timed out UDP sessions
		if (time(NULL) - gctime > otcfg_udp_ttl) {
			udps_cleanup(otcfg_udp_ttl);
			gctime = time(NULL);

			///Rebuild fdset
			nfds = udps_fdset(&initfds);
			FD_SET(lfd, &initfds);
			if (lfd > nfds) {
				nfds = lfd;
			}
		}

		rfds = initfds;
		to.tv_sec = otcfg_udp_ttl + 1;
		to.tv_usec = 0;

		ret = select(nfds + 1, &rfds, NULL, NULL, &to);
		if (ret == -1) {
			OT_LOGE("select() error: %s\n", strerror(errno));
			return -1;
		}
		else if (ret == 0) {
			OT_LOGD("select() timed out\n");

			udps_cleanup(otcfg_udp_ttl);
			gctime = time(NULL);

			///Rebuild fdset
			nfds = udps_fdset(&initfds);
			FD_SET(lfd, &initfds);
			if (lfd > nfds) {
				nfds = lfd;
			}

			continue;
		}

		curtime = time(NULL);

		if (FD_ISSET(lfd, &rfds)) {
			/// 在监听端口收到数据
			memset(&caddr, 0x00, sizeof(caddr));
			caddr_len = sizeof(caddr);
			rcvlen = recvfrom(lfd, rcvbuf, sizeof(rcvbuf), 0, (struct sockaddr*)&caddr, &caddr_len);
			if (rcvlen > 0) {
				OT_LOGD("Recived %d bytes from client %s:%d\n", rcvlen, inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
			}
			else if (rcvlen == 0) {
				OT_LOGD("Client listen connection broken\n");
				return 0;
			}
			else {
				OT_LOGE("recvfrom() fail: %s\n", strerror(errno));
				continue;
			}

			s = udps_search_byladdr(caddr);
			if (s == NULL) {
				/// UDP Session is not exists
				udp_session_t stmp;

				stmp.laddr = caddr;
				stmp.laddr_len = sizeof(stmp.laddr);
				stmp.raddr = addr_parse(otcfg_target_host, otcfg_target_port);
				stmp.raddr_len = sizeof(stmp.raddr);

				/// Connect to remote
				stmp.fd = socket(AF_INET, SOCK_DGRAM, 0);
				if (stmp.fd < 0) {
					OT_LOGE("socket() fail while connecting to target host: %s\n", strerror(errno));
					continue;
				}
				ret = connect(stmp.fd, (struct sockaddr*)&stmp.raddr, stmp.raddr_len);
				if (ret < 0) {
					OT_LOGE("connect() fail while connecting to target host: %s\n", strerror(errno));
					continue;
				}
				else {
					OT_LOGI("Connect to %s:%d in UDP\n", inet_ntoa(stmp.raddr.sin_addr), ntohs(stmp.raddr.sin_port));
				}

				/// Add to UDP session
				s = udps_add(stmp);
				if (s == NULL) {
					OT_LOGE("Can't add %s:%d to UDP session\n", inet_ntoa(stmp.laddr.sin_addr), ntohs(stmp.laddr.sin_port));
					continue;
				}
				OT_LOGD("Added %s:%d to UDP session\n", inet_ntoa(stmp.laddr.sin_addr), ntohs(stmp.laddr.sin_port));

				/// Update fdset
				if (stmp.fd > nfds) {
					nfds = stmp.fd;
				}
				FD_SET(stmp.fd, &initfds);
			}

			/// UDP session exists, or has been added

			/// Encode or decode data
			if (otcfg_side == OT_SIDE_SERVER) {
				/// Decode
				obfsem_decode(rcvbuf, rcvlen, &buf, &buflen);
			}
			else {
				/// Encode
				obfsem_encode(rcvbuf, rcvlen, &buf, &buflen);
			}

			/// Forwar data
			s->atime = curtime;
			ret = sendto(s->fd, buf, buflen, 0, (struct sockaddr*)&s->raddr, s->raddr_len);
			if (ret == 0) {
				OT_LOGI("Connection to target host %s:%d lost\n", inet_ntoa(s->raddr.sin_addr), ntohs(s->raddr.sin_port));
			}
			else if (ret < 0) {
				OT_LOGD("sendto() fail: %s\n", strerror(errno));
			}
			else {
				OT_LOGD("Sent %d bytes to target host %s:%d\n", ret, inet_ntoa(s->raddr.sin_addr), ntohs(s->raddr.sin_port));
			}
		}

		/// 从远程主机收到数据
		for (fd = 0; fd <= 1024; fd++) {	/// FIXME: Should traverse UDP session rather than such bruce
			if (!FD_ISSET(fd, &rfds) || fd == lfd) {
				continue;
			}

			raddr_len = sizeof(raddr);
			rcvlen = recvfrom(fd, rcvbuf, sizeof(rcvbuf), 0, (struct sockaddr*)&raddr, &raddr_len);
			if (rcvlen > 0) {
				OT_LOGD("Recived %d bytes from remote %s:%d\n", rcvlen, inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
			}
			else if (rcvlen == 0) {
				OT_LOGD("Remote connection broken\n");
				continue;	/// Continue handle next connection
			}
			else {
				OT_LOGE("recvfrom() fail: %s\n", strerror(errno));
				continue;	/// Continue handle next connection
			}

			s = udps_search_byfd(fd);
			if (s == NULL) {
				OT_LOGD("Unknown packet from %s:%d\n", inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
				continue;
			}

			/// Encode or decode data
			if (otcfg_side == OT_SIDE_SERVER) {
				/// Encode
				obfsem_encode(rcvbuf, rcvlen, &buf, &buflen);
			}
			else {
				/// Decode
				obfsem_decode(rcvbuf, rcvlen, &buf, &buflen);
			}

			/// Forward data
			s->atime = curtime;
			ret = sendto(lfd, buf, buflen, 0, (struct sockaddr*)&s->laddr, s->laddr_len);
			if (ret == 0) {
				OT_LOGI("Connection to target host %s:%d lost\n", inet_ntoa(s->laddr.sin_addr), ntohs(s->laddr.sin_port));
			}
			else if (ret < 0) {
				OT_LOGD("sendto() fail: %s\n", strerror(errno));
			}
			else {
				OT_LOGD("Sent %d bytes to client host %s:%d\n", ret, inet_ntoa(s->laddr.sin_addr), ntohs(s->laddr.sin_port));
			}
		}	/// End of 遍历 UDP 连接列表
	} /// End of while()
}
Beispiel #11
0
int net_bind(
	const char *name,
	const char* addr,
	const char* port,
	const char* ifce,
	int protocol, int af
) {
	char addrbuf[FULL_ADDSTRLEN+1];
	int sock;
	int val;
	IP sockaddr;

	if( af != AF_INET && af != AF_INET6 ) {
		log_err( "NET: Unknown address family value." );
		return -1;
	}

	if( addr_parse( &sockaddr, addr, port, af ) != 0 ) {
		log_err( "NET: Failed to parse IP address '%s' and port '%s'.", addr, port );
		return -1;
	}

	if( protocol == IPPROTO_TCP ) {
		sock = socket( sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP );
	} else if( protocol == IPPROTO_UDP ) {
		sock = socket( sockaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP );
	} else {
		sock = -1;
	}

	if( sock < 0 ) {
		log_err( "NET: Failed to create socket: %s", strerror( errno ) );
		return -1;
	}

	val = 1;
	if ( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ) < 0 ) {
		close( sock );
		log_err( "NET: Failed to set socket option SO_REUSEADDR: %s", strerror( errno ));
		return -1;
	}

	if( ifce && setsockopt( sock, SOL_SOCKET, SO_BINDTODEVICE, ifce, strlen( ifce ) ) ) {
		close( sock );
		log_err( "NET: Unable to bind to device '%s': %s", ifce, strerror( errno ) );
		return -1;
	}

	if( af == AF_INET6 ) {
		val = 1;
		if( setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val) ) < 0 ) {
			close( sock );
			log_err( "NET: Failed to set socket option IPV6_V6ONLY: %s", strerror( errno ));
			return -1;
		}
	}

	if( bind( sock, (struct sockaddr*) &sockaddr, sizeof(IP) ) < 0 ) {
		close( sock );
		log_err( "NET: Failed to bind socket to address: '%s'", strerror( errno ) );
		return -1;
	}

	if( net_set_nonblocking( sock ) < 0 ) {
		close( sock );
		log_err( "NET: Failed to make socket nonblocking: '%s'", strerror( errno ) );
		return -1;
	}

	if( protocol == IPPROTO_TCP && listen( sock, 5 ) < 0 ) {
		close( sock );
		log_err( "NET: Failed to listen on socket: '%s'", strerror( errno ) );
		return -1;
	}

	log_info( ifce ? "%s: Bind to %s, interface %s" : "%s: Bind to %s" ,
		name, str_addr( &sockaddr, addrbuf ), ifce
	);

	return sock;
}
Beispiel #12
0
/*
rcpt_parse() -- Break To|Cc|Bcc into individual addresses
*/
void rcpt_parse(char *str)
{
	bool_t in_quotes = False, got_addr = False;
	char *p, *q, *r;

#if 0
	(void)fprintf(stderr, "*** rcpt_parse(): str = [%s]\n", str);
#endif

	if((p = strdup(str)) == (char *)NULL) {
		die("rcpt_parse(): strdup() failed");
	}
	q = p;

	/* Replace <CR>, <LF> and <TAB> */
	while(*q) {
		switch(*q) {
			case '\t':
			case '\n':
			case '\r':
					*q = ' ';
		}
		q++;
	}
	q = p;

#if 0
	(void)fprintf(stderr, "*** rcpt_parse(): q = [%s]\n", q);
#endif

	r = q;
	while(*q) {
		if(*q == '"') {
			in_quotes = (in_quotes ? False : True);
		}

		/* End of string? */
		if(*(q + 1) == (char)NULL) {
			got_addr = True;
		}

		/* End of address? */
		if((*q == ',') && (in_quotes == False)) {
			got_addr = True;

			*q = (char)NULL;
		}

		if(got_addr) {
			while(*r && isspace(*r)) r++;

			rcpt_save(addr_parse(r));
			r = (q + 1);
#if 0
			(void)fprintf(stderr, "*** rcpt_parse(): r = [%s]\n", r);
#endif
			got_addr = False;
		}
		q++;
	}
	free(p);
}
Beispiel #13
0
/*
ssmtp() -- send the message (exactly one) from stdin to the mailhub SMTP port
*/
int ssmtp(char *argv[])
{
	char b[(BUF_SZ + 2)], *buf = b+1, *p, *q;
#ifdef MD5AUTH
	char challenge[(BUF_SZ + 1)];
#endif
	struct passwd *pw;
	int i, sock;
	uid_t uid;
	bool_t minus_v_save, leadingdot, linestart = True;
	int timeout = 0;
	int bufsize = sizeof(b)-1;

	b[0] = '.';
	outbytes = 0;
	ht = &headers;

	uid = getuid();
	if((pw = getpwuid(uid)) == (struct passwd *)NULL) {
		die("Could not find password entry for UID %d", uid);
	}
	get_arpadate(arpadate);

	if(read_config() == False) {
		log_event(LOG_INFO, "%s not found", config_file);
	}

	if((p = strtok(pw->pw_gecos, ";,"))) {
		if((gecos = strdup(p)) == (char *)NULL) {
			die("ssmtp() -- strdup() failed");
		}
	}
	revaliases(pw);

	/* revaliases() may have defined this */
	if(uad == (char *)NULL) {
		uad = append_domain(pw->pw_name);
	}

	rt = &rcpt_list;

	header_parse(stdin);

#if 1
	/* With FromLineOverride=YES set, try to recover sane MAIL FROM address */
	uad = append_domain(uad);
#endif

	from = from_format(uad, override_from);

	/* Now to the delivery of the message */
	(void)signal(SIGALRM, (void(*)())handler);	/* Catch SIGALRM */
	(void)alarm((unsigned) MAXWAIT);			/* Set initial timer */
	if(setjmp(TimeoutJmpBuf) != 0) {
		/* Then the timer has gone off and we bail out */
		die("Connection lost in middle of processing");
	}

	if((sock = smtp_open(mailhost, port)) == -1) {
		die("Cannot open %s:%d", mailhost, port);
	}
	else if (use_starttls == False) /* no initial response after STARTTLS */
	{
		if(smtp_okay(sock, buf) == False)
			die("Invalid response SMTP server");
	}

	/* If user supplied username and password, then try ELHO */
	if(auth_user) {
		outbytes += smtp_write(sock, "EHLO %s", hostname);
	}
	else {
		outbytes += smtp_write(sock, "HELO %s", hostname);
	}
	(void)alarm((unsigned) MEDWAIT);

	if(smtp_okay(sock, buf) == False) {
		die("%s (%s)", buf, hostname);
	}

	/* Try to log in if username was supplied */
	if(auth_user) {
#ifdef MD5AUTH
		if(auth_pass == (char *)NULL) {
			auth_pass = strdup("");
		}

		if(auth_method && strcasecmp(auth_method, "cram-md5") == 0) {
			outbytes += smtp_write(sock, "AUTH CRAM-MD5");
			(void)alarm((unsigned) MEDWAIT);

			if(smtp_read(sock, buf) != 3) {
				die("Server rejected AUTH CRAM-MD5 (%s)", buf);
			}
			strncpy(challenge, strchr(buf,' ') + 1, sizeof(challenge));

			memset(buf, 0, bufsize);
			crammd5(challenge, auth_user, auth_pass, buf);
		}
		else {
#endif
		memset(buf, 0, bufsize);
		to64frombits(buf, auth_user, strlen(auth_user));
		if (use_oldauth) {
			outbytes += smtp_write(sock, "AUTH LOGIN %s", buf);
		}
		else {
			outbytes += smtp_write(sock, "AUTH LOGIN");
			(void)alarm((unsigned) MEDWAIT);
			if(smtp_read(sock, buf) != 3) {
				die("Server didn't like our AUTH LOGIN (%s)", buf);
			}
			/* we assume server asked us for Username */
			memset(buf, 0, bufsize);
			to64frombits(buf, auth_user, strlen(auth_user));
			outbytes += smtp_write(sock, buf);
		}

		(void)alarm((unsigned) MEDWAIT);
		if(smtp_read(sock, buf) != 3) {
			die("Server didn't accept AUTH LOGIN (%s)", buf);
		}
		memset(buf, 0, bufsize);

		to64frombits(buf, auth_pass, strlen(auth_pass));
#ifdef MD5AUTH
		}
#endif
		/* We do NOT want the password output to STDERR
		 * even base64 encoded.*/
		minus_v_save = minus_v;
		minus_v = False;
		outbytes += smtp_write(sock, "%s", buf);
		minus_v = minus_v_save;
		(void)alarm((unsigned) MEDWAIT);

		if(smtp_okay(sock, buf) == False) {
			die("Authorization failed (%s)", buf);
		}
	}

	/* Send "MAIL FROM:" line */
	outbytes += smtp_write(sock, "MAIL FROM:<%s>", uad);

	(void)alarm((unsigned) MEDWAIT);

	if(smtp_okay(sock, buf) == 0) {
		die("%s", buf);
	}

	/* Send all the To: adresses */
	/* Either we're using the -t option, or we're using the arguments */
	if(minus_t) {
		if(rcpt_list.next == (rcpt_t *)NULL) {
			die("No recipients specified although -t option used");
		}
		rt = &rcpt_list;

		while(rt->next) {
			p = rcpt_remap(rt->string);
			outbytes += smtp_write(sock, "RCPT TO:<%s>", p);

			(void)alarm((unsigned)MEDWAIT);

			if(smtp_okay(sock, buf) == 0) {
				die("RCPT TO:<%s> (%s)", p, buf);
			}

			rt = rt->next;
		}
	}
	else {
		for(i = 1; (argv[i] != NULL); i++) {
			p = strtok(argv[i], ",");
			while(p) {
				/* RFC822 Address -> "foo@bar" */
				q = rcpt_remap(addr_parse(p));
				outbytes += smtp_write(sock, "RCPT TO:<%s>", q);

				(void)alarm((unsigned) MEDWAIT);

				if(smtp_okay(sock, buf) == 0) {
					die("RCPT TO:<%s> (%s)", q, buf);
				}

				p = strtok(NULL, ",");
			}
		}
	}

	/* Send DATA */
	outbytes += smtp_write(sock, "DATA");
	(void)alarm((unsigned) MEDWAIT);

	if(smtp_read(sock, buf) != 3) {
		/* Oops, we were expecting "354 send your data" */
		die("%s", buf);
	}

	outbytes += smtp_write(sock,
		"Received: by %s (sSMTP sendmail emulation); %s", hostname, arpadate);

	if(have_from == False) {
		outbytes += smtp_write(sock, "From: %s", from);
	}

	if(have_date == False) {
		outbytes += smtp_write(sock, "Date: %s", arpadate);
	}

#ifdef HASTO_OPTION
	if(have_to == False) {
		outbytes += smtp_write(sock, "To: postmaster");
	}
#endif

	ht = &headers;
	while(ht->next) {
		outbytes += smtp_write(sock, "%s", ht->string);
		ht = ht->next;
	}

	(void)alarm((unsigned) MEDWAIT);

	/* End of headers, start body */
	outbytes += smtp_write(sock, "");

	/*prevent blocking on pipes, we really shouldnt be using
	  stdio functions like fgets in the first place */
	fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);

	while(!feof(stdin)) {
		if (!fgets(buf, bufsize, stdin)) {
			/* if nothing was received, then no transmission
			 * over smtp should be done */
			sleep(1);
			/* don't hang forever when reading from stdin */
			if (++timeout >= MEDWAIT) {
				log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter.");
				die("Timeout on stdin while reading body");
			}
			continue;
		}
		/* Trim off \n, double leading .'s */
		leadingdot = standardise(buf, &linestart);

		if (linestart || feof(stdin)) {
			linestart = True;
			outbytes += smtp_write(sock, "%s", leadingdot ? b : buf);
		} else {
			if (log_level > 0) {
				log_event(LOG_INFO, "Sent a very long line in chunks");
			}
			if (leadingdot) {
				outbytes += fd_puts(sock, b, sizeof(b));
			} else {
				outbytes += fd_puts(sock, buf, bufsize);
			}
		}
		(void)alarm((unsigned) MEDWAIT);
	}
	if(!linestart) {
		smtp_write(sock, "");
	}
	/* End of body */

	outbytes += smtp_write(sock, ".");
	(void)alarm((unsigned) MAXWAIT);

	if(smtp_okay(sock, buf) == 0) {
		die("%s", buf);
	}

	/* Close connection */
	(void)signal(SIGALRM, SIG_IGN);

	outbytes += smtp_write(sock, "QUIT");
	(void)smtp_okay(sock, buf);
	(void)close(sock);

	log_event(LOG_INFO, "Sent mail for %s (%s) uid=%d username=%s outbytes=%d", 
		from_strip(uad), buf, uid, pw->pw_name, outbytes);

	return(0);
}
Beispiel #14
0
/*
* Parse/Resolve various string representations of
* IPv4/IPv6 addresses and optional port.
* An address can also be a domain name.
* A port can also be a service  (e.g. 'www').
*
* "<address>"
* "<ipv4_address>:<port>"
* "[<address>]"
* "[<address>]:<port>"
*/
int addr_parse_full( IP *addr, const char full_addr_str[], const char default_port[], int af ) {
	char addr_buf[256];

	char *addr_beg, *addr_tmp;
	char *last_colon;
	const char *addr_str = NULL;
	const char *port_str = NULL;
	size_t len;

	len = strlen( full_addr_str );
	if( len >= (sizeof(addr_buf) - 1) ) {
		/* address too long */
		return -1;
	} else {
		addr_beg = addr_buf;
	}

	memset( addr_buf, '\0', sizeof(addr_buf) );
	memcpy( addr_buf, full_addr_str, len );

	last_colon = strrchr( addr_buf, ':' );

	if( addr_beg[0] == '[' ) {
		/* [<addr>] or [<addr>]:<port> */
		addr_tmp = strrchr( addr_beg, ']' );

		if( addr_tmp == NULL ) {
			/* broken format */
			return -1;
		}

		*addr_tmp = '\0';
		addr_str = addr_beg + 1;

		if( *(addr_tmp+1) == '\0' ) {
			port_str = default_port;
		} else if( *(addr_tmp+1) == ':' ) {
			port_str = addr_tmp + 2;
		} else {
			/* port expected */
			return -1;
		}
	} else if( last_colon && last_colon == strchr( addr_buf, ':' ) ) {
		/* <non-ipv6-addr>:<port> */
		addr_tmp = last_colon;
		if( addr_tmp ) {
			*addr_tmp = '\0';
			addr_str = addr_buf;
			port_str = addr_tmp+1;
		} else {
			addr_str = addr_buf;
			port_str = default_port;
		}
	} else {
		/* <addr> */
		addr_str = addr_buf;
		port_str = default_port;
	}

	return addr_parse( addr, addr_str, port_str, af );
}
Beispiel #15
0
int main(int argc, char *argv[])
{
	int rc;
	int argi;

	rc = inetping_init(&ev_ops);
	if (rc != EOK) {
		printf(NAME ": Failed connecting to internet ping service "
		    "(%d).\n", rc);
		return 1;
	}

	argi = 1;
	if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
		ping_repeat = true;
		++argi;
	} else {
		ping_repeat = false;
	}

	if (argc - argi != 1) {
		print_syntax();
		return 1;
	}

	/* Parse destination address */
	rc = addr_parse(argv[argi], &dest_addr);
	if (rc != EOK) {
		printf(NAME ": Invalid address format.\n");
		print_syntax();
		return 1;
	}

	/* Determine source address */
	rc = inetping_get_srcaddr(&dest_addr, &src_addr);
	if (rc != EOK) {
		printf(NAME ": Failed determining source address.\n");
		return 1;
	}

	fid_t fid;

	if (ping_repeat) {
		fid = fibril_create(transmit_fibril, NULL);
		if (fid == 0) {
			printf(NAME ": Failed creating transmit fibril.\n");
			return 1;
		}

		fibril_add_ready(fid);

		fid = fibril_create(input_fibril, NULL);
		if (fid == 0) {
			printf(NAME ": Failed creating input fibril.\n");
			return 1;
		}

		fibril_add_ready(fid);
	} else {
		ping_send(1);
	}

	fibril_mutex_lock(&done_lock);
	rc = EOK;
	while (!done && rc != ETIMEOUT) {
		rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
			ping_repeat ? 0 : PING_TIMEOUT);
	}
	fibril_mutex_unlock(&done_lock);

	if (rc == ETIMEOUT) {
		printf(NAME ": Echo request timed out.\n");
		return 1;
	}

	return 0;
}