Bug 79639

Summary: security problem with gets
Product: [Retired] Red Hat Linux Reporter: d.binderman
Component: imapAssignee: Mike A. Harris <mharris>
Status: CLOSED WONTFIX QA Contact: David Lawrence <dkl>
Severity: low Docs Contact:
Priority: medium    
Version: 8.0   
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2002-12-18 20:56:41 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Description d.binderman 2002-12-14 10:39:42 UTC
Description of problem:

Hello there,

I just tried to compile package imap-2001a-15 from Redhat 8.0.

Here are some of the compiler messages.

/usr/src/redhat/BUILD/imap-2001a/mtest/mtest.c:517: the `gets' function is dangerous and should not be used.

The man page for gets suggests that fgets is a suitable replacement.

I make the following untested patch

*** ./src/mtest/mtest.c.old	2001-06-05 19:53:44.000000000 +0100
--- ./src/mtest/mtest.c	2002-11-29 08:44:55.000000000 +0000
***************
*** 77,83 ****
  void header (MAILSTREAM *stream,long msgno);
  void display_body (BODY *body,char *pfx,long i);
  void status (MAILSTREAM *stream);
! void prompt (char *msg,char *txt);
  void smtptest (long debug);
  

  /* Main program - initialization */
--- 77,83 ----
  void header (MAILSTREAM *stream,long msgno);
  void display_body (BODY *body,char *pfx,long i);
  void status (MAILSTREAM *stream);
! static void prompt (char *msg,char *txt, int txtSize);
  void smtptest (long debug);
  

  /* Main program - initialization */
***************
*** 115,127 ****
  #endif
    curhst = cpystr (mylocalhost ());
    puts ("MTest -- C client test program");
!   if (!*personalname) prompt ("Personal name: ",personalname);
  				/* user wants protocol telemetry? */
!   prompt ("Debug protocol (y/n)?",tmp);
    ucase (tmp);
    debug = (tmp[0] == 'Y') ? T : NIL;
    do {
!     prompt ("Mailbox ('?' for help): ",tmp);
      if (!strcmp (tmp,"?")) {
        puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
        puts ("Known local mailboxes:");
--- 115,128 ----
  #endif
    curhst = cpystr (mylocalhost ());
    puts ("MTest -- C client test program");
!   if (!*personalname) 
! 	prompt ("Personal name: ",personalname, sizeof( personalname));
  				/* user wants protocol telemetry? */
!   prompt ("Debug protocol (y/n)?",tmp, sizeof tmp);
    ucase (tmp);
    debug = (tmp[0] == 'Y') ? T : NIL;
    do {
!     prompt ("Mailbox ('?' for help): ",tmp, sizeof tmp);
      if (!strcmp (tmp,"?")) {
        puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
        puts ("Known local mailboxes:");
***************
*** 157,163 ****
    BODY *body;
    status (stream);		/* first report message status */
    while (stream) {
!     prompt ("MTest>",cmd);	/* prompt user, get command */
  				/* get argument */
      if (arg = strchr (cmd,' ')) *arg++ = '\0';
      switch (*ucase (cmd)) {	/* dispatch based on command */
--- 158,164 ----
    BODY *body;
    status (stream);		/* first report message status */
    while (stream) {
!     prompt ("MTest>",cmd, sizeof( cmd));	/* prompt user, get command */
  				/* get argument */
      if (arg = strchr (cmd,' ')) *arg++ = '\0';
      switch (*ucase (cmd)) {	/* dispatch based on command */
***************
*** 252,258 ****
        }
  				/* get the new mailbox */
        while (!(stream = mail_open (stream,arg,debug))) {
! 	prompt ("Mailbox: ",arg);
  	if (!arg[0]) break;
        }
        last = 0;
--- 253,259 ----
        }
  				/* get the new mailbox */
        while (!(stream = mail_open (stream,arg,debug))) {
! 	prompt ("Mailbox: ",arg, sizeof( arg));
  	if (!arg[0]) break;
        }
        last = 0;
***************
*** 511,520 ****
   *          pointer to input buffer
   */
  
! void prompt (char *msg,char *txt)
  {
    printf ("%s",msg);
!   gets (txt);
  }
  

  /* Interfaces to C-client */
--- 512,522 ----
   *          pointer to input buffer
   */
  
! static void 
! prompt (char *msg,char *txt, int txtSize)
  {
    printf ("%s",msg);
!   fgets (txt, txtSize, stdin);
  }
  

  /* Interfaces to C-client */
***************
*** 624,630 ****
    }
    else {
      sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
!     prompt (tmp,user);
      strcpy (tmp,"Password: ");
    }
    if (curusr) fs_give ((void **) &curusr);
--- 626,632 ----
    }
    else {
      sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
!     prompt (tmp,user, sizeof( user));
      strcpy (tmp,"Password: ");
    }
    if (curusr) fs_give ((void **) &curusr);
***************
*** 632,638 ****
  #if UNIXLIKE
    strcpy (pwd,getpass (tmp));
  #else
!   prompt (tmp,pwd);
  #endif
  }
  
--- 634,640 ----
  #if UNIXLIKE
    strcpy (pwd,getpass (tmp));
  #else
!   prompt (tmp,pwd, sizeof( pwd));
  #endif
  }
  
***************
*** 679,692 ****
    msg->return_path = mail_newaddr ();
    msg->return_path->mailbox = cpystr (curusr);
    msg->return_path->host = cpystr (curhst);
!   prompt ("To: ",line);
    rfc822_parse_adrlist (&msg->to,line,curhst);
    if (msg->to) {
!     prompt ("cc: ",line);
      rfc822_parse_adrlist (&msg->cc,line,curhst);
    }
    else {
!     prompt ("Newsgroups: ",line);
      if (*line) msg->newsgroups = cpystr (line);
      else {
        mail_free_body (&body);
--- 681,694 ----
    msg->return_path = mail_newaddr ();
    msg->return_path->mailbox = cpystr (curusr);
    msg->return_path->host = cpystr (curhst);
!   prompt ("To: ",line, sizeof( line));
    rfc822_parse_adrlist (&msg->to,line,curhst);
    if (msg->to) {
!     prompt ("cc: ",line, sizeof( line));
      rfc822_parse_adrlist (&msg->cc,line,curhst);
    }
    else {
!     prompt ("Newsgroups: ",line, sizeof( line));
      if (*line) msg->newsgroups = cpystr (line);
      else {
        mail_free_body (&body);
***************
*** 694,705 ****
        fs_give ((void **) &text);
      }
    }
!   prompt ("Subject: ",line);
    msg->subject = cpystr (line);
    puts (" Msg (end with a line with only a '.'):");
    body->type = TYPETEXT;
    *text = '\0';
!   while (gets (line)) {
      if (line[0] == '.') {
        if (line[1] == '\0') break;
        else strcat (text,".");
--- 696,707 ----
        fs_give ((void **) &text);
      }
    }
!   prompt ("Subject: ",line, sizeof( line));
    msg->subject = cpystr (line);
    puts (" Msg (end with a line with only a '.'):");
    body->type = TYPETEXT;
    *text = '\0';
!   while (fgets (line, sizeof( line), stdin)) {
      if (line[0] == '.') {
        if (line[1] == '\0') break;
        else strcat (text,".");


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.
    
Actual results:


Expected results:


Additional info:

Comment 1 Alan Cox 2002-12-18 18:51:21 UTC
This is a test tool not something we install


Comment 2 Mike A. Harris 2002-12-18 20:56:41 UTC
As Alan says, this is a test tool, and is not even shipped with Red Hat Linux.
Also, the imap FAQ states that they are aware of gets() and consider it
a non issue due to the nature of the software.

Personally, I would fix it if I was the upstream maintainer, just to have
more robust software regardless of how trivial it is, and to also not
propagate poor programming techniques.  However upstream maintainers are
unlikely to be convinced in any case.

Closing WONTFIX