Password Handling
YANG Extensions Affecting Passwords
The YANG extension ncx:password can be used in a YANG module (leaf definition) to identify password fields.
The "obj_is_password" function will be true for these objects, and any object that uses the “crypt-hash” typedef from the iana-crypt-hash.yang module.
Note
The "ncx:password" extension is deprecated and should not be used. It does not prevent disclosure of passwords in all cases. Use the "crypt-hash" data type instead.
The OpenConfig YANG extension oc-ext:openconfig-hashed-value can be used in a YANG module (leaf definition) to identify a password field with strict requirements for non-disclosure.
The initial cleartext password string is converted to a hash right away and only the hash is stored or displayed after that.
This extension should be used instead of "ncx:password" if the "crypt-hash" data type cannot be used.
Passwords and crypt-hash
Objects that are type “crypt-hash” will be processed by the server according to the following typedef from iana-crypt-hash.yang:
typedef crypt-hash {
type string {
pattern
'$0$.*'
+ '|$1$[a-zA-Z0-9./]{1,8}$[a-zA-Z0-9./]{22}'
+ '|$5$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{43}'
+ '|$6$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{86}';
}
description
"The crypt-hash type is used to store passwords using
a hash function. The algorithms for applying the hash
function and encoding the result are implemented in
various UNIX systems as the function crypt(3).
A value of this type matches one of the forms:
$0$<clear text password>
$<id>$<salt>$<password hash>
$<id>$<parameter>$<salt>$<password hash>
The '$0$' prefix signals that the value is clear text. When
such a value is received by the server, a hash value is
calculated, and the string '$<id>$<salt>$' or
$<id>$<parameter>$<salt>$ is prepended to the result. This
value is stored in the configuration data store.
If a value starting with '$<id>$', where <id> is not '0', is
received, the server knows that the value already represents a
hashed value and stores it 'as is' in the data store.
When a server needs to verify a password given by a user, it
finds the stored password hash string for that user, extracts
the salt, and calculates the hash with the salt and given
password as input. If the calculated hash value is the same
as the stored value, the password given by the client is
accepted.
This type defines the following hash functions:
id | hash function | feature
---+---------------+-------------------
1 | MD5 | crypt-hash-md5
5 | SHA-256 | crypt-hash-sha-256
6 | SHA-512 | crypt-hash-sha-512
The server indicates support for the different hash functions
by advertising the corresponding feature.";
reference
"IEEE Std 1003.1-2008 - crypt() function
RFC 1321: The MD5 Message-Digest Algorithm
FIPS.180-4.2012: Secure Hash Standard (SHS)";
}
Values of this datatype that match the “$0$” format will be converted and stored as a hash, according to the typedef specification.
The agt_profile field "agt_min_password_len" field will be used to enforce a minimum password length for the crypt-hash data type. The default value is 8.
The agt_profile field "agt_crypt_hash_prefix" field will be used to select the hash function that will be used for the conversion of $0$ format strings. The default value is SHA-512 ($6$).
The obj_is_password() function will be true for any crypt-hash data node
Password Storage
The "crypt-hash" data type must be used (with mode 5 or 6) to avoid exposure of a cleartext password by the client in the initial password configuration edit request.
Otherwise, the "crypt-hash" data type (mode 0) or the "openconfig-hashed-value" extension should be used.
Passwords Stored in YANG Data
Server Password Management Behavior
Any cleartext password is converted to a hashed value as soon as possible.
The cleartext password is not exposed in any debug traces within a production build (PRODUCTION=1).
The cleartext password can only be exposed in initial input buffer debug traces within a debug build (DEBUG=1).
For NETCONF over TLS, DEBUG_LOG_TLS=1 is also required for input buffer tracing.
NETCONF over TLS log tracing is not available in binary-only packages.
The cleartext password is not saved in memory or disk by the server.
The cleartext password is not available to SIL or SIL-SA code.
The server uses the standard "crypt-hash" format and the C library functions "crypt" and "crypt_r" to store and validate password hashes.
IANA crypt-hash Data Type
The iana-crypt-hash.yang module contains the "crypt-hash" data type, which is the preferred method for setting passwords through YANG.
Either a cleartext or a hashed value can be passed by the client:
Cleartext value: "$0$" prefix (example: "$0$thisisatest")
Hashed value: "$<id>$<salt>$<hash>" (or "$<id>$<params>$<salt>$<hash>")
Example YANG usage (ietf-system.yang):
leaf password {
type ianach:crypt-hash;
description
"The password for this entry.";
}
YANG Extension oc-ext:openconfig-hashed-value
The OpenConfig extension oc-ext:openconfig-hashed-value marks a leaf or leaf-list as a special password field:
Client input is a cleartext password string (not "$0$" crypt-hash format).
The server hashes the value immediately.
The server stores and returns only the hashed value.
Example YANG usage (openconfig-aaa.yang):
leaf admin-password {
type string;
oc-ext:openconfig-hashed-value;
description
"The admin/root password, supplied as a cleartext string.
The system should hash and only store the password as a
hashed value.";
}
For a complete description and examples, see oc-ext:openconfig-hashed-value.
Checking a Password with crypt or crypt_r
Basic procedure:
Extract the salt prefix from the saved hash string.
Run "crypt" or "crypt_r" with the offered cleartext password and extracted salt.
Compare the result with the saved hash string.
Notes:
The GNU C Library is required to use the functions in crypt.h.
If UCLINUX=1 is used, GNU libc is not available in the server.
Use "crypt" for a single-threaded server.
Use "crypt_r" if PTHREADS=1 is used to build the server.
Example: test-ochash.yang
module test-ochash {
yang-version 1.1;
namespace "http://netconfcentral.org/ns/test-ochash";
prefix toch;
import openconfig-extensions { prefix oc-ext; }
revision 2021-02-26;
container octop {
leaf ochash {
type string;
oc-ext:openconfig-hashed-value;
}
}
}
In this example the SIL code for the /octop/ochash leaf will save the hashed password somewhere in the system. The actual configuration value can also be retrieved from the server by the SIL code.
The password saved is "thisisatest" (quotes not saved).
Saved Password
Command:
get-config source=running
Output:
rpc-reply {
data {
octop {
ochash $6$bYPSvlTU3UYq4R2d$2gUvlnTKmgxBHi1NBZBSKwJiPs6zqO7PN35Zvfin3RidwUnFDUSeJ2GgyBAmTVorv..mXgg12naL6j9Xs2njo.
}
}
}
Test Offered Password
/**
* @brief Check a plain-text password against the saved hashed value
* @param offered The plain-text password to check
* @param hashed The saved crypt-hash password string
* @return true if the offered password matches the hashed value
*/
static boolean
test_password (const char *offered,
const char *hashed)
{
int h_len = strlen(hashed);
int copy_len = 0;
/* get the salt length from the crypt-hash string */
if (!strncmp(hashed, "$1$", 3)) {
copy_len = 12; // 3 + 8 + 1
} else if (!strncmp(hashed, "$5$", 3) ||
!strncmp(hashed, "$6$", 3)) {
copy_len = 20; // 3 + 16 + 1
} else {
return false; // really an error!
}
if (h_len <= copy_len) {
return false; // really an error
}
/* extract the salt from the saved hash */
char salt[22];
*salt = 0;
(void)strncpy(salt, hashed, copy_len);
salt[copy_len] = 0;
boolean result;
#ifdef HAS_CRYPT_R
/* use the GNU re-entrant version of crypt so this will work
* OK in all PTHREADS scenarios
*/
struct crypt_data *crdata = m__getObj(struct crypt_data);
if (crdata == NULL) {
result = false; // ERR_INTERNAL_MEM
} else {
crdata->initialized = 0;
char *crypt_result = crypt_r(offered, salt, crdata);
if (crypt_result) {
result = (strcmp(crypt_result, hashed) == 0);
}
m__free(crdata);
}
#else
/* use the UNISTD non-re-entrant version of crypt
* THIS WILL NOT WORK IN PTHREADS SERVER
*/
char *crypt_result = crypt(offered, salt);
result = (strcmp(crypt_result, hashed) == 0);
#endif // HAS_CRYPT_R
return result;
}
Deprecated: ncx:password
The ncx:password extension existed before the "crypt-hash" data type and the OpenConfig extension. It should not be used.
It can cause a password value to be stored in cleartext if used in configuration data.
It only masks display in some output formats (e.g., showing four asterisks), but the actual NETCONF or RESTCONF messages may still contain the cleartext password.