mirror of https://github.com/wolfSSL/wolfssh.git
commit
20d97b299e
|
|
@ -41,6 +41,12 @@ If the characters are echoed twice, the client has local echo enabled.
|
|||
testing notes
|
||||
-------------
|
||||
|
||||
After cloning the repository, be sure to make the testing private keys read-
|
||||
only for the user, otherwise ssh_client will tell you to do it.
|
||||
|
||||
$ chmod 0600 ./certs/key-gretel.pem ./certs/key-hansel.pem \
|
||||
./certs/key-ecc.pem
|
||||
|
||||
Authentication against the example echoserver can be done with a password or
|
||||
public key. To use a password the command line:
|
||||
|
||||
|
|
@ -53,7 +59,7 @@ Where the `USER` and password pairs are:
|
|||
|
||||
To use public key authentication use the command line:
|
||||
|
||||
$ ssh_client -l ./certs/key-USER.pem -p 22222 USER@localhost
|
||||
$ ssh_client -i ./certs/key-USER.pem -p 22222 USER@localhost
|
||||
|
||||
Where the user can be `gretel` or `hansel`.
|
||||
|
||||
|
|
|
|||
|
|
@ -263,8 +263,8 @@ static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs)
|
|||
WOLFSSH* ssh = (WOLFSSH*)vArgs;
|
||||
SOCKET_T clientFd = wolfSSH_get_fd(ssh);
|
||||
|
||||
uint8_t buf[4096];
|
||||
uint32_t bufSz;
|
||||
uint8_t buf[4096];
|
||||
int bufSz;
|
||||
|
||||
if (wolfSSH_accept(ssh) == WS_SUCCESS) {
|
||||
|
||||
|
|
@ -313,6 +313,8 @@ static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return fileSz;
|
||||
}
|
||||
|
||||
|
|
@ -383,6 +385,7 @@ static void PwMapListDelete(PwMapList* list)
|
|||
PwMap* cur = head;
|
||||
head = head->next;
|
||||
memset(cur, 0, sizeof(PwMap));
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -471,10 +474,12 @@ static int LoadPublicKeyBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list)
|
|||
str = delimiter + 1;
|
||||
delimiter = strchr(str, ' ');
|
||||
publicKey64 = (uint8_t*)str;
|
||||
*delimiter = 0;
|
||||
publicKey64Sz = (uint32_t)(delimiter - str);
|
||||
str = delimiter + 1;
|
||||
delimiter = strchr(str, '\n');
|
||||
username = (uint8_t*)str;
|
||||
*delimiter = 0;
|
||||
usernameSz = (uint32_t)(delimiter - str);
|
||||
str = delimiter + 1;
|
||||
publicKeySz = sizeof(publicKey);
|
||||
|
|
@ -542,16 +547,22 @@ static int wsUserAuth(uint8_t authType,
|
|||
map = list->head;
|
||||
|
||||
while (map != NULL) {
|
||||
if (authData->type == map->type &&
|
||||
authData->usernameSz == map->usernameSz &&
|
||||
if (authData->usernameSz == map->usernameSz &&
|
||||
memcmp(authData->username, map->username, map->usernameSz) == 0) {
|
||||
if (memcmp(map->p, authHash, SHA256_DIGEST_SIZE) != 0) {
|
||||
return (authType == WOLFSSH_USERAUTH_PASSWORD ?
|
||||
|
||||
if (authData->type == map->type) {
|
||||
if (memcmp(map->p, authHash, SHA256_DIGEST_SIZE) == 0) {
|
||||
return WOLFSSH_USERAUTH_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return (authType == WOLFSSH_USERAUTH_PASSWORD ?
|
||||
WOLFSSH_USERAUTH_INVALID_PASSWORD :
|
||||
WOLFSSH_USERAUTH_INVALID_PUBLICKEY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
|
||||
}
|
||||
|
||||
return WOLFSSH_USERAUTH_SUCCESS;
|
||||
}
|
||||
map = map->next;
|
||||
}
|
||||
|
|
@ -652,6 +663,7 @@ int main(void)
|
|||
}
|
||||
|
||||
PwMapListDelete(&pwMapList);
|
||||
wolfSSH_CTX_free(ctx);
|
||||
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
||||
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
|
|
@ -129,6 +129,9 @@ const char* GetErrorString(int err)
|
|||
case WS_RESOURCE_E:
|
||||
return "insufficient resources for new channel";
|
||||
|
||||
case WS_INVALID_USERNAME:
|
||||
return "invalid user name";
|
||||
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
|
|
@ -1389,20 +1392,23 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
}
|
||||
|
||||
if (ssh->ctx->userAuthCb != NULL) {
|
||||
WLOG(WS_LOG_DEBUG, "DUAR: Checking the password");
|
||||
WLOG(WS_LOG_DEBUG, "DUARPW: Calling the userauth callback");
|
||||
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PASSWORD,
|
||||
authData, ssh->userAuthCtx);
|
||||
if (ret == WS_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, "DUAR: password check successful");
|
||||
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
|
||||
WLOG(WS_LOG_DEBUG, "DUARPW: password check successful");
|
||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_DEBUG, "DUAR: password check failed");
|
||||
SendUserAuthFailure(ssh, 0);
|
||||
WLOG(WS_LOG_DEBUG, "DUARPW: password check failed");
|
||||
if (ret != WOLFSSH_USERAUTH_SUCCESS) {
|
||||
return SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_DEBUG, "DUAR: No user auth callback");
|
||||
WLOG(WS_LOG_DEBUG, "DUARPW: No user auth callback");
|
||||
return SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
|
||||
*idx = begin;
|
||||
|
|
@ -1417,14 +1423,15 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
|||
{
|
||||
RsaKey key;
|
||||
uint8_t* publicKeyType;
|
||||
uint32_t publicKeyTypeSz;
|
||||
uint32_t publicKeyTypeSz = 0;
|
||||
uint8_t* n;
|
||||
uint32_t nSz;
|
||||
uint32_t nSz = 0;
|
||||
uint8_t* e;
|
||||
uint32_t eSz;
|
||||
uint32_t eSz = 0;
|
||||
uint32_t i = 0;
|
||||
int ret;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestRsa()");
|
||||
/* First check that the public key's type matches the one we are
|
||||
* expecting. */
|
||||
GetUint32(&publicKeyTypeSz, pk->publicKey, pk->publicKeySz, &i);
|
||||
|
|
@ -1475,6 +1482,8 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
WS_UserAuthData_PublicKey* pk = &authData->sf.publicKey;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestPublicKey()");
|
||||
|
||||
authData->type = WOLFSSH_USERAUTH_PUBLICKEY;
|
||||
GetBoolean(&pk->hasSignature, buf, len, &begin);
|
||||
GetUint32(&pk->publicKeyTypeSz, buf, len, &begin);
|
||||
|
|
@ -1494,13 +1503,24 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
pk->signatureSz = 0;
|
||||
}
|
||||
|
||||
*idx = begin;
|
||||
|
||||
if (ssh->ctx->userAuthCb != NULL) {
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: Calling the userauth callback");
|
||||
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PUBLICKEY,
|
||||
authData, ssh->userAuthCtx);
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: callback result = %d", ret);
|
||||
if (ret != WOLFSSH_USERAUTH_SUCCESS) {
|
||||
return SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: no userauth callback set");
|
||||
return SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
|
||||
if (pk->signature == NULL) {
|
||||
WLOG(WS_LOG_DEBUG, "DUAR: Send the PK OK");
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: Send the PK OK");
|
||||
ret = SendUserAuthPkOk(ssh, pk->publicKeyType, pk->publicKeyTypeSz,
|
||||
pk->publicKey, pk->publicKeySz);
|
||||
}
|
||||
|
|
@ -1555,8 +1575,8 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
sizeCompare = encDigestSz != checkDigestSz;
|
||||
|
||||
if (compare || sizeCompare || ret < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "signature compare failure");
|
||||
SendUserAuthFailure(ssh, 0);
|
||||
WLOG(WS_LOG_DEBUG, "DUARPK: signature compare failure");
|
||||
return SendUserAuthFailure(ssh, 0);
|
||||
}
|
||||
else {
|
||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||
|
|
@ -1564,8 +1584,6 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
}
|
||||
}
|
||||
|
||||
*idx = begin;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1578,6 +1596,8 @@ static int DoUserAuthRequest(WOLFSSH* ssh,
|
|||
uint8_t authNameId;
|
||||
WS_UserAuthData authData;
|
||||
|
||||
WMEMSET(&authData, 0, sizeof(authData));
|
||||
|
||||
GetUint32(&authData.usernameSz, buf, len, &begin);
|
||||
authData.username = buf + begin;
|
||||
begin += authData.usernameSz;
|
||||
|
|
@ -2147,12 +2167,17 @@ int ProcessReply(WOLFSSH* ssh)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = Decrypt(ssh,
|
||||
ssh->inputBuffer.buffer +
|
||||
ssh->inputBuffer.idx + peerBlockSz,
|
||||
ssh->inputBuffer.buffer +
|
||||
ssh->inputBuffer.idx + peerBlockSz,
|
||||
ssh->curSz + LENGTH_SZ - peerBlockSz);
|
||||
if (ssh->curSz + LENGTH_SZ - peerBlockSz > 0) {
|
||||
ret = Decrypt(ssh,
|
||||
ssh->inputBuffer.buffer +
|
||||
ssh->inputBuffer.idx + peerBlockSz,
|
||||
ssh->inputBuffer.buffer +
|
||||
ssh->inputBuffer.idx + peerBlockSz,
|
||||
ssh->curSz + LENGTH_SZ - peerBlockSz);
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_INFO, "Not trying to decrypt short message.");
|
||||
}
|
||||
|
||||
/* Verify the buffer is big enough for the data and mac.
|
||||
* Even if the decrypt step fails, verify the MAC anyway.
|
||||
|
|
@ -2860,7 +2885,7 @@ int SendServiceAccept(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
static const char cannedAuths[] = "publickey";
|
||||
static const char cannedAuths[] = "publickey,password";
|
||||
static const uint32_t cannedAuthsSz = sizeof(cannedAuths) - 1;
|
||||
|
||||
|
||||
|
|
@ -3082,6 +3107,7 @@ int SendChannelData(WOLFSSH* ssh, uint32_t peerChannel,
|
|||
|
||||
if (channel->peerWindowSz < dataSz) {
|
||||
WLOG(WS_LOG_DEBUG, "Peer window too small");
|
||||
return WS_OVERFLOW_E;
|
||||
}
|
||||
|
||||
ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + LENGTH_SZ + dataSz);
|
||||
|
|
|
|||
|
|
@ -225,12 +225,16 @@ static void SshResourceFree(WOLFSSH* ssh, void* heap)
|
|||
WFREE(ssh->handshake, heap, DYNTYPE_HS);
|
||||
}
|
||||
if (ssh->rng) {
|
||||
/* FreeRng(ssh->rng); */
|
||||
wc_FreeRng(ssh->rng);
|
||||
WFREE(ssh->rng, heap, DYNTYPE_RNG);
|
||||
}
|
||||
if (ssh->userName) {
|
||||
WFREE(ssh->userName, heap, DYNTYPE_STRING);
|
||||
}
|
||||
if (ssh->channel.inputBuffer.buffer) {
|
||||
WFREE(ssh->channel.inputBuffer.buffer,
|
||||
ssh->channel.inputBuffer.heap, DYNTYPE_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ enum WS_ErrorCodes {
|
|||
WS_CREATE_MAC_E = -24,
|
||||
WS_RESOURCE_E = -25, /* insufficient resources for new channel */
|
||||
WS_INVALID_CHANTYPE = -26, /* invalid channel type */
|
||||
WS_INVALID_USERNAME = -28
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -348,7 +348,8 @@ enum WS_MessageIds {
|
|||
MSGID_USERAUTH_FAILURE = 51,
|
||||
MSGID_USERAUTH_SUCCESS = 52,
|
||||
MSGID_USERAUTH_BANNER = 53,
|
||||
MSGID_USERAUTH_PK_OK = 60,
|
||||
MSGID_USERAUTH_PK_OK = 60, /* Public Key OK */
|
||||
MSGID_USERAUTH_PW_CHRQ = 60, /* Password Change Request */
|
||||
|
||||
MSGID_CHANNEL_OPEN = 90,
|
||||
MSGID_CHANNEL_OPEN_CONF = 91,
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ enum WS_UserAuthTypes {
|
|||
enum WS_UserAuthResults {
|
||||
WOLFSSH_USERAUTH_SUCCESS,
|
||||
WOLFSSH_USERAUTH_FAILURE,
|
||||
WOLFSSH_USERAUTH_INVALID_AUTHTYPE,
|
||||
WOLFSSH_USERAUTH_INVALID_USER,
|
||||
WOLFSSH_USERAUTH_INVALID_PASSWORD,
|
||||
WOLFSSH_USERAUTH_INVALID_PUBLICKEY
|
||||
|
|
|
|||
Loading…
Reference in New Issue