[PATCH 1/2] Support changing expired passwords

2016-04-25 Thread Joakim Tjernlund
This adds support for handling expired passwords in the server.
Client remains to do.

Signed-off-by: Joakim Tjernlund <joakim.tjernl...@infinera.com>
---
 auth.h|  1 +
 svr-auth.c| 21 +
 svr-authpam.c | 52 +---
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/auth.h b/auth.h
index 3a47401..a6bb3f1 100644
--- a/auth.h
+++ b/auth.h
@@ -36,6 +36,7 @@ void cli_authinitialise();
 void recv_msg_userauth_request();
 void send_msg_userauth_failure(int partial, int incrfail);
 void send_msg_userauth_success();
+void send_msg_userauth_chauthtok();
 void send_msg_userauth_banner(buffer *msg);
 void svr_auth_password();
 void svr_auth_pubkey();
diff --git a/svr-auth.c b/svr-auth.c
index 2febe8d..35c4758 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -419,3 +419,24 @@ void send_msg_userauth_success() {
TRACE(("leave send_msg_userauth_success"))
 
 }
+
+/* Send change password */
+void send_msg_userauth_chauthtok() {
+#ifdef ENABLE_SVR_PAM_AUTH
+   const char * msg = "";
+#else
+   const char * msg = "Password has expired, please change now";
+#endif
+
+   TRACE(("enter send_msg_userauth_chauthtok"))
+
+   CHECKCLEARTOWRITE();
+
+   buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ);
+   buf_putstring(ses.writepayload, msg, strlen(msg));
+   buf_putstring(ses.writepayload, "en", 2);
+
+   encrypt_packet();
+
+   TRACE(("leave send_msg_userauth_chauthtok"))
+}
diff --git a/svr-authpam.c b/svr-authpam.c
index 30de5b3..033dfae 100644
--- a/svr-authpam.c
+++ b/svr-authpam.c
@@ -40,8 +40,9 @@
 #endif
 
 struct UserDataS {
-   char* user;
+   const char* user;
char* passwd;
+   char* new_passwd;
 };
 
 /* PAM conversation function - for now we only handle one message */
@@ -89,7 +90,7 @@ pamConvFunc(int num_msg,
 
case PAM_PROMPT_ECHO_OFF:
 
-   if (!(strcmp(compare_message, "password:") == 0)) {
+   if (strstr(compare_message, "password:") == NULL) {
/* We don't recognise the prompt as asking for 
a password,
   so can't handle it. Add more above as 
required for
   different pam modules/implementations. If 
you need
@@ -106,9 +107,10 @@ pamConvFunc(int num_msg,
 * it here */
resp = (struct pam_response*) m_malloc(sizeof(struct 
pam_response));
memset(resp, 0, sizeof(struct pam_response));
-
-   resp->resp = m_strdup(userDatap->passwd);
-   m_burn(userDatap->passwd, strlen(userDatap->passwd));
+   if (strstr(compare_message, "new"))
+   resp->resp = m_strdup(userDatap->new_passwd);
+   else
+   resp->resp = m_strdup(userDatap->passwd);
(*respp) = resp;
break;
 
@@ -180,7 +182,7 @@ pamConvFunc(int num_msg,
  * interactive responses, over the network. */
 void svr_auth_pam(const char * username, int localUserMissing) {
 
-   struct UserDataS userData = {NULL, NULL};
+   struct UserDataS userData = {NULL, NULL, NULL};
struct pam_conv pamConv = {
pamConvFunc,
 /* submitted to pamvConvFunc as appdata_ptr */ 
@@ -189,6 +191,7 @@ void svr_auth_pam(const char * username, int 
localUserMissing) {
pam_handle_t* pamHandlep = NULL;
 
char * password = NULL;
+   char * new_password = NULL;
unsigned int passwordlen;
 
int rc = PAM_SUCCESS;
@@ -196,19 +199,16 @@ void svr_auth_pam(const char * username, int 
localUserMissing) {
 
/* check if client wants to change password */
changepw = buf_getbool(ses.payload);
-   if (changepw) {
-   /* not implemented by this server */
-   send_msg_userauth_failure(0, 1);
-   goto cleanup;
-   }
 
password = buf_getstring(ses.payload, );
-
+   if (changepw)
+   new_password = buf_getstring(ses.payload, );
/* used to pass data to the PAM conversation function - don't bother 
with
 * strdup() etc since these are touched only by our own conversation
 * function (above) which takes care of it */
userData.user = username;
userData.passwd = password;
+   userData.new_passwd = new_password;
 
/* Init pam */
if ((rc = pam_start("sshd", NULL, , )) != 
PAM_SUCCESS) {
@@ -242,7 +242,22 @@ void svr_auth_pam(const char * username, int 
localUserMissing) {
goto cleanup;
}
 
-   if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) {
+  

[PATCH 2/2] Support changing expired passwords in client

2016-04-25 Thread Joakim Tjernlund
This adds support for handling expired passwords in the client.

Signed-off-by: Joakim Tjernlund <joakim.tjernl...@infinera.com>
---
 auth.h   |  1 +
 cli-auth.c   |  8 ++-
 cli-authpasswd.c | 71 
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/auth.h b/auth.h
index a6bb3f1..a0aa3a4 100644
--- a/auth.h
+++ b/auth.h
@@ -39,6 +39,7 @@ void send_msg_userauth_success();
 void send_msg_userauth_chauthtok();
 void send_msg_userauth_banner(buffer *msg);
 void svr_auth_password();
+void cli_auth_new_password();
 void svr_auth_pubkey();
 void svr_auth_pam(const char * username, int createLocalUser);
 
diff --git a/cli-auth.c b/cli-auth.c
index da0d9d5..1eb93e7 100644
--- a/cli-auth.c
+++ b/cli-auth.c
@@ -137,12 +137,8 @@ void recv_msg_userauth_specific_60() {
 
 #ifdef ENABLE_CLI_PASSWORD_AUTH
if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) {
-   /* Eventually there could be proper password-changing
-* support. However currently few servers seem to
-* implement it, and password auth is last-resort
-* regardless - keyboard-interactive is more likely
-* to be used anyway. */
-   dropbear_close("Your password has expired.");
+   cli_auth_new_password();
+   return;
}
 #endif
 
diff --git a/cli-authpasswd.c b/cli-authpasswd.c
index 3cf49a2..72e6f2e 100644
--- a/cli-authpasswd.c
+++ b/cli-authpasswd.c
@@ -158,4 +158,75 @@ void cli_auth_password() {
 
TRACE(("leave cli_auth_password"))
 }
+
+static char *ask_password(char* prompt)
+{
+   char* password = NULL;
+
+#ifdef ENABLE_CLI_ASKPASS_HELPER
+   if (want_askpass())
+   {
+   password = gui_getpass(prompt);
+   if (!password) {
+   dropbear_exit("No password");
+   }
+   } else
+#endif
+   {
+   password = getpass_or_cancel(prompt);
+   }
+   return password;
+}
+
+void cli_auth_new_password() {
+
+   char* password = NULL;
+   char* new_password = NULL;
+   char* new2_password = NULL;
+   char prompt[80];
+
+   TRACE(("enter cli_auth_password"))
+   CHECKCLEARTOWRITE();
+
+   snprintf(prompt, sizeof(prompt), "Enter %s@%s's old password: ",
+   cli_opts.username, cli_opts.remotehost);
+   password = strdup(ask_password(prompt));
+   do {
+   snprintf(prompt, sizeof(prompt), "Enter %s@%s's new password: ",
+cli_opts.username, cli_opts.remotehost);
+   new_password = strdup(ask_password(prompt));
+   snprintf(prompt, sizeof(prompt), "Retype %s@%s's new password: 
",
+cli_opts.username, cli_opts.remotehost);
+   new2_password = strdup(ask_password(prompt));
+   if (strcmp(new_password, new2_password) == 0)
+   break; /* Both passworde match, continue with login */
+   fprintf(stderr, "Mismatch; try again, Ctrl-C to quit\n");
+   } while (1);
+   buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+   buf_putstring(ses.writepayload, cli_opts.username,
+   strlen(cli_opts.username));
+
+   buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION,
+   SSH_SERVICE_CONNECTION_LEN);
+
+   buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD,
+   AUTH_METHOD_PASSWORD_LEN);
+
+   buf_putbyte(ses.writepayload, 1); /* TRUE */
+   buf_putstring(ses.writepayload, password, strlen(password));
+   buf_putstring(ses.writepayload, new_password, strlen(new_password));
+
+   encrypt_packet();
+   m_burn(password, strlen(password));
+   if (new_password)
+   m_burn(new_password, strlen(new_password));
+   if (new2_password)
+   m_burn(new2_password, strlen(new2_password));
+   free(password);
+   free(new_password);
+   free(new2_password);
+   TRACE(("leave cli_auth_password"))
+}
+
 #endif /* ENABLE_CLI_PASSWORD_AUTH */
-- 
2.7.3



Re: dropbear and PAM_NEW_AUTHTOK_REQ ?

2016-04-25 Thread Joakim Tjernlund
On Fri, 2016-04-22 at 21:48 +0800, Matt Johnston wrote:
> Hi Joakim,
> 
> Does this work for changing passwords? I'm not entirely clear on what 
> pam_chauthtok() does, but if it tries
> a PAM conversation with the user it won't work - Dropbear's PAM password 
> login is a bit of a hack to just
> reply with the given password. (There's a branch 
> https://secure.ucc.asn.au/hg/dropbear/shortlog/696205e3dc99
>  to handle it properly, but that needs some attention before merging)
> 
> I might be missing something though. I'll try to look further next week.

Matt, did some more hacking during the weekend. I will send two patches to the 
list for
you to look at. I hope they still apply on latest dropbear but if not it will 
be trivial
to fix I think.
Let me know what you think, unless there is a problem we will use these two 
patches for now.

> 
> Cheers,
> Matt
> 
> > 
> > On Fri 22/4/2016, at 1:30 pm, Joakim Tjernlund 
> > <joakim.tjernl...@infinera.com> wrote:
> > 
> > On Tue, 2016-04-19 at 12:59 +0200, Joakim Tjernlund wrote:
> > > 
> > > Just had a look at adding support for PAM_NEW_AUTHTOK_REQ in dropbear 
> > > like so:
> > > --- a/svr-authpam.c
> > > +++ b/svr-authpam.c
> > > -   if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) {
> > > +   rc = pam_acct_mgmt(pamHandlep, 0);
> > > +   if (rc == PAM_NEW_AUTHTOK_REQD) {
> > > +   rc = pam_chauthtok(pamHandlep, 
> > > PAM_CHANGE_EXPIRED_AUTHTOK);
> > > +   }
> > > +   if (rc != PAM_SUCCESS) {
> > > 
> > > This is of course not enough and I wonder if upstream dropbear would be
> > > interested in adding support for PAM_NEW_AUTHTOK_REQ?
> > > 
> > >  Jocke
> > Ping ?
> > 
> > PAM_NEW_AUTHTOK_REQ is needed to support passwd expiration, that is, 
> > forcing the
> > user to change passwd at first login/or passwd to old.
> > 
> >  Jocke


Re: patch: a deficiency in pam support

2016-09-19 Thread Joakim Tjernlund
On Sun, 2016-09-18 at 20:56 +0200, u-p...@aetey.se wrote:
> Hello,
> 
> [While configuring dropbear-2016.74 for use with pam_krb5] I found
> a deficiency, the lack of pam_setcred(), and suggest a fix as follows:

This reminds me, I have several fix to pam / expired passwd handling.
I just (dry) ported them to:
https://github.com/joakim-tjernlund/dropbear/commits/expired_passwd
Hopefully these can be added to dropbear.

You might want to build kerberos upon that

 Jocke

> 
> sed -i.orig '
> /\/\* successful authentication \*\//i\
> if ((rc = pam_setcred(pamHandlep, 0)) != PAM_SUCCESS) {\
> dropbear_log(LOG_WARNING, "pam_setcred() failed, rc=%d, %s",\
> rc, pam_strerror(pamHandlep, rc));\
> send_msg_userauth_failure(0, 1);\
> goto cleanup;\
> }\
> 
> ' svr-authpam.c
> 
> It is not complete to be able to use the Kerberos tickets after login,
> the KRB5CCNAME variable needs to be passed from pam to the user environment.
> 
> Thus, conditionally passing KRB5CCNAME would be a useful feature.
> 
> NFSv4/Kerberos finds the user tickets on its own, because of this
> the above change _is_ sufficient for accessing NFSv4 home directories.
> 
> It also improves the conformance to the pam API.
> 
> Regards,
> Rune
> 


Re: dropbear and new host keys?

2019-12-12 Thread Joakim Tjernlund
On Thu, 2019-12-12 at 13:31 +, Geoff Winkless wrote:
> 
> On Wed, 11 Dec 2019 at 17:00, Joakim Tjernlund
>  wrote:
> > In out case we cannot just restart dropbear and rebooting just for new keys 
> > is not an option either.
> > Could dropbear gain automatic reread of keys ?
> 
> You know if you kill the parent process the child processes keep
> running? So you can restart it without disconnecting everyone.

Yes, but in our case dropbear start/stop script is connected with several other 
daemons, but yes it can be
worked around.

The bigger issue here is why not reread keys at every new session? That seems 
to like the
right thing to do in any case? 

 Jocke


Re: dropbear and new host keys?

2019-12-12 Thread Joakim Tjernlund
On Wed, 2019-12-11 at 18:00 +0100, Joakim Tjernlund wrote:
> On Wed, 2019-12-11 at 23:53 +0800, Matt Johnston wrote:
> > Hi Joakim,
> > 
> > The server needs to be stopped and restarted. If this is for new keys at
> > first-boot you could look at the -R option.
> 
> It's not first boot :(
> This is when a user wants to replace the current keys for some reason. 
> Ideally the
> next new session should read the new keys automatically.
> 
> In out case we cannot just restart dropbear and rebooting just for new keys 
> is not an option either.
> Could dropbear gain automatic reread of keys ?
> 

W.r.t -R option, will it dectect a bad key and regenerate a new one ?
One problem we have with using -R is that we need to convert dropbear keys to 
openssh
format as well and I cannot see a way to automatically trigger dropbearconvert 
etc.
if we do use -R, is there a way?

 Jocke


Re: dropbear and new host keys?

2019-12-11 Thread Joakim Tjernlund
On Wed, 2019-12-11 at 23:53 +0800, Matt Johnston wrote:
> 
> Hi Joakim,
> 
> The server needs to be stopped and restarted. If this is for new keys at
> first-boot you could look at the -R option.

It's not first boot :(
This is when a user wants to replace the current keys for some reason. Ideally 
the
next new session should read the new keys automatically.

In out case we cannot just restart dropbear and rebooting just for new keys is 
not an option either.
Could dropbear gain automatic reread of keys ?

 Jocke

> 
> Cheers,
> Matt
> 
> On Wed, Dec 11, 2019 at 03:38:36PM +, Joakim Tjernlund wrote:
> > Is there a way to tell a running dropbear server to reread host keys if the 
> > keys has changed?
> > 
> >  Jocke



dropbear and new host keys?

2019-12-11 Thread Joakim Tjernlund
Is there a way to tell a running dropbear server to reread host keys if the 
keys has changed?

 Jocke 


Re: dropbear and new host keys?

2019-12-12 Thread Joakim Tjernlund
On Thu, 2019-12-12 at 18:34 +0100, Hans Harder wrote:
> 
> >   The bigger issue here is why not reread keys at every new session? That 
> > seems to like the right thing to do in any case? 
> 
> Performance...

My text above was badly worded, should be: reread if keyfiles has changed.

> Why should you do that.
> You should not change your host keys everytime, because the connecting client 
> will have a conflict and get a warning about a possible man in the middle 
> attack because it cannot verify the host since the hostkey is changed.
> 

Of course not, I didn't say that you should change keys every new session. 
However, every now and then an admin may regenerate keys and it would
be great if dropbear picked up these new keys automatically, it is easy to 
forget that one also have to restart dropbear ...

> Simple way is to generate the new hostkeys, kill the main dropbear and start 
> it again.
> Should be a very simple script...  and the current running sessions are not 
> affected.
> 
> Hans
> 
> 
> On Thu, Dec 12, 2019 at 2:58 PM Joakim Tjernlund 
>  wrote:
> > On Thu, 2019-12-12 at 13:31 +, Geoff Winkless wrote:
> > > 
> > > On Wed, 11 Dec 2019 at 17:00, Joakim Tjernlund
> > >  wrote:
> > > > In out case we cannot just restart dropbear and rebooting just for new 
> > > > keys is not an option either.
> > > > Could dropbear gain automatic reread of keys ?
> > > 
> > > You know if you kill the parent process the child processes keep
> > > running? So you can restart it without disconnecting everyone.
> > 
> > Yes, but in our case dropbear start/stop script is connected with several 
> > other daemons, but yes it can be
> > worked around.
> > 
> > The bigger issue here is why not reread keys at every new session? That 
> > seems to like the
> > right thing to do in any case? 
> > 
> >  Jocke
> > 



Re: dropbear and new host keys?

2019-12-19 Thread Joakim Tjernlund
On Mon, 2019-12-16 at 22:16 +0800, Matt Johnston wrote:
> 
> > On Fri 13/12/2019, at 2:14 am, Joakim Tjernlund 
> >  wrote:
> > 
> > On Thu, 2019-12-12 at 18:34 +0100, Hans Harder wrote:
> > > >  The bigger issue here is why not reread keys at every new session? 
> > > > That seems to like the right thing to do in any case?
> > > 
> > > Performance...
> 
> I don't _think_ there would be any performance problem reloading key files 
> for each session - compared with the key exchange it's not compute intensive. 
> It's better to keep it simple rather than introduce cache invalidation by 
> file timestamps where it isn't needed. I'd been considering moving non-inetd 
> dropbear to use fork/self-exec instead of plain fork() for improved address 
> space randomisation, that would probably require loading keys each time too.
> 
> That said if I were in the same situation I'd just run "kill `cat 
> /var/run/dropbear.pid; service dropbear start" or similar when writing 
> keyfiles - job done.
> 

Well, these days people wants to regen both host keys and certificates every 
now and then. I think the community would appreciate
if dropbear picked up new keys automatically without being forced to an inetd 
model. You already have an option to generate keys
on the fly(-R)

 Jocke