Allow plaintext connections with -P
parent
714b4bc76a
commit
551f22a901
7
README.7
7
README.7
|
@ -56,6 +56,9 @@ the
|
||||||
option enables tight sandboxing.
|
option enables tight sandboxing.
|
||||||
Sandboxing is always used on
|
Sandboxing is always used on
|
||||||
.Ox .
|
.Ox .
|
||||||
|
.It
|
||||||
|
Plaintext support:
|
||||||
|
It's usually less secure than TLS, but who cares.
|
||||||
.El
|
.El
|
||||||
.
|
.
|
||||||
.Ss Non-features
|
.Ss Non-features
|
||||||
|
@ -95,10 +98,6 @@ Protocol coverage:
|
||||||
IRCv3 extensions are implemented only
|
IRCv3 extensions are implemented only
|
||||||
where they contribute to
|
where they contribute to
|
||||||
the intended user experience.
|
the intended user experience.
|
||||||
.It
|
|
||||||
Cleartext IRC:
|
|
||||||
TLS is now ubiquitous
|
|
||||||
and certificates are easy to obtain.
|
|
||||||
.El
|
.El
|
||||||
.
|
.
|
||||||
.Sh INSTALLING
|
.Sh INSTALLING
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
.
|
.
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl KRelqv
|
.Op Fl KPRelqv
|
||||||
.Op Fl C Ar copy
|
.Op Fl C Ar copy
|
||||||
.Op Fl H Ar hash
|
.Op Fl H Ar hash
|
||||||
.Op Fl I Ar highlight
|
.Op Fl I Ar highlight
|
||||||
|
@ -188,6 +188,9 @@ The default is the first available of
|
||||||
.Xr open 1 ,
|
.Xr open 1 ,
|
||||||
.Xr xdg-open 1 .
|
.Xr xdg-open 1 .
|
||||||
.
|
.
|
||||||
|
.It Fl P | Cm plaintext
|
||||||
|
Don't use TLS for the server connection.
|
||||||
|
.
|
||||||
.It Fl R | Cm restrict
|
.It Fl R | Cm restrict
|
||||||
Disable the
|
Disable the
|
||||||
.Ic /copy ,
|
.Ic /copy ,
|
||||||
|
|
7
chat.c
7
chat.c
|
@ -226,6 +226,7 @@ int main(int argc, char *argv[]) {
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
bool insecure = false;
|
bool insecure = false;
|
||||||
|
bool useTLS = true;
|
||||||
bool printCert = false;
|
bool printCert = false;
|
||||||
const char *bind = NULL;
|
const char *bind = NULL;
|
||||||
const char *host = NULL;
|
const char *host = NULL;
|
||||||
|
@ -249,6 +250,7 @@ int main(int argc, char *argv[]) {
|
||||||
{ .val = 'K', .name = "kiosk", no_argument },
|
{ .val = 'K', .name = "kiosk", no_argument },
|
||||||
{ .val = 'N', .name = "notify", required_argument },
|
{ .val = 'N', .name = "notify", required_argument },
|
||||||
{ .val = 'O', .name = "open", required_argument },
|
{ .val = 'O', .name = "open", required_argument },
|
||||||
|
{ .val = 'P', .name = "plaintext", no_argument },
|
||||||
{ .val = 'R', .name = "restrict", no_argument },
|
{ .val = 'R', .name = "restrict", no_argument },
|
||||||
{ .val = 'S', .name = "bind", required_argument },
|
{ .val = 'S', .name = "bind", required_argument },
|
||||||
{ .val = 'T', .name = "timestamp", optional_argument },
|
{ .val = 'T', .name = "timestamp", optional_argument },
|
||||||
|
@ -290,6 +292,7 @@ int main(int argc, char *argv[]) {
|
||||||
break; case 'K': self.kiosk = true;
|
break; case 'K': self.kiosk = true;
|
||||||
break; case 'N': utilPush(&uiNotifyUtil, optarg);
|
break; case 'N': utilPush(&uiNotifyUtil, optarg);
|
||||||
break; case 'O': utilPush(&urlOpenUtil, optarg);
|
break; case 'O': utilPush(&urlOpenUtil, optarg);
|
||||||
|
break; case 'P': useTLS = false;
|
||||||
break; case 'R': self.restricted = true;
|
break; case 'R': self.restricted = true;
|
||||||
break; case 'S': bind = optarg;
|
break; case 'S': bind = optarg;
|
||||||
break; case 'T': {
|
break; case 'T': {
|
||||||
|
@ -326,7 +329,7 @@ int main(int argc, char *argv[]) {
|
||||||
int error = pledge("stdio inet dns", NULL);
|
int error = pledge("stdio inet dns", NULL);
|
||||||
if (error) err(EX_OSERR, "pledge");
|
if (error) err(EX_OSERR, "pledge");
|
||||||
#endif
|
#endif
|
||||||
ircConfig(true, NULL, NULL, NULL);
|
ircConfig(useTLS, true, NULL, NULL, NULL);
|
||||||
ircConnect(bind, host, port);
|
ircConnect(bind, host, port);
|
||||||
ircPrintCert();
|
ircPrintCert();
|
||||||
ircClose();
|
ircClose();
|
||||||
|
@ -373,7 +376,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
inputCompleteAdd();
|
inputCompleteAdd();
|
||||||
|
|
||||||
ircConfig(insecure, trust, cert, priv);
|
ircConfig(useTLS, insecure, trust, cert, priv);
|
||||||
|
|
||||||
uiInit();
|
uiInit();
|
||||||
sig_t cursesWinch = signal(SIGWINCH, signalHandler);
|
sig_t cursesWinch = signal(SIGWINCH, signalHandler);
|
||||||
|
|
2
chat.h
2
chat.h
|
@ -235,7 +235,7 @@ struct Message {
|
||||||
};
|
};
|
||||||
|
|
||||||
void ircConfig(
|
void ircConfig(
|
||||||
bool insecure, const char *trust, const char *cert, const char *priv
|
bool useTLS, bool insecure, const char *trust, const char *cert, const char *priv
|
||||||
);
|
);
|
||||||
int ircConnect(const char *bind, const char *host, const char *port);
|
int ircConnect(const char *bind, const char *host, const char *port);
|
||||||
void ircHandshake(void);
|
void ircHandshake(void);
|
||||||
|
|
38
irc.c
38
irc.c
|
@ -46,13 +46,16 @@
|
||||||
|
|
||||||
static struct tls *client;
|
static struct tls *client;
|
||||||
static struct tls_config *config;
|
static struct tls_config *config;
|
||||||
|
static int sock = -1;
|
||||||
|
|
||||||
void ircConfig(
|
void ircConfig(
|
||||||
bool insecure, const char *trust, const char *cert, const char *priv
|
bool useTLS, bool insecure, const char *trust, const char *cert, const char *priv
|
||||||
) {
|
) {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
|
if (!useTLS) return;
|
||||||
|
|
||||||
config = tls_config_new();
|
config = tls_config_new();
|
||||||
if (!config) errx(EX_SOFTWARE, "tls_config_new");
|
if (!config) errx(EX_SOFTWARE, "tls_config_new");
|
||||||
|
|
||||||
|
@ -107,10 +110,7 @@ void ircConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
int ircConnect(const char *bindHost, const char *host, const char *port) {
|
int ircConnect(const char *bindHost, const char *host, const char *port) {
|
||||||
assert(client);
|
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
int sock = -1;
|
|
||||||
struct addrinfo *head;
|
struct addrinfo *head;
|
||||||
struct addrinfo hints = {
|
struct addrinfo hints = {
|
||||||
.ai_family = AF_UNSPEC,
|
.ai_family = AF_UNSPEC,
|
||||||
|
@ -159,14 +159,18 @@ int ircConnect(const char *bindHost, const char *host, const char *port) {
|
||||||
freeaddrinfo(head);
|
freeaddrinfo(head);
|
||||||
|
|
||||||
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
||||||
|
if (client) {
|
||||||
error = tls_connect_socket(client, sock, host);
|
error = tls_connect_socket(client, sock, host);
|
||||||
if (error) errx(EX_PROTOCOL, "tls_connect: %s", tls_error(client));
|
if (error) errx(EX_PROTOCOL, "tls_connect: %s", tls_error(client));
|
||||||
|
}
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ircHandshake(void) {
|
void ircHandshake(void) {
|
||||||
int error;
|
int error;
|
||||||
|
if (!config) return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
error = tls_handshake(client);
|
error = tls_handshake(client);
|
||||||
} while (error == TLS_WANT_POLLIN || error == TLS_WANT_POLLOUT);
|
} while (error == TLS_WANT_POLLIN || error == TLS_WANT_POLLOUT);
|
||||||
|
@ -177,6 +181,8 @@ void ircHandshake(void) {
|
||||||
|
|
||||||
void ircPrintCert(void) {
|
void ircPrintCert(void) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
if (!config) return;
|
||||||
|
|
||||||
ircHandshake();
|
ircHandshake();
|
||||||
const byte *pem = tls_peer_cert_chain_pem(client, &len);
|
const byte *pem = tls_peer_cert_chain_pem(client, &len);
|
||||||
printf("subject= %s\n", tls_peer_cert_subject(client));
|
printf("subject= %s\n", tls_peer_cert_subject(client));
|
||||||
|
@ -198,7 +204,7 @@ static void debug(const char *pre, const char *line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ircSend(const char *ptr, size_t len) {
|
void ircSend(const char *ptr, size_t len) {
|
||||||
assert(client);
|
if (client) {
|
||||||
while (len) {
|
while (len) {
|
||||||
ssize_t ret = tls_write(client, ptr, len);
|
ssize_t ret = tls_write(client, ptr, len);
|
||||||
if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) continue;
|
if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) continue;
|
||||||
|
@ -206,6 +212,15 @@ void ircSend(const char *ptr, size_t len) {
|
||||||
ptr += ret;
|
ptr += ret;
|
||||||
len -= ret;
|
len -= ret;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert(sock != -1);
|
||||||
|
while (len) {
|
||||||
|
ssize_t ret = write(sock, ptr, len);
|
||||||
|
if (ret < 0) errx(EX_IOERR, "write: %s", "TODO how the fuck does errno work again");
|
||||||
|
ptr += ret;
|
||||||
|
len -= ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ircFormat(const char *format, ...) {
|
void ircFormat(const char *format, ...) {
|
||||||
|
@ -284,12 +299,19 @@ void ircRecv(void) {
|
||||||
static char buf[MessageCap];
|
static char buf[MessageCap];
|
||||||
static size_t len = 0;
|
static size_t len = 0;
|
||||||
|
|
||||||
assert(client);
|
if (client) {
|
||||||
ssize_t ret = tls_read(client, &buf[len], sizeof(buf) - len);
|
ssize_t ret = tls_read(client, &buf[len], sizeof(buf) - len);
|
||||||
if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) return;
|
if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) return;
|
||||||
if (ret < 0) errx(EX_IOERR, "tls_read: %s", tls_error(client));
|
if (ret < 0) errx(EX_IOERR, "tls_read: %s", tls_error(client));
|
||||||
if (!ret) errx(EX_PROTOCOL, "server closed connection");
|
if (!ret) errx(EX_PROTOCOL, "server closed connection");
|
||||||
len += ret;
|
len += ret;
|
||||||
|
} else {
|
||||||
|
assert(sock != 1);
|
||||||
|
ssize_t ret = read(sock, &buf[len], sizeof(buf) - len);
|
||||||
|
if (ret < 0) errx(EX_IOERR, "read: %s", "TODO here too");
|
||||||
|
if (!ret) errx(EX_PROTOCOL, "server closed connection");
|
||||||
|
len += ret;
|
||||||
|
}
|
||||||
|
|
||||||
char *crlf;
|
char *crlf;
|
||||||
char *line = buf;
|
char *line = buf;
|
||||||
|
@ -308,6 +330,10 @@ void ircRecv(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ircClose(void) {
|
void ircClose(void) {
|
||||||
|
if (client) {
|
||||||
tls_close(client);
|
tls_close(client);
|
||||||
tls_free(client);
|
tls_free(client);
|
||||||
|
} else {
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue