Skip to content

Commit a4fa57f

Browse files
author
Emma Stensland
committed
SSHD/Echoserver: Fix memory leaks and public-key lookup
1 parent 422f69d commit a4fa57f

4 files changed

Lines changed: 92 additions & 26 deletions

File tree

apps/wolfsshd/auth.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
18131813
#define WOLFSSH_USER_GET_STRING(x) #x
18141814
#define WOLFSSH_USER_STRING(x) WOLFSSH_USER_GET_STRING(x)
18151815

1816-
static int SetDefualtUserID(WOLFSSHD_AUTH* auth)
1816+
static int SetDefaultUserID(WOLFSSHD_AUTH* auth)
18171817
{
18181818
#ifdef _WIN32
18191819
/* TODO: Implement for Windows. */
@@ -1822,6 +1822,11 @@ static int SetDefualtUserID(WOLFSSHD_AUTH* auth)
18221822
struct passwd* pwInfo;
18231823
int ret = WS_SUCCESS;
18241824

1825+
if (wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf) ==
1826+
WOLFSSHD_PRIV_OFF) {
1827+
return WS_SUCCESS;
1828+
}
1829+
18251830
pwInfo = getpwnam(WOLFSSH_USER_STRING(WOLFSSH_SSHD_USER));
18261831
if (pwInfo == NULL) {
18271832
/* user name not found on system */
@@ -1882,7 +1887,7 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
18821887
}
18831888

18841889
if (ret == WS_SUCCESS) {
1885-
ret = SetDefualtUserID(auth);
1890+
ret = SetDefaultUserID(auth);
18861891
if (ret != WS_SUCCESS) {
18871892
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting default "
18881893
"user ID.");
@@ -1914,24 +1919,31 @@ int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth)
19141919
/* return WS_SUCCESS on success */
19151920
int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
19161921
{
1917-
int ret = 0;
1922+
int ret = WS_SUCCESS;
19181923

1919-
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
19201924
#ifndef WIN32
1921-
if (auth) {
1922-
if (setegid(auth->sGid) != 0) {
1923-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1924-
ret = WS_FATAL_ERROR;
1925+
{
1926+
byte flag = 0;
1927+
1928+
if (auth == NULL) {
1929+
return WS_BAD_ARGUMENT;
19251930
}
19261931

1927-
if (seteuid(auth->sUid) != 0) {
1928-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1929-
ret = WS_FATAL_ERROR;
1932+
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
1933+
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
1934+
wolfSSH_Log(WS_LOG_INFO,
1935+
"[SSHD] Attempting to raise permissions level");
1936+
if (setegid(auth->sGid) != 0) {
1937+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1938+
ret = WS_FATAL_ERROR;
1939+
}
1940+
1941+
if (ret == WS_SUCCESS && seteuid(auth->sUid) != 0) {
1942+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1943+
ret = WS_FATAL_ERROR;
1944+
}
19301945
}
19311946
}
1932-
else {
1933-
ret = WS_BAD_ARGUMENT;
1934-
}
19351947
#endif
19361948

19371949
return ret;

examples/echoserver/echoserver.c

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,6 @@ static int load_key(byte isEcc, byte* buf, word32 bufSz)
17851785
return sz;
17861786
}
17871787

1788-
17891788
#ifndef WOLFSSH_NO_ED25519
17901789
/* returns buffer size on success */
17911790
static int load_key_ed25519(byte* buf, word32 bufSz)
@@ -1806,6 +1805,7 @@ static int load_key_ed25519(byte* buf, word32 bufSz)
18061805
#endif /* WOLFSSH_NO_ED25519 */
18071806

18081807

1808+
18091809
typedef struct StrList {
18101810
const char* str;
18111811
struct StrList* next;
@@ -2358,7 +2358,7 @@ static int EchoserverInitTpmHostKey(WOLFSSH_CTX* ctx, const char* keyFile,
23582358
wolfTPM2_Cleanup(&tpmHostDev);
23592359
}
23602360

2361-
/* keyBlob holds the private blob and key auth; the session may hold auth. */
2361+
/* zeroize key material; session may also hold auth data */
23622362
wc_ForceZero(&keyBlob, sizeof(keyBlob));
23632363
wc_ForceZero(&tpmSession, sizeof(tpmSession));
23642364
#ifndef NO_FILESYSTEM
@@ -2439,6 +2439,7 @@ static int wsUserAuth(byte authType,
24392439
PwMapList* list;
24402440
PwMap* map;
24412441
byte authHash[WC_SHA256_DIGEST_SIZE] = {0};
2442+
int userFound = 0;
24422443

24432444
if (ctx == NULL) {
24442445
fprintf(stderr, "wsUserAuth: ctx not set");
@@ -2559,12 +2560,12 @@ static int wsUserAuth(byte authType,
25592560
authData->type == map->type) {
25602561

25612562
if (authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
2563+
userFound = 1;
25622564
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
25632565
return WOLFSSH_USERAUTH_SUCCESS;
25642566
}
2565-
else {
2566-
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
2567-
}
2567+
/* Hash mismatch: continue checking other registered keys
2568+
* for this user (a user may have multiple public keys). */
25682569
}
25692570
else if (authData->type == WOLFSSH_USERAUTH_PASSWORD) {
25702571
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
@@ -2607,6 +2608,8 @@ static int wsUserAuth(byte authType,
26072608
map = map->next;
26082609
}
26092610

2611+
if (userFound)
2612+
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
26102613
return WOLFSSH_USERAUTH_INVALID_USER;
26112614
}
26122615

@@ -2690,7 +2693,8 @@ static void ShowUsage(void)
26902693
" load in a SSH public key to accept from peer\n");
26912694
printf(" -s <file> load in a TPM public key file to replace default hansel key\n");
26922695
#ifdef WOLFSSH_TPM
2693-
printf(" -G <file> load an ECC/RSA host key blob from the TPM (private key stays in the TPM)\n");
2696+
printf(" -G <file> load ECC/RSA host key blob from TPM"
2697+
" (private key stays in TPM)\n");
26942698
#endif
26952699
printf(" -J <name>:<file>\n"
26962700
" load in an X.509 PEM cert to accept from peer\n");
@@ -3096,14 +3100,17 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
30963100
if (kbAuthData.prompts == NULL) {
30973101
ES_ERROR("Error allocating prompts");
30983102
}
3099-
kbAuthData.prompts[0] = (byte*)"KB Auth Password: ";
31003103
kbAuthData.promptLengths = (word32*)WMALLOC(sizeof(word32), NULL, 0);
3101-
if (kbAuthData.prompts == NULL) {
3104+
if (kbAuthData.promptLengths == NULL) {
3105+
WFREE(kbAuthData.prompts, NULL, 0);
31023106
ES_ERROR("Error allocating promptLengths");
31033107
}
3108+
kbAuthData.prompts[0] = (byte*)"KB Auth Password: ";
31043109
kbAuthData.promptLengths[0] = 18;
31053110
kbAuthData.promptEcho = (byte*)WMALLOC(sizeof(byte), NULL, 0);
3106-
if (kbAuthData.prompts == NULL) {
3111+
if (kbAuthData.promptEcho == NULL) {
3112+
WFREE(kbAuthData.prompts, NULL, 0);
3113+
WFREE(kbAuthData.promptLengths, NULL, 0);
31073114
ES_ERROR("Error allocating promptEcho");
31083115
}
31093116
kbAuthData.promptEcho[0] = 0;
@@ -3137,7 +3144,8 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31373144
if (tpmHostKeyPath != NULL) {
31383145
if (EchoserverInitTpmHostKey(ctx, tpmHostKeyPath,
31393146
ECHOSERVER_TPM_KEY_AUTH_DEFAULT) != 0) {
3140-
ES_ERROR("Couldn't load TPM host key from %s.\n", tpmHostKeyPath);
3147+
ES_ERROR("Couldn't load TPM host key from %s.\n",
3148+
tpmHostKeyPath);
31413149
}
31423150
loadDefaultHostKeys = 0;
31433151
}
@@ -3146,10 +3154,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31463154
if (loadDefaultHostKeys) {
31473155
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
31483156
if (bufSz == 0) {
3157+
#ifdef WOLFSSH_SMALL_STACK
3158+
WFREE(keyLoadBuf, NULL, 0);
3159+
#endif
31493160
ES_ERROR("Couldn't load first key file.\n");
31503161
}
31513162
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
31523163
WOLFSSH_FORMAT_ASN1) < 0) {
3164+
#ifdef WOLFSSH_SMALL_STACK
3165+
WFREE(keyLoadBuf, NULL, 0);
3166+
#endif
31533167
ES_ERROR("Couldn't use first key buffer.\n");
31543168
}
31553169

@@ -3159,10 +3173,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31593173

31603174
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
31613175
if (bufSz == 0) {
3176+
#ifdef WOLFSSH_SMALL_STACK
3177+
WFREE(keyLoadBuf, NULL, 0);
3178+
#endif
31623179
ES_ERROR("Couldn't load second key file.\n");
31633180
}
31643181
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
31653182
WOLFSSH_FORMAT_ASN1) < 0) {
3183+
#ifdef WOLFSSH_SMALL_STACK
3184+
WFREE(keyLoadBuf, NULL, 0);
3185+
#endif
31663186
ES_ERROR("Couldn't use second key buffer.\n");
31673187
}
31683188
#endif
@@ -3171,10 +3191,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31713191
bufSz = EXAMPLE_KEYLOAD_BUFFER_SZ;
31723192
bufSz = load_key_ed25519(keyLoadBuf, bufSz);
31733193
if (bufSz == 0) {
3194+
#ifdef WOLFSSH_SMALL_STACK
3195+
WFREE(keyLoadBuf, NULL, 0);
3196+
#endif
31743197
ES_ERROR("Couldn't load Ed25519 key file.\n");
31753198
}
31763199
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
31773200
WOLFSSH_FORMAT_ASN1) < 0) {
3201+
#ifdef WOLFSSH_SMALL_STACK
3202+
WFREE(keyLoadBuf, NULL, 0);
3203+
#endif
31783204
ES_ERROR("Couldn't use Ed25519 key buffer.\n");
31793205
}
31803206
#endif /* WOLFSSH_NO_ED25519 */
@@ -3190,11 +3216,17 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31903216

31913217
/* create temp buffer and load in file */
31923218
if (userBufSz == 0) {
3219+
#ifdef WOLFSSH_SMALL_STACK
3220+
WFREE(keyLoadBuf, NULL, 0);
3221+
#endif
31933222
ES_ERROR("Couldn't find size of file %s.\n", userPubKey);
31943223
}
31953224

31963225
userBuf = (byte*)WMALLOC(userBufSz, NULL, 0);
31973226
if (userBuf == NULL) {
3227+
#ifdef WOLFSSH_SMALL_STACK
3228+
WFREE(keyLoadBuf, NULL, 0);
3229+
#endif
31983230
ES_ERROR("WMALLOC failed\n");
31993231
}
32003232
load_file(userPubKey, userBuf, &userBufSz);
@@ -3212,17 +3244,26 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
32123244
load_file(caCert, NULL, &certBufSz);
32133245

32143246
if (certBufSz == 0) {
3247+
#ifdef WOLFSSH_SMALL_STACK
3248+
WFREE(keyLoadBuf, NULL, 0);
3249+
#endif
32153250
ES_ERROR("Couldn't find size of file %s.\n", caCert);
32163251
}
32173252

32183253
certBuf = (byte*)WMALLOC(certBufSz, NULL, 0);
32193254
if (certBuf == NULL) {
3255+
#ifdef WOLFSSH_SMALL_STACK
3256+
WFREE(keyLoadBuf, NULL, 0);
3257+
#endif
32203258
ES_ERROR("WMALLOC failed\n");
32213259
}
32223260
load_file(caCert, certBuf, &certBufSz);
32233261
ret = wolfSSH_CTX_AddRootCert_buffer(ctx, certBuf, certBufSz,
32243262
WOLFSSH_FORMAT_PEM);
32253263
if (ret != 0) {
3264+
#ifdef WOLFSSH_SMALL_STACK
3265+
WFREE(keyLoadBuf, NULL, 0);
3266+
#endif
32263267
ES_ERROR("Couldn't add root cert\n");
32273268
}
32283269
WFREE(certBuf, NULL, 0);

src/internal.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13520,14 +13520,24 @@ int SendKexDhReply(WOLFSSH* ssh)
1352013520
}
1352113521

1352213522
if (sigKeyBlock_ptr != NULL) {
13523-
if (sigKeyBlock_ptr->pubKeyFmtId == ID_SSH_RSA) {
13523+
if (sigKeyBlock_ptr->pubKeyFmtId == ID_SSH_RSA
13524+
#ifdef WOLFSSH_CERTS
13525+
|| sigKeyBlock_ptr->pubKeyFmtId == ID_X509V3_SSH_RSA
13526+
#endif
13527+
) {
1352413528
#ifndef WOLFSSH_NO_RSA
1352513529
wc_FreeRsaKey(&sigKeyBlock_ptr->sk.rsa.key);
1352613530
#endif
1352713531
}
1352813532
else if (sigKeyBlock_ptr->pubKeyFmtId == ID_ECDSA_SHA2_NISTP256
1352913533
|| sigKeyBlock_ptr->pubKeyFmtId == ID_ECDSA_SHA2_NISTP384
13530-
|| sigKeyBlock_ptr->pubKeyFmtId == ID_ECDSA_SHA2_NISTP521) {
13534+
|| sigKeyBlock_ptr->pubKeyFmtId == ID_ECDSA_SHA2_NISTP521
13535+
#ifdef WOLFSSH_CERTS
13536+
|| sigKeyBlock_ptr->pubKeyFmtId == ID_X509V3_ECDSA_SHA2_NISTP256
13537+
|| sigKeyBlock_ptr->pubKeyFmtId == ID_X509V3_ECDSA_SHA2_NISTP384
13538+
|| sigKeyBlock_ptr->pubKeyFmtId == ID_X509V3_ECDSA_SHA2_NISTP521
13539+
#endif
13540+
) {
1353113541
#ifndef WOLFSSH_NO_ECDSA
1353213542
wc_ecc_free(&sigKeyBlock_ptr->sk.ecc.key);
1353313543
#endif

tests/auth.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,11 +1602,14 @@ static THREAD_RETURN WOLFSSH_THREAD server_thread(void* args)
16021602
promptData.promptLengths =
16031603
(word32*)WMALLOC(sizeof(word32) * kbResponseCount, NULL, 0);
16041604
if (promptData.promptLengths == NULL) {
1605+
WFREE(promptData.prompts, NULL, 0);
16051606
ES_ERROR("Could not allocate promptLengths");
16061607
}
16071608
promptData.promptEcho =
16081609
(byte*)WMALLOC(sizeof(byte) * kbResponseCount, NULL, 0);
16091610
if (promptData.promptEcho == NULL) {
1611+
WFREE(promptData.prompts, NULL, 0);
1612+
WFREE(promptData.promptLengths, NULL, 0);
16101613
ES_ERROR("Could not allocate promptEcho");
16111614
}
16121615
for (word32 prompt = 0; prompt < kbResponseCount; prompt++) {

0 commit comments

Comments
 (0)