diff --git a/src/GNUmakefile.common b/src/GNUmakefile.common index 5aeae08..a040b8f 100644 --- a/src/GNUmakefile.common +++ b/src/GNUmakefile.common @@ -50,7 +50,8 @@ HDRS:= bbs.h OBJS:= inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o \ doors.o bbs_list.o chat_system.o email.o files.o settings.o \ lua_glue.o strings.o bluewave.o hashmap/hashmap.o menus.o \ - nodelist.o blog.o util.o stralloc/stralloc.o + nodelist.o blog.o util.o stralloc/stralloc.o strlcpy/strlcpy.o \ + strlcpy/strlcat.o WWWOBJS:= ../deps/aha/aha.o ../deps/hashids/hashids.o www.o www_email.o \ www_msgs.o www_last10.o www_blog.o www_files.o ${OBJS} diff --git a/src/bbs.c b/src/bbs.c index 03fff29..14d56bf 100644 --- a/src/bbs.c +++ b/src/bbs.c @@ -536,7 +536,7 @@ void s_readstring_inject(char *buffer, int max, char *inject) { return; } - strcpy(buffer, inject); + strlcpy(buffer, inject, max); s_printf("%s", inject); @@ -686,8 +686,8 @@ void record_last10_callers(struct user_record *user) { if (strcasecmp(conf.sysop_name, user->loginname) != 0) { memset(&new_entry, 0, sizeof(struct last10_callers)); - strcpy(new_entry.name, user->loginname); - strcpy(new_entry.location, user->location); + strlcpy(new_entry.name, user->loginname, sizeof(new_entry.name)); + strlcpy(new_entry.location, user->location, sizeof(new_entry.location)); new_entry.time = time(NULL); new_entry.calls = user->timeson; if (i == 10) { @@ -777,7 +777,7 @@ void automessage_write() { timen = time(NULL); localtime_r(&timen, &timenow); - sprintf(automsg, get_string(15), gUser->loginname, asctime(&timenow)); + snprintf(automsg, sizeof automsg, get_string(15), gUser->loginname, asctime(&timenow)); automsg[strlen(automsg) - 1] = '\r'; automsg[strlen(automsg)] = '\n'; @@ -785,8 +785,8 @@ void automessage_write() { for (i = 0; i < 4; i++) { s_printf("\r\n%d: ", i); s_readstring(buffer, 75); - strcat(automsg, buffer); - strcat(automsg, "\r\n"); + strlcat(automsg, buffer, sizeof automsg); + strlcat(automsg, "\r\n", sizeof automsg); } fptr = fopen("automessage.txt", "w"); @@ -1346,7 +1346,7 @@ char *str_replace(const char *str, const char *from, const char *to) { if (count == 0) { /* If no matches, then just duplicate the string. */ - strcpy(ret, str); + strlcpy(ret, str, retlen + 1); } else { /* Otherwise, duplicate the string whilst performing * the replacements using the position cache. */ diff --git a/src/bbs.h b/src/bbs.h index d0cc70a..0501974 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -3,6 +3,7 @@ #include +#include #include #include #ifdef __APPLE__ @@ -11,12 +12,17 @@ #if defined(ENABLE_WWW) #include #endif +#include #include "lua/lua.h" #include "lua/lauxlib.h" #include "jamlib/jam.h" #include "stralloc/stralloc.h" +#ifndef __linux__ +#define HAVE_STRLCPY +#endif + #define VERSION_MAJOR 0 #define VERSION_MINOR 12 #define VERSION_STR "alpha" @@ -405,6 +411,11 @@ extern char *str4dup(const char *a, const char *b, const char *c, const char *d) extern char *str3dup(const char *a, const char *b, const char *c); extern char *str2dup(const char *a, const char *b); +#if !defined(HAVE_STRLCPY) +extern size_t strlcat(char *dst, const char *src, size_t dsize); +extern size_t strlcpy(char *dst, const char *src, size_t dsize); +#endif + #if defined(ENABLE_WWW) extern void www_init(); extern void *www_logger(void *cls, const char *uri, struct MHD_Connection *con); diff --git a/src/bluewave.c b/src/bluewave.c index 781ab55..fc0c696 100644 --- a/src/bluewave.c +++ b/src/bluewave.c @@ -591,9 +591,9 @@ int bwave_add_message(int confr, int area, unsigned int dwritten, char *to, char jmh.DateWritten = dwritten; jmh.Attribute |= JAM_MSG_LOCAL; if (conf.mail_conferences[confr]->realnames == 0) { - strcpy(buffer, gUser->loginname); + strlcpy(buffer, gUser->loginname, sizeof buffer); } else { - sprintf(buffer, "%s %s", gUser->firstname, gUser->lastname); + snprintf(buffer, sizeof buffer, "%s %s", gUser->firstname, gUser->lastname); } jsp = JAM_NewSubPacket(); diff --git a/src/chat_system.c b/src/chat_system.c index 5b02632..c1f1273 100644 --- a/src/chat_system.c +++ b/src/chat_system.c @@ -432,8 +432,8 @@ void chat_system(struct user_record *user) { return; } - strncat(partmessage, readbuffer, len); - strcpy(readbuffer, partmessage); + strlcat(partmessage, readbuffer, sizeof(partmessage)); + strlcpy(readbuffer, partmessage, sizeof(readbuffer)); y = 0; for (z = 0; z < strlen(readbuffer); z++) { diff --git a/src/doors.c b/src/doors.c index d8d892b..39bde87 100644 --- a/src/doors.c +++ b/src/doors.c @@ -91,7 +91,7 @@ int write_door32sys(struct user_record *user) { return 1; } - strcpy(buffer, conf.sysop_name); + strlcpy(buffer, conf.sysop_name, sizeof(buffer)); ptr = NULL; diff --git a/src/email.c b/src/email.c index 6807603..7a9a2ac 100644 --- a/src/email.c +++ b/src/email.c @@ -170,7 +170,7 @@ void show_email(struct user_record *user, int msgno, int email_count, struct ema if (z == start_line) { line[0] = '\0'; } else { - strncpy(line, &emails[msgno]->body[start_line], z - start_line); + strlcpy(line, &emails[msgno]->body[start_line], z - start_line + 1); line[z - start_line] = '\0'; } if (emails[msgno]->body[z] == '\r') { diff --git a/src/mail_menu.c b/src/mail_menu.c index 30d5bcb..ac726a7 100644 --- a/src/mail_menu.c +++ b/src/mail_menu.c @@ -531,10 +531,10 @@ char *external_editor(struct user_record *user, char *to, char *from, char *quot if (!sig) { if (user->autosig) { - strcat(body2, "\r"); - strcat(body2, user->signature); + strlcat(body2, "\r", totlen + 1); + strlcat(body2, user->signature, totlen + 1); } - strcat(body2, buffer); + strlcat(body2, buffer, totlen + 1); } free(body); @@ -594,7 +594,7 @@ char *editor(struct user_record *user, char *quote, int quotelen, char *from, in while (!doquit) { s_printf(get_string(88), lines, ""); - strcpy(linebuffer, next_line_buffer); + strlcpy(linebuffer, next_line_buffer, sizeof(linebuffer)); s_readstring_inject(linebuffer, 70, next_line_buffer); memset(next_line_buffer, 0, 70); @@ -602,7 +602,7 @@ char *editor(struct user_record *user, char *quote, int quotelen, char *from, in for (i = strlen(linebuffer) - 1; i > 15; i--) { if (linebuffer[i] == ' ') { linebuffer[i] = '\0'; - strcpy(next_line_buffer, &linebuffer[i + 1]); + strlcpy(next_line_buffer, &linebuffer[i + 1], sizeof next_line_buffer); s_printf("\e[%dD\e[0K", 70 - i); break; } @@ -654,18 +654,18 @@ char *editor(struct user_record *user, char *quote, int quotelen, char *from, in msg = (char *)malloz(size); for (i = 0; i < ptr_vector_len(&content); i++) { - strcat(msg, ptr_vector_get(&content, i)); - strcat(msg, "\r"); + strlcat(msg, ptr_vector_get(&content, i), size); + strlcat(msg, "\r", size); } ptr_vector_apply(&content, free); destroy_ptr_vector(&content); if (!sig) { if (user->autosig) { - strcat(msg, "\r"); - strcat(msg, user->signature); + strlcat(msg, "\r", size); + strlcat(msg, user->signature, size); } - strcat(msg, buffer); + strlcat(msg, buffer, size); } if (quote != NULL) { @@ -1520,7 +1520,7 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno if (z == start_line) { msg_line[0] = '\0'; } else { - strncpy(msg_line, &body[start_line], z - start_line); + strlcpy(msg_line, &body[start_line], z - start_line + 1); msg_line[z - start_line] = '\0'; } if (body[z] == '\r') { @@ -1634,7 +1634,7 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno s_printf("\r\n"); if (msghs->msgs[mailno]->from != NULL) { - strcpy(buffer, msghs->msgs[mailno]->from); + strlcpy(buffer, msghs->msgs[mailno]->from, sizeof buffer); } if (conf.mail_conferences[user->cur_mail_conf]->realnames == 0) { from = strdup(user->loginname); @@ -1643,8 +1643,7 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno } if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NEWSGROUP_AREA) { free(to); - to = (char *)malloz(4); - strcpy(to, "ALL"); + to = strdup("ALL"); } replybody = external_editor(user, to, from, body, z2, msghs->msgs[mailno]->from, subject, 0, 0); if (replybody != NULL) { @@ -2064,7 +2063,7 @@ void post_message(struct user_record *user) { s_readstring(buffer, 32); } if (strlen(buffer) == 0) { - strcpy(buffer, "ALL"); + strlcpy(buffer, "ALL", sizeof(buffer)); } if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NETMAIL_AREA) { @@ -2129,9 +2128,9 @@ void post_message(struct user_record *user) { jmh.DateWritten = (uint32_t)utc_to_local(time(NULL)); jmh.Attribute |= JAM_MSG_LOCAL; if (conf.mail_conferences[user->cur_mail_conf]->realnames == 0) { - strcpy(buffer, user->loginname); + strlcpy(buffer, user->loginname, sizeof(buffer)); } else { - sprintf(buffer, "%s %s", user->firstname, user->lastname); + snprintf(buffer, sizeof buffer, "%s %s", user->firstname, user->lastname); } jsp = JAM_NewSubPacket(); diff --git a/src/strlcpy/strlcat.c b/src/strlcpy/strlcat.c new file mode 100644 index 0000000..f27dfe0 --- /dev/null +++ b/src/strlcpy/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.18 2016/10/16 17:37:39 dtucker Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Appends src to string dst of size dsize (unlike strncat, dsize is the + * full size of dst, not space left). At most dsize-1 characters + * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). + * Returns strlen(src) + MIN(dsize, strlen(initial dst)). + * If retval >= dsize, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t dsize) +{ + const char *odst = dst; + const char *osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return(dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return(dlen + (src - osrc)); /* count does not include NUL */ +} diff --git a/src/strlcpy/strlcpy.c b/src/strlcpy/strlcpy.c new file mode 100644 index 0000000..241586e --- /dev/null +++ b/src/strlcpy/strlcpy.c @@ -0,0 +1,50 @@ +/* $OpenBSD: strlcpy.c,v 1.15 2016/10/16 17:37:39 dtucker Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). + * Returns strlen(src); if retval >= dsize, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t dsize) +{ + const char *osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return(src - osrc - 1); /* count does not include NUL */ +} diff --git a/src/www_msgs.c b/src/www_msgs.c index 87dfc2a..4acfb4b 100644 --- a/src/www_msgs.c +++ b/src/www_msgs.c @@ -870,9 +870,9 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, jmh.Attribute |= JAM_MSG_LOCAL; if (conf.mail_conferences[conference]->realnames == 0) { - strcpy(buffer, user->loginname); + strlcpy(buffer, user->loginname, sizeof buffer); } else { - sprintf(buffer, "%s %s", user->firstname, user->lastname); + snprintf(buffer, sizeof buffer, "%s %s", user->firstname, user->lastname); } jsp = JAM_NewSubPacket();