Merge pull request #9 from ejohnstown/fix-userauth

Fix User Auth
pull/11/head
JacobBarthelmeh 2016-07-14 20:00:55 -06:00 committed by GitHub
commit 20d97b299e
7 changed files with 83 additions and 32 deletions

View File

@ -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`.

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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
};

View File

@ -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,

View File

@ -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