shithub: mez

ref: 34148b407ec9d5516c7f07958434fe409bb17fcd
dir: /mez.c/

View raw version
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <mp.h>
#include <libsec.h>

void
usage(void)
{
	fprint(2, "usage: %s [-u user] host\n", argv0);
	exits("usage");
}

void
error(char *s)
{
	fprint(2, "%s: fatal error: %s: %r\n", argv0, s);
	exits(s);
}

void*
emallocz(ulong sz, int clr)
{
	void *p;

	if((p = mallocz(sz, clr)) == nil)
		error("Out of memory");
	setmalloctag(p, getcallerpc(&sz));
	return p;
}

void
vmsg(int fd, char *fmt, va_list v)
{
	static char buf[8192];
	char *e;

	e = vseprint(buf, buf+sizeof(buf), fmt, v);
	va_end(v);
	*e++ = '\r';
	*e++ = '\n';
	write(fd, buf, e-buf);
}

void
msg(int fd, char *fmt, ...)
{
	va_list v;

	va_start(v, fmt);
	vmsg(fd, fmt, v);
}

char*
rtmsg(int fd, char *fmt, ...)
{
	static char buf[8192];
	int bytes;
	va_list v;

	va_start(v, fmt);
	vmsg(fd, fmt, v);
	bytes = read(fd, buf, sizeof(buf));
	buf[bytes] = '\0';
	return buf;
}

void
main(int argc, char **argv)
{
	TLSconn conn;
	int fd, bytes, i;
	UserPasswd *up;
	uchar buf[512];
	char *user, *host, b64[512], in[8192];

	user = getenv("user");
	ARGBEGIN{
	default:
		usage();
	case 'u':
		user = EARGF(usage());
		break;
	}ARGEND
	if (argc != 1)
		usage();
	host = argv[0];
	up = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=irc user=%s", host, user);
	fd = dial(netmkaddr(host, "tcp", "6697"), nil, nil, nil);
	if(fd == -1)
		error("Could not connect");
	fd = tlsClient(fd, &conn);
	if(fd == -1)
		error("Could not negotiate tls connection");

	msg(fd, "CAP LS 302");
	msg(fd, "NICK %s", user);
	print(rtmsg(fd, "USER %s 0 * %s", user, user));
	//:domain.dom CAP * LS :draft/chathistory batch soju.im/account-required draft/read-marker setname draft/pre-away message-tags away-notify soju.im/bouncer-networks-notify soju.im/search account-notify cap-notify server-time invite-notify draft/extended-monitor extended-join multi-prefix soju.im/read extended-monitor chghost account-tag soju.im/bouncer-networks echo-message soju.im/webpush sasl=PLAIN soju.im/no-implicit-names draft/no-implicit-names

	print(rtmsg(fd, "CAP REQ :sasl"));
	//:domain.dom CAP * ACK sasl

	print(rtmsg(fd, "AUTHENTICATE PLAIN\r\n"));
	//AUTHENTICATE +

	bytes = snprint((char*)buf, sizeof(buf), "%c%s%c%s", '\0', user, '\0', up->passwd);
	free(up);
	enc64(b64, sizeof(b64), buf, bytes);
	print(rtmsg(fd, "AUTHENTICATE %s\r\n", b64));
	//:domain.dom 903 * :SASL authentication successful

	print(rtmsg(fd, "CAP END"));
	//:tlaloc.cbza.org 001 spew :Welcome to soju, spew, etc.
	for(i = 0; i < 4; ++i){
		bytes = read(fd, in, sizeof(in));
		in[bytes] = '\0';
		print(in);
	}

	print(rtmsg(fd, "BOUNCER LISTNETWORKS"));
	//BOUNCER NETWORK 1 etc.
	for(i = 0; i < 3; ++i){
		bytes = read(fd, in, sizeof(in));
		in[bytes] = '\0';
		print(in);
	}

	// So then I need to make a fresh connection and do the same then and then do BOUNCER BIND before I do CAP END (which will end registration)
	close(fd);
	exits(0);
}