[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

BUGFIX: Re: pammed qpopper?



On Fri, 2 May 1997, Chris Dent wrote:

> Following up to myself...how gauche...

And again.

[snip]
> I tried the patch and it applied, but if it is no good let me know and
> I'll make another.

I've found a very significant bug in the patch that I sent out that
allows you to use PAM with qpopper. When given a bad password it was
doing this:

user cdent
+OK Password required for cdent.
pass fruck
+OK Pop server at xxxxxxxxxxxxx signing off.
Connection closed by foreign host.

When it should have been doing this:

user cdent
+OK Password required for cdent.
pass fruck
-ERR Password supplied for "cdent" is incorrect.
+OK Pop server at xxxxxxxxxxxxx signing off.

This caused POP clients like netscape to claim "no new messages on
server" even when it never got in to do a STAT or LIST.

I have attached a new patch (agains clean qpopper2.3 source). If you just
want to make the change it your source it is a one liner. Where you
find:

	return(POP_FAILURE);

just above the end of the PAM section (around line 553) replace with:

        return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));

It was a stupid mistake. Sorry for any problems this may have caused
people.

By the way: should I clean this patch up and put it on a web page
somewhere?

..........................
Chris Dent........SysAdmin
...........Kiva Networking
Common subdirectories: qpopper2.3/doc and qpopper2.3.pam/doc
diff -c qpopper2.3/make.linux qpopper2.3.pam/make.linux
*** qpopper2.3/make.linux	Mon Mar 31 17:52:34 1997
--- qpopper2.3.pam/make.linux	Fri Apr 25 02:31:47 1997
***************
*** 39,49 ****
  
  CFLAGS                =	-DBIND43 -DHAVE_VSPRINTF -DSYSV -DLINUX \
  			-DBINMAIL_IS_SETGID \
! 			-DAPOP=\"/etc/pop.auth\" -DPOPUID=\"pop\" -DGDBM \
  #			-DAUTH
  #
  #LIBS		= -lshadow -ldbm 
! LIBS		= -lgdbm 
  
  TARGET                =       popper.linux
  
--- 39,51 ----
  
  CFLAGS                =	-DBIND43 -DHAVE_VSPRINTF -DSYSV -DLINUX \
  			-DBINMAIL_IS_SETGID \
! 			-DPAM -DAUTH
! #			-DAPOP=\"/etc/pop.auth\" -DPOPUID=\"pop\" -DGDBM \
  #			-DAUTH
  #
  #LIBS		= -lshadow -ldbm 
! #LIBS		= -lgdbm 
! LIBS            = -lpam -ldl
  
  TARGET                =       popper.linux
  
diff -c qpopper2.3/pop_pass.c qpopper2.3.pam/pop_pass.c
*** qpopper2.3/pop_pass.c	Fri Mar 28 23:30:36 1997
--- qpopper2.3.pam/pop_pass.c	Thu May  8 18:23:06 1997
***************
*** 17,22 ****
--- 17,26 ----
  # include <strings.h>
  #endif
  
+ #ifdef PAM
+ #include <security/pam_appl.h>
+ #endif
+ 
  #include <pwd.h>
  #include "popper.h"
  
***************
*** 423,429 ****
  
  #endif	/* UNIXWARE */
  
! #ifdef LINUX
  #include <shadow.h>
   
  static int
--- 427,433 ----
  
  #endif	/* UNIXWARE */
  
! #if defined(LINUX) && !defined(PAM)
  #include <shadow.h>
   
  static int
***************
*** 470,477 ****
  
      return(POP_SUCCESS);
  }
- 
  #endif  /* LINUX */
  
  #else	/* NOT AUTH */
  
--- 474,560 ----
  
      return(POP_SUCCESS);
  }
  #endif  /* LINUX */
+ 
+ #if defined(PAM) && defined(LINUX)
+ 
+ static char *PAM_username;
+ static char *PAM_password;
+ static int PAM_error =0;
+ 
+ static int PAM_conv (int num_msg,
+                      const struct pam_message **msg,
+                      struct pam_response **resp,
+                      void *appdata_ptr) {
+   int count = 0, replies = 0;
+   struct pam_response *reply = NULL;
+   int size = sizeof(struct pam_response);
+ 
+   #define GET_MEM if (reply) realloc(reply, size); else reply = malloc(size); \
+   if (!reply) return PAM_CONV_ERR; \
+   size += sizeof(struct pam_response)
+   #define COPY_STRING(s) (s) ? strdup(s) : NULL
+ 
+   for (count = 0; count < num_msg; count++) {
+     switch (msg[count]->msg_style) {
+       case PAM_PROMPT_ECHO_ON:
+         GET_MEM;
+         reply[replies].resp_retcode = PAM_SUCCESS;
+         reply[replies++].resp = COPY_STRING(PAM_username);
+           /* PAM frees resp */
+         break;
+       case PAM_PROMPT_ECHO_OFF:
+         GET_MEM;
+         reply[replies].resp_retcode = PAM_SUCCESS;
+         reply[replies++].resp = COPY_STRING(PAM_password);
+           /* PAM frees resp */
+         break;
+       case PAM_TEXT_INFO:
+         /* ignore it... */
+         break;
+       case PAM_ERROR_MSG:
+       default:
+         /* Must be an error of some sort... */
+         free (reply);
+         PAM_error = 1;
+         return PAM_CONV_ERR;
+     }
+   }
+   if (reply) *resp = reply;
+   return PAM_SUCCESS;
+ }
+ 
+ struct pam_conv conv = {
+   PAM_conv,
+   NULL
+ };
+  
+ static int
+ auth_user(p, pw)
+ POP     *   p;
+ {
+     pam_handle_t *pamh=NULL;
+     int retval;
+ 
+     const char *user="nobody";
+ 
+     user = p->user;
+     PAM_username = user;
+     PAM_password = p->pop_parm[1];
+     retval = pam_start("qpop", user, &conv, &pamh);
+     if (retval == PAM_SUCCESS)
+        retval = pam_authenticate(pamh, 0);
+     if (retval == PAM_SUCCESS)
+        retval = pam_acct_mgmt(pamh, 0);
+     if (retval == PAM_SUCCESS) {
+        return(POP_SUCCESS);
+     } else {
+        sleep(SLEEP_SECONDS); 
+        return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
+     }
+ }
+ 
+ #endif  /* PAM */
  
  #else	/* NOT AUTH */
  

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []