Browse Source

* security tunes for csocket

master
Alex 'AdUser' Z 4 years ago
parent
commit
19529fe3a5
  1. 24
      src/csocket.c

24
src/csocket.c

@ -65,11 +65,11 @@ f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b
/* handle incoming data */ /* handle incoming data */
if (in) { if (in) {
f2b_log_msg(log_debug, "some incoming data on socket %d", conn->sock);
char tmp[RBUF_SIZE] = ""; char tmp[RBUF_SIZE] = "";
char *line = NULL; char *line = NULL;
ssize_t read = 0; ssize_t read = 0;
read = recv(conn->sock, tmp, RBUF_SIZE, MSG_DONTWAIT); size_t avail = conn->recv.size - conn->recv.used;
read = recv(conn->sock, tmp, avail, MSG_DONTWAIT);
if (read == 0 || (read < 0 && errno == ECONNRESET)) { if (read == 0 || (read < 0 && errno == ECONNRESET)) {
f2b_log_msg(log_debug, "received connection close on socket %d", conn->sock); f2b_log_msg(log_debug, "received connection close on socket %d", conn->sock);
return -1; return -1;
@ -80,8 +80,14 @@ f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b
} }
if (read > 0) { if (read > 0) {
tmp[read] = '\0'; tmp[read] = '\0';
f2b_buf_append(&conn->recv, tmp, read); for (const char *p = tmp; *p != '\0'; p++) {
f2b_log_msg(log_debug, "received %zd bytes from socket %d", read, conn->sock); if (isgraph(*p) || isspace(*p))
continue;
f2b_log_msg(log_error, "non-printable character in data on sock %d", conn->sock);
return -1;
}
retval = f2b_buf_append(&conn->recv, tmp, read);
f2b_log_msg(log_debug, "received %zd bytes from socket %d, append %d to buf", read, conn->sock, retval);
/* extract message(s) */ /* extract message(s) */
while ((line = f2b_buf_extract(&conn->recv, "\n")) != NULL) { while ((line = f2b_buf_extract(&conn->recv, "\n")) != NULL) {
if (strlen(line) == 0) { if (strlen(line) == 0) {
@ -106,7 +112,7 @@ f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b
/* handle outgoing data */ /* handle outgoing data */
if (conn->send.used > 0) { if (conn->send.used > 0) {
f2b_log_msg(log_debug, "sending %zu bytes to socket %d", conn->send.used, conn->sock); f2b_log_msg(log_debug, "sending %zu bytes to socket %d", conn->send.used, conn->sock);
retval = send(conn->sock, conn->send.data, conn->send.used, MSG_DONTWAIT); retval = send(conn->sock, conn->send.data, conn->send.used, MSG_DONTWAIT | MSG_NOSIGNAL);
if (retval > 0) { if (retval > 0) {
f2b_buf_splice(&conn->send, retval); f2b_buf_splice(&conn->send, retval);
f2b_log_msg(log_debug, "sent %d bytes to socket %d (%zu remains)", retval, conn->sock, conn->send.used); f2b_log_msg(log_debug, "sent %d bytes to socket %d (%zu remains)", retval, conn->sock, conn->send.used);
@ -183,6 +189,8 @@ f2b_csocket_destroy(f2b_csock_t *csock) {
void void
f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) { f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) {
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
struct ucred peer;
socklen_t peerlen = 0;
fd_set rfds, wfds; fd_set rfds, wfds;
f2b_conn_t *conn = NULL; f2b_conn_t *conn = NULL;
int retval, nfds; int retval, nfds;
@ -234,8 +242,11 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
if ((sock = accept(csock->sock, NULL, NULL)) < 0) { if ((sock = accept(csock->sock, NULL, NULL)) < 0) {
f2b_log_msg(log_error, "can't accept() new connection: %s", strerror(errno)); f2b_log_msg(log_error, "can't accept() new connection: %s", strerror(errno));
} else if (cnum < MAXCONNS) { } else if (cnum < MAXCONNS) {
peerlen = sizeof(peer);
if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peer, &peerlen) < 0)
f2b_log_msg(log_error, "can't get remote peer credentials: %s", strerror(errno));
if ((conn = f2b_conn_create(RBUF_SIZE, WBUF_SIZE)) != NULL) { if ((conn = f2b_conn_create(RBUF_SIZE, WBUF_SIZE)) != NULL) {
f2b_log_msg(log_debug, "new connection accept()ed, socket %d", sock); f2b_log_msg(log_debug, "new connection accept()ed, socket %d from uid %d", sock, peer.uid);
conn->sock = sock; conn->sock = sock;
csock->clients[cnum] = conn; csock->clients[cnum] = conn;
} else { } else {
@ -252,6 +263,7 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
continue; continue;
retval = f2b_conn_process(conn, FD_ISSET(conn->sock, &rfds), cb); retval = f2b_conn_process(conn, FD_ISSET(conn->sock, &rfds), cb);
if (retval < 0) { if (retval < 0) {
f2b_log_msg(log_debug, "closing connection on socket %d", conn->sock);
shutdown(conn->sock, SHUT_RDWR); shutdown(conn->sock, SHUT_RDWR);
f2b_conn_destroy(conn); f2b_conn_destroy(conn);
csock->clients[cnum] = NULL; csock->clients[cnum] = NULL;

Loading…
Cancel
Save