On 10/30/19 6:45 AM, Martijn van Duren wrote:
> In copying over the net-snmp semantics for snmp-v3/USM I got a bit too
> lenient in handling the keys. This diff tries to rectify that.
> 
> This diff does basically two things:
> 1) Try to push people to use passphrases from stdin.
> 2) Clean up keying material (including from the ps listing) as soon as
>    possible,
> 
> $ ./snmp get -v3 -u test -l authPriv -a SHA -x AES 127.0.0.1 \
>> sysServices.0 < /home/martijn/.snmp/localhost
> sysServices.0 = INTEGER: 74
> 
> OK?
> 
> martijn@
> 
Use malloc_conceal based on shower-realisation.

Index: snmpc.c
===================================================================
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.17
diff -u -p -r1.17 snmpc.c
--- snmpc.c     26 Oct 2019 19:34:15 -0000      1.17
+++ snmpc.c     30 Oct 2019 06:16:17 -0000
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <netdb.h>
 #include <poll.h>
+#include <readpassphrase.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -43,6 +44,7 @@
 #include "usm.h"
 
 #define GETOPT_COMMON          "A:a:c:E:e:K:k:l:n:O:r:t:u:v:X:x:Z:"
+#define PWLEN                  128
 
 int snmpc_get(int, char *[]);
 int snmpc_walk(int, char *[]);
@@ -122,9 +124,19 @@ main(int argc, char *argv[])
        char *strtolp;
        int ch;
        size_t i;
+       char *passphrase = NULL;
+       int pwdflags = 0;
 
-       if (pledge("stdio inet dns", NULL) == -1)
-               err(1, "pledge");
+       if (isatty(STDIN_FILENO)) {
+               if (unveil("/dev/tty", "rw") == -1)
+                       err(1, "unveil");
+               if (pledge("stdio inet dns rpath wpath tty", NULL) == -1)
+                       err(1, "pledge");
+       } else {
+               if (pledge("stdio inet dns", NULL) == -1)
+                       err(1, "pledge");
+               pwdflags = RPP_STDIN;
+       }
 
        if (argc <= 1)
                usage();
@@ -161,6 +173,7 @@ main(int argc, char *argv[])
                        authkey = optarg;
                        authkeylen = strlen(authkey);
                        authkeylevel = USM_KEY_PASSWORD;
+                       warnx("Use of -A is deprecated");
                        break;
                case 'a':
                        if (strcasecmp(optarg, "MD5") == 0)
@@ -211,7 +224,8 @@ main(int argc, char *argv[])
                                errx(1, "-3K");
                        }
                        privkeylevel = USM_KEY_LOCALIZED;
-                               break;
+                       warnx("Use of -K is deprecated");
+                       break;
                case 'k':
                        authkey = snmpc_hex2bin(optarg, &authkeylen);
                        if (authkey == NULL) {
@@ -220,6 +234,7 @@ main(int argc, char *argv[])
                                err(1, "-k");
                        }
                        authkeylevel = USM_KEY_LOCALIZED;
+                       warnx("Use of -k is deprecated");
                        break;
                case 'l':
                        if (strcasecmp(optarg, "noAuthNoPriv") == 0)
@@ -395,6 +410,7 @@ main(int argc, char *argv[])
                        privkey = optarg;
                        privkeylen = strlen(privkey);
                        privkeylevel = USM_KEY_PASSWORD;
+                       warnx("Use of -X is deprecated");
                        break;
                case 'x':
                        if (strcasecmp(optarg, "DES") == 0)
@@ -434,21 +450,46 @@ main(int argc, char *argv[])
                if (seclevel & SNMP_MSGFLAG_AUTH) {
                        if (md == NULL)
                                md = EVP_md5();
-                       if (authkey == NULL)
-                               errx(1, "No authKey or authPassword specified");
+                       if (authkey == NULL) {
+                               if ((passphrase =
+                                   malloc_conceal(PWLEN)) == NULL)
+                                       err(1 , NULL);
+                               if ((authkey = readpassphrase("\rAuthpass: ",
+                                   passphrase, PWLEN, pwdflags)) == NULL)
+                                       err(1, "Couldn't read Authpass");
+                               authkeylen = strlen(authkey);
+                               authkeylevel = USM_KEY_PASSWORD;
+                       }
                        if (usm_setauth(sec, md, authkey, authkeylen,
-                           authkeylevel) == -1)
+                           authkeylevel) == -1) {
+                               explicit_bzero(authkey, authkeylen);
                                err(1, "Can't set authkey");
+                       }
+                       explicit_bzero(authkey, authkeylen);
                }
                if (seclevel & SNMP_MSGFLAG_PRIV) {
                        if (cipher == NULL)
                                cipher = EVP_des_cbc();
-                       if (privkey == NULL)
-                               errx(1, "No privKey or privPassword specified");
+                       if (privkey == NULL) {
+                               if (passphrase == NULL) {
+                                       if ((passphrase =
+                                           malloc_conceal(PWLEN)) == NULL)
+                                               err(1, NULL);
+                               }
+                               if ((privkey = readpassphrase("\rPrivpass: ",
+                                   passphrase, PWLEN, pwdflags)) == NULL)
+                                       err(1, "Couldn't read Privpass");
+                               privkeylen = strlen(privkey);
+                               privkeylevel = USM_KEY_PASSWORD;
+                       }
                        if (usm_setpriv(sec, cipher, privkey, privkeylen,
-                           privkeylevel) == -1)
+                           privkeylevel) == -1) {
+                               explicit_bzero(privkey, privkeylen);
                                err(1, "Can't set authkey");
+                       }
+                       explicit_bzero(privkey, privkeylen);
                }
+               free(passphrase);
                if (secengineid != NULL) {
                        if (usm_setengineid(sec, secengineid,
                            secengineidlen) == -1)
Index: usm.c
===================================================================
RCS file: /cvs/src/usr.bin/snmp/usm.c,v
retrieving revision 1.5
diff -u -p -r1.5 usm.c
--- usm.c       24 Oct 2019 12:39:26 -0000      1.5
+++ usm.c       30 Oct 2019 06:16:17 -0000
@@ -44,9 +44,11 @@ struct usm_sec {
        enum usm_key_level authlevel;
        const EVP_MD *digest;
        char *authkey;
+       size_t authkeylen;
        enum usm_key_level privlevel;
        const EVP_CIPHER *cipher;
        char *privkey;
+       size_t privkeylen;
        int bootsset;
        uint32_t boots;
        int timeset;
@@ -319,7 +321,7 @@ usm_finalparams(struct snmp_agent *agent
        if (usm->authlevel != USM_KEY_LOCALIZED)
                return -1;
 
-       if (HMAC(usm->digest, usm->authkey, EVP_MD_size(usm->digest), buf,
+       if (HMAC(usm->digest, usm->authkey, usm->authkeylen, buf,
            buflen, digest, NULL) == NULL)
                return -1;
 
@@ -427,7 +429,7 @@ usm_parseparams(struct snmp_agent *agent
        }
        if ((agent->v3->level & SNMP_MSGFLAG_AUTH)) {
                bzero(packet + secparamsoffset + digestoffset, digestlen);
-               if (HMAC(usm->digest, usm->authkey, EVP_MD_size(usm->digest), 
packet,
+               if (HMAC(usm->digest, usm->authkey, usm->authkeylen, packet,
                    packetlen, exp_digest, NULL) == NULL)
                        goto fail;
 
@@ -507,16 +509,17 @@ usm_setauth(struct snmp_sec *sec, const 
                if ((usm->authkey = usm_passwd2mkey(digest, key)) == NULL)
                        return -1;
                level = USM_KEY_MASTER;
-               keylen = EVP_MD_size(digest);
+               usm->authkeylen = EVP_MD_size(digest);
        } else {
                if (keylen != (size_t)EVP_MD_size(digest)) {
                        errno = EINVAL;
                        return -1;
                }
-               if ((lkey = malloc(keylen)) == NULL)
+               if ((lkey = malloc_conceal(keylen)) == NULL)
                        return -1;
                memcpy(lkey, key, keylen);
                usm->authkey = lkey;
+               usm->authkeylen = keylen;
        }
        usm->digest = digest;
        usm->authlevel = level;
@@ -544,16 +547,17 @@ usm_setpriv(struct snmp_sec *sec, const 
                if ((usm->privkey = usm_passwd2mkey(usm->digest, key)) == NULL)
                        return -1;
                level = USM_KEY_MASTER;
-               keylen = EVP_MD_size(usm->digest);
+               usm->privkeylen = EVP_MD_size(usm->digest);
        } else {
                if (keylen != (size_t)EVP_MD_size(usm->digest)) {
                        errno = EINVAL;
                        return -1;
                }
-               if ((lkey = malloc(keylen)) == NULL)
+               if ((lkey = malloc_conceal(keylen)) == NULL)
                        return -1;
                memcpy(lkey, key, keylen);
                usm->privkey = lkey;
+               usm->privkeylen = keylen;
        }
        usm->cipher = cipher;
        usm->privlevel = level;
@@ -582,6 +586,7 @@ usm_setengineid(struct snmp_sec *sec, ch
                        return -1;
                }
                free(mkey);
+               usm->authkeylen = EVP_MD_size(usm->digest);
                usm->authlevel = USM_KEY_LOCALIZED;
        }
        if (usm->privlevel == USM_KEY_MASTER) {
@@ -592,6 +597,7 @@ usm_setengineid(struct snmp_sec *sec, ch
                        return -1;
                }
                free(mkey);
+               usm->privkeylen = EVP_MD_size(usm->digest);
                usm->privlevel = USM_KEY_LOCALIZED;
        }
 
@@ -639,7 +645,7 @@ usm_passwd2mkey(const EVP_MD *md, const 
        EVP_DigestFinal_ex(&ctx, keybuf, &dlen);
        EVP_MD_CTX_cleanup(&ctx);
 
-       if ((key = malloc(dlen)) == NULL)
+       if ((key = malloc_conceal(dlen)) == NULL)
                return NULL;
        memcpy(key, keybuf, dlen);
        return key;
@@ -663,7 +669,7 @@ usm_mkey2lkey(struct usm_sec *usm, const
        EVP_DigestFinal_ex(&ctx, buf, &lklen);
        EVP_MD_CTX_cleanup(&ctx);
 
-       if ((lkey = malloc(lklen)) == NULL)
+       if ((lkey = malloc_conceal(lklen)) == NULL)
                return NULL;
        memcpy(lkey, buf, lklen);
        return lkey;

Reply via email to