--- inn-1.7.2.orig/frontends/inews.c
+++ inn-1.7.2/frontends/inews.c
@@ -28,7 +28,7 @@
 #define HEADER_DELTA		20
 #define GECOSTERM(c)		\
 	    ((c) == ',' || (c) == ';' || (c) == ':' || (c) == LPAREN)
-
+#define HEADER_STRLEN		998
 
 typedef enum _HEADERTYPE {
     HTobs,
@@ -121,7 +121,7 @@
 QuitServer(x)
     int		x;
 {
-    char	buff[NNTP_STRLEN + 2];
+    char	buff[HEADER_STRLEN];
     char	*p;
 
     if (Spooling)
@@ -344,9 +344,15 @@
 	if (buff[0] == '.' && buff[1] == '\0')
 	    break;
 	if (EQn(buff, "Sender:", 7))
-	    (void)strcpy(remotefrom, TrimSpaces(&buff[7]));
+	{
+	    (void)strncpy(remotefrom, TrimSpaces(&buff[7]), SMBUF);
+	    remotefrom[SMBUF-1] = '\0';
+	}
 	else if (remotefrom[0] == '\0' && EQn(buff, "From:", 5))
-	    (void)strcpy(remotefrom, TrimSpaces(&buff[5]));
+	{
+	    (void)strncpy(remotefrom, TrimSpaces(&buff[5]), SMBUF);
+	    remotefrom[SMBUF-1] = '\0';
+	}
     }
     if (remotefrom[0] == '\0') {
 	if (JustReturn)
@@ -357,7 +363,8 @@
     HeaderCleanFrom(remotefrom);
 
     /* Get the local user. */
-    (void)strcpy(localfrom, HDR(_sender) ? HDR(_sender) : HDR(_from));
+    (void)strncpy(localfrom, HDR(_sender) ? HDR(_sender) : HDR(_from), SMBUF);
+    localfrom[SMBUF-1] = '\0';
     HeaderCleanFrom(localfrom);
 
     /* Is the right person cancelling? */
@@ -449,7 +456,8 @@
 	  || EQ(ctrl, "sendsys")
 	  || EQ(ctrl, "senduuname")
 	  || EQ(ctrl, "version")) {
-	(void)strcpy(name, pwp->pw_name);
+	(void)strncpy(name, pwp->pw_name, SMBUF);
+	name[SMBUF-1] = '\0';
 	if (!AnAdministrator(name, (int)pwp->pw_gid)) {
 	    (void)fprintf(stderr,
 		    "Ask your news administrator to do the \"%s\" for you.\n",
@@ -485,6 +493,7 @@
     char	outbuff[SMBUF];
     char	*out;
     char	*p;
+    int 	left;
 
 #if	!defined(DONT_MUNGE_GETENV)
     (void)memset(outbuff, 0, SMBUF);
@@ -497,26 +506,40 @@
 
 
 #if	defined(DONT_MUNGE_GECOS)
-    (void)strcpy(outbuff, pwp->pw_gecos);
+    (void)strncpy(outbuff, pwp->pw_gecos, SMBUF);
+    outbuff[SMBUF-1] = '\0';
 #else
+    /* Be very careful here.  If we're not, we can potentially overflow our
+     * buffer.  Remember that on some Unix systems, the content of the GECOS
+     * field is under (untrusted) user control and we could be setgid. */
     p = pwp->pw_gecos;
+    left = SMBUF - 1;
     if (*p == '*')
 	p++;
-    for (out = outbuff; *p && !GECOSTERM(*p); p++) {
+    for (out = outbuff; *p && !GECOSTERM(*p) && left; p++) {
 	if (*p == '&') {
-	    (void)strcpy(out, pwp->pw_name);
+	    (void)strncpy(out, pwp->pw_name, left);
 	    if (CTYPE(islower, *out)
 	     && (out == outbuff || !isalpha(out[-1])))
 		*out = toupper(*out);
 	    while (*out)
+	    {
 		out++;
+		left--;
+	    }
 	}
 	else if (*p == '-'
 	      && p > pwp->pw_gecos
 	      && (isdigit(p[-1]) || isspace(p[-1]) || p[-1] == ']'))
+	{
 	    out = outbuff;
+	    left = SMBUF - 1;
+	}
 	else
+	{
 	    *out++ = *p;
+	    left--;
+	}
     }
     *out = '\0';
 #endif	/* defined(DONT_MUNGE_GECOS) */
@@ -527,9 +550,9 @@
 
     out = TrimSpaces(outbuff);
     if (out[0])
-	(void)sprintf(buff, "%s@%s (%s)", pwp->pw_name, node, out);
+	(void)snprintf(buff, sizeof (buff), "%s@%s (%s)", pwp->pw_name, node, out);
     else
-	(void)sprintf(buff, "%s@%s", pwp->pw_name, node);
+	(void)snprintf(buff, sizeof (buff), "%s@%s", pwp->pw_name, node);
     return COPY(buff);
 }
 
@@ -597,13 +620,20 @@
     if ((p = GetConfigValue(_CONF_FROMHOST)) == NULL)
 	PerrorExit(TRUE, "Can't get host name");
     if (HDR(_from) == NULL)
-	HDR(_from) = FormatUserName(pwp, p);
+       HDR(_from) = FormatUserName(pwp, p);
     else {
+      if (strlen(pwp->pw_name) + strlen(p) + 2 > sizeof(buff)) {
+          fprintf(stderr, "Username and host too long\n");
+          QuitServer(1);
+      }
       (void)sprintf(buff, "%s@%s", pwp->pw_name, p);
-      (void)strcpy(from, HDR(_from));
+      (void)strncpy(from, HDR(_from), SMBUF);
+      from[SMBUF-1] = '\0';
       HeaderCleanFrom(from);
+#ifdef PRETTY_PLEASE_ADD_SENDER_HEADER
       if (!EQ(from, buff))
         HDR(_sender) = COPY(buff);
+#endif
     }
 
     /* Set Date. */
@@ -616,7 +646,7 @@
      * printf's treat it %02 (two digits wide) .2 (zero-fill to at least
      * two digits), while old versions treat it as %02 (zero-fill two
      * digits wide) .2 (noise).  You might want to check this on your
-     * system. */
+     * system.  This shouldn't be able to overflow SMBUF... */
     if (Now.tzone < 0) {
 	p = &SIGNS[0];
 	zone = -Now.tzone;
@@ -678,9 +708,20 @@
 	    i += strlen(p) + 1;
 	    HDR(_path) = NEW(char, i + 1);
 	    if (*p)
+	    {
+		if (strlen(Exclusions) + strlen(p) + strlen(PATHFLUFF) + 2 <= sizeof(HDR(_path))) {
+		    fprintf(stderr, "Path line too long\n");
+		    QuitServer(1);
+		}
 		(void)sprintf(HDR(_path), "%s%s!%s", Exclusions, p, PATHFLUFF);
 	    else
+	    {
+		if (strlen(Exclusions) + strlen(PATHFLUFF) +1 > sizeof(HDR(_path))) {
+		    fprintf(stderr, "Path line too long\n");
+		    QuitServer(1);
+		}
 		(void)sprintf(HDR(_path), "%s%s", Exclusions, PATHFLUFF);
+	    }
 	}
 	else if (GetFileConfigValue(_CONF_SERVER) != NULL) {
 	    if ((p = GetFQDN()) == NULL) {
@@ -774,6 +815,10 @@
 
     /* Open the file. */
     *linesp = 0;
+    if (strlen(homedir) > sizeof(buff) - 14) {
+        fprintf(stderr, "Home directory path too long\n");
+        QuitServer(1);
+    }
     (void)sprintf(buff, "%s/.signature", homedir);
     if ((F = fopen(buff, "r")) == NULL) {
 	if (errno == ENOENT)
@@ -1088,7 +1133,7 @@
 {
     (void)fprintf(ToServer, "post\r\n");
     SafeFlush(ToServer);
-    if (fgets(buff, NNTP_STRLEN, FromServer) == NULL)
+    if (fgets(buff, HEADER_STRLEN, FromServer) == NULL)
 	PerrorExit(TRUE,
 	    Authorized ? "Can't offer article to server (authorized)"
 		       : "Can't offer article to server");
@@ -1178,8 +1223,8 @@
     struct passwd	*pwp;
     char		*article;
     char		*deadfile;
-    char		buff[NNTP_STRLEN + 2];
-    char		SpoolMessage[NNTP_STRLEN + 2];
+    char		buff[HEADER_STRLEN];
+    char		SpoolMessage[HEADER_STRLEN];
     BOOL		DoSignature;
     BOOL		AddOrg;
     SIZE_T		Length;
@@ -1269,23 +1314,33 @@
 	if ((p = strchr(buff, '\r')) != NULL)
 	    *p = '\0';
 	(void)strcpy(SpoolMessage, buff[0] ? buff : NOCONNECT);
+        if (strlen(pwp->pw_dir) > sizeof(buff) - 14) {
+            fprintf(stderr, "Home directory path too long\n");
+            exit(1);
+        }
 	(void)sprintf(buff, "%s/dead.article", pwp->pw_dir);
 	deadfile = COPY(buff);
     }
     else {
+	setbuf(FromServer, NEW(char, BUFSIZ));
+	setbuf(ToServer, NEW(char, BUFSIZ));
 	/* See if we can post. */
 	i = atoi(buff);
 
 	/* Tell the server we're posting. */
-	setbuf(FromServer, NEW(char, BUFSIZ));
-	setbuf(ToServer, NEW(char, BUFSIZ));
 	(void)fprintf(ToServer, "mode reader\r\n");
 	SafeFlush(ToServer);
-	if (fgets(buff, NNTP_STRLEN, FromServer) == NULL)
+	if (fgets(buff, HEADER_STRLEN, FromServer) == NULL)
 	    PerrorExit(TRUE, "Can't tell server we're reading");
 	if ((j = atoi(buff)) != NNTP_BAD_COMMAND_VAL)
 	    i = j;
 
+	/* Authorize with password if required. */
+	if (i == NNTP_AUTH_NEEDED_VAL) {
+	    if (NNTPsendpassword((char *)NULL, FromServer, ToServer) < 0)
+		PerrorExit(TRUE, "Authorization error");
+	    i = NNTP_POSTOK_VAL;
+	}
 	if (i != NNTP_POSTOK_VAL) {
 	    (void)fprintf(stderr, "You do not have permission to post.\n");
 	    QuitServer(1);
@@ -1324,22 +1379,22 @@
 	QuitServer(1);
     }
     for (hp = Table; hp < ENDOF(Table); hp++)
-	if (hp->Value && (int)strlen(hp->Value) + hp->Size > NNTP_STRLEN) {
+	if (hp->Value && (int)strlen(hp->Value) + hp->Size > HEADER_STRLEN) {
 	    (void)fprintf(stderr, "\"%s\" header is too long.\n", hp->Name);
 	    QuitServer(1);
 	}
     for (i = 0; i < OtherCount; i++)
-	if ((int)strlen(OtherHeaders[i]) > NNTP_STRLEN) {
+	if ((int)strlen(OtherHeaders[i]) > HEADER_STRLEN) {
 	    (void)fprintf(stderr,
 		    "Header too long (%d characters max):\n\t%40.40s...\n",
-		    NNTP_STRLEN, OtherHeaders[i]);
+		    HEADER_STRLEN, OtherHeaders[i]);
 	    QuitServer(1);
 	}
 
     /* Check the newsgroups. */
-    if ((F = CAlistopen(FromServer, ToServer, (char *)NULL)) == NULL) {
+    if ((F = CAopen(FromServer, ToServer)) == NULL) {
 	if (NNTPsendpassword((char *)NULL, FromServer, ToServer) >= 0)
-	    F = CAlistopen(FromServer, ToServer, (char *)NULL);
+	    F = CAopen(FromServer, ToServer);
     }
     if (F != NULL) {
 	if (!ValidNewsgroups(HDR(_newsgroups), F, article)) {
