mirror of https://github.com/wolfSSL/wolfssh.git
1. Flushed out the authentication callback.
2. Added public key authentication.pull/4/head
parent
a744dcc540
commit
a275ac59f0
|
@ -0,0 +1,5 @@
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MHcCAQEEIPIxGlM2XBIY6NulXIJgXdOheM+mZ7ixU8RLaXy2OoJeoAoGCCqGSM49
|
||||||
|
AwEHoUQDQgAEpalbz23q5UgbcVHU0uGllXYqEw9kAG/uyCSMfZ1wliKi6tXrs/9p
|
||||||
|
WCseyyREeyKmmMqt6WkekGJd54jHPa/Wyw==
|
||||||
|
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
||||||
|
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKWpW89t6uVIG3FR1NLhpZV2KhMPZABv7sgkjH2dcJYiourV67P/aVgrHsskRHsippjKrelpHpBiXeeIxz2v1ss= john@johnwork.local
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAqg8EVU0VZP8Iz4aKOuvjM7a3N9SrMQ2fpAFdNd/Tx0PsLLnj
|
||||||
|
aW2uozZ+aOplExDq8a89CzLAyTgTOwphtPfN5BeIESIoRAqUNK3Izj+gUn21UxPZ
|
||||||
|
nyCuSLFImRnfEqBPZEldqSdhb2XgUBDaAMRBZNM2S/bXIT0vjglBmyuEg487jWZf
|
||||||
|
99DHM7O9zdzAc4uidaD6O7BZaswennAYytiqY7rOGNa2BaYSZ1MbSrwdLPoaGmna
|
||||||
|
7m4hOe3Sugax+YmcFS00Crsd9bgiSz4YpLSN4i23ZRmRHLSZE2rH1UrFIs8FSMkY
|
||||||
|
4VSpm3SERsJFN/A9ONwEdYdJlKBgjyCrqnBTHwIDAQABAoIBADTkttRRRXZEXNkv
|
||||||
|
X480D1bmXdZfr19yfVTll7hKBfTUi4Dd0H3aP5dEO80mGonzmR/TAYmaH5x2dITI
|
||||||
|
ldtTuBZZu1iY5y1CnRZFd0+vOo5tyxgr9GQqJgs2GP6FrXx9oDPxHdCfDw83AK3m
|
||||||
|
j+ftIunZR+oYvJD6FvB2sJEy1+STBoI6znDILaJzm0sR6YCnaH05cfVTB/UyNisy
|
||||||
|
8OAIJrhB+oiH/BdWyYDhVM3E09uFt8b5+rJVqhQ+G+dFzRNsTLLAzADGWtxr3Yl6
|
||||||
|
XtHjNDE/HobMgjlH6CkXPZ5ZO3wkUPg4EuTaS1atlaxWqHqp/3OffB8rPGxg0N+n
|
||||||
|
w9NRbwECgYEA1E6AgiCVOj7fIFcznoEJSu2tcdPcCD+PopWisNWNE678ZqlUsD/4
|
||||||
|
7Fxz24RUn+1+pO4VjQ0vmDkhgM+O28gJdd1O+3loht9+h3Ie2+/EUXQudmqs7sPV
|
||||||
|
8DAuhWrnqrO6W4/nO/6MEgcXI5iJyi+uCNclMARDN1T3bh60UbcfAksCgYEAzQ6n
|
||||||
|
xGBkkAm2gItkjdIlZFVKJikSpKhLnQV5D04y/S5nw1XBdk7iL8rWIqZVYlE+7sjX
|
||||||
|
TB4gCXtFFZDTnM8fSzQU5I3ggo5NxmKq/Q4hl2aFSPEK3PMQ4Ik4jud85rluhTG8
|
||||||
|
WRtIlvbqSKTSiuPbZXD/xmS3EL8Xf+V2wbK/zf0CgYEAsvCbZZIa1KXLIBH/Ytf1
|
||||||
|
Qh8Dcg4TxSv1Xx5pqkvDhVSWTdzokUjKAEWILPvi64ybkl1M8r6rX8y/TTcjfGCk
|
||||||
|
gKAQAup4TD0xAu4PzmXO/KxEwO/2Y6PRvIiPnUnWiszDBItMZQeNfWBWg1z8vdnk
|
||||||
|
AHV9VXQyRv+pMDpW1wzV6PMCgYAnL6HH2VPeYrzJm9m/cGVM4y+kUz0I0lCA1Ubp
|
||||||
|
Mdx0naWeooix/ykiUPTS8k5m13fbUe4y0Z71sOTm1iJaWQp16KIFe0doK6GZQ8nB
|
||||||
|
Si4JLMJTyhx1VM3o2tBAHuSzgsQoF/USYjBhCRaEg1rox9ppbEq0sxJ41Mu82TD0
|
||||||
|
myAkUQKBgFboHyz32Lx4/xB0fNTyw5c4tmnvQ8B1BFInXV3+yfL6vRIVDAfj5mMn
|
||||||
|
WUNo1Hd77uHLuB3n4TzU8KwbF1vD2aACLk3p+OVRramMyv98nrl83oBMONxUh9Qb
|
||||||
|
J1NBwEkdjaqk+s+r3SSl7avVJJOViEGwGnrm0a6kACd5zxdjx0vk
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAvT92RaMDrDjVxw+TMFognIl8rQUWRoaDDYorFkoFLOR3R3AA
|
||||||
|
rh2D4tlumdTwRZgVk/aHTqxkY6GVyXww6D4vo/EknwxrHP4bApnNxqdshIVGVBJA
|
||||||
|
4bTl8qo57NYnJAvRoeLvNGklbcB0ZyWYfcT4UqubSzoSHeHj+tbPmuacI045xIQW
|
||||||
|
iD1CTtgvzNKRZ522cSoCZV+7dQ6Mu4eXl8b4spjiL2gmSlPseTqKX8zP8BZHstBD
|
||||||
|
1jZsyOcv/qc1OWn7HXhFnYkAyEHPNB+j8/H7KBT72EhvrOP8M9Hbru8nnldWKaIa
|
||||||
|
OuWa/qRJyH+3TtAfBG5YFrfrnfiSPMKwIXxOMQIDAQABAoIBAQCNpGEGL8NA9Gz0
|
||||||
|
hzC4AMzlvHWHHgaVFHoj+STUkuQavIiV/DtWFhsu/2QrWNfYjsKfsuWEubyNYVQ1
|
||||||
|
sHD+cgTAJG0vaWEGGx3mLW15YLf027dOlzbed8GfhU7Dd2lmLj5hdvNn+8aaxW+Z
|
||||||
|
/+aJQ5JEddJOVJFYskgq5voNSsrUFJ72J2e3JXpDuytn0f7RaCMGMHy/YEnezH4m
|
||||||
|
Wjv+pqbnqN2sua+CmjpBfmEhN6MI5MS8EfU7jk1R873aurLF7vvP34OhggHhUZ0H
|
||||||
|
Wl3Yx1s/lxNqTR6NOaxAlYJsoqHMipshMjpYzOctGnmkMVCxS3YjG7NAPT1ycjLs
|
||||||
|
Xzi1jbKNAoGBAO1afo6hYn0mXHjEh3HJQVd3lJOTJnjIoxW9WcsbtLJrD+eA8vr8
|
||||||
|
jjKpGx5/4SbvACXY3ckaIwAmO0YjwFDnzmKyNrKYCRY0GJ5GvK8sKJQv4F3Jssj7
|
||||||
|
XRPVNqoVD4mlFlldInSkR136+wxegL8PwpyVD+eqfxYb1Ns4fVguV3gvAoGBAMwd
|
||||||
|
f3Q2bbSSJWLFULBcodrzsv0emA2LBWlgjl7SiZBKDUZ+4lRprhbmy9W9ezAre1zu
|
||||||
|
kxLPY4mcPcgt5HphCV6A+zwDs3PWmNCEDFmfToDzRu0DndXci+ex6KpX3NFBVQfH
|
||||||
|
32c8cniwYI+FoZCZDKVnq/C2dJADVXtezMW/3qefAoGAQIFuka7UiHSrfvrSYJ80
|
||||||
|
jePm0jCUrRDCGb9rLuLpue+U0/Lclk+bCbOhtilE9ILRxHdq1yOuTXUWeNpwgsxs
|
||||||
|
76/FY8Yj+g/QfPt2fhj/Mj7MuFB/sVV3F1PD1neA0IS4TTMdkRuwdZ8nKVZpoQNU
|
||||||
|
fZ+ZQfm5LjYEJEv27MczaGsCgYBgNcs80Ob3BSggHVeCObeFB/enPcN4Jr4/RGb3
|
||||||
|
JQ/4dh85ylcOaN3JJ7KOpgip1OUKEd47MIv/cijg8VjPomuTIwLI8AmnIVDYgFV9
|
||||||
|
7QxI1eLplxnPk2xSotZDbLTF4aCd0UVpWOGwJ5rsK5XTHYELeglepfHda+TgCPhG
|
||||||
|
gcEGiwKBgAD28uslungErQ4NLqdp1lfmNjJQ0vLrrTFGZcAHl4NsZic+lCwFAV9c
|
||||||
|
4DEw7GHSdDW3nzjnjmexUAhozs/Y7oj9XcTN4oY9Sg4Ef+6K6JsWofwJguJiAzzo
|
||||||
|
JX88mqqD+NiT0VT5zrT6NTbMGFSq8pC3fJcLJy+u/MOTrxp17Bjb
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,2 @@
|
||||||
|
jill:upthehill
|
||||||
|
jack:fetchapail
|
|
@ -0,0 +1,2 @@
|
||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGhoMNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3Gp2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTjnEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPWNmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pEnIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel
|
||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqDwRVTRVk/wjPhoo66+Mztrc31KsxDZ+kAV0139PHQ+wsueNpba6jNn5o6mUTEOrxrz0LMsDJOBM7CmG0983kF4gRIihECpQ0rcjOP6BSfbVTE9mfIK5IsUiZGd8SoE9kSV2pJ2FvZeBQENoAxEFk0zZL9tchPS+OCUGbK4SDjzuNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadrubiE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdIRGwkU38D043AR1h0mUoGCPIKuqcFMf gretel
|
|
@ -33,6 +33,8 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <wolfssl/wolfcrypt/sha256.h>
|
||||||
|
#include <wolfssl/wolfcrypt/coding.h>
|
||||||
#include <wolfssh/ssh.h>
|
#include <wolfssh/ssh.h>
|
||||||
#ifndef SO_NOSIGPIPE
|
#ifndef SO_NOSIGPIPE
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -315,9 +317,253 @@ static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void c32toa(uint32_t u32, uint8_t* c)
|
||||||
|
{
|
||||||
|
c[0] = (u32 >> 24) & 0xff;
|
||||||
|
c[1] = (u32 >> 16) & 0xff;
|
||||||
|
c[2] = (u32 >> 8) & 0xff;
|
||||||
|
c[3] = u32 & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Map user names to passwords */
|
||||||
|
/* Use arrays for username and p. The password or public key can
|
||||||
|
* be hashed and the hash stored here. Then I won't need the type. */
|
||||||
|
typedef struct PwMap {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t username[32];
|
||||||
|
uint32_t usernameSz;
|
||||||
|
uint8_t p[SHA256_DIGEST_SIZE];
|
||||||
|
struct PwMap* next;
|
||||||
|
} PwMap;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PwMapList {
|
||||||
|
PwMap* head;
|
||||||
|
} PwMapList;
|
||||||
|
|
||||||
|
|
||||||
|
static PwMap* PwMapNew(PwMapList* list, uint8_t type, const uint8_t* username,
|
||||||
|
uint32_t usernameSz, const uint8_t* p, uint32_t pSz)
|
||||||
|
{
|
||||||
|
PwMap* map;
|
||||||
|
|
||||||
|
map = (PwMap*)malloc(sizeof(PwMap));
|
||||||
|
if (map != NULL) {
|
||||||
|
Sha256 sha;
|
||||||
|
uint8_t flatSz[4];
|
||||||
|
|
||||||
|
map->type = type;
|
||||||
|
if (usernameSz >= sizeof(map->username))
|
||||||
|
usernameSz = sizeof(map->username) - 1;
|
||||||
|
memcpy(map->username, username, usernameSz + 1);
|
||||||
|
map->username[usernameSz] = 0;
|
||||||
|
map->usernameSz = usernameSz;
|
||||||
|
|
||||||
|
wc_InitSha256(&sha);
|
||||||
|
c32toa(pSz, flatSz);
|
||||||
|
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||||
|
wc_Sha256Update(&sha, p, pSz);
|
||||||
|
wc_Sha256Final(&sha, map->p);
|
||||||
|
|
||||||
|
map->next = list->head;
|
||||||
|
list->head = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PwMapListDelete(PwMapList* list)
|
||||||
|
{
|
||||||
|
if (list != NULL) {
|
||||||
|
PwMap* head = list->head;
|
||||||
|
|
||||||
|
while (head != NULL) {
|
||||||
|
PwMap* cur = head;
|
||||||
|
head = head->next;
|
||||||
|
memset(cur, 0, sizeof(PwMap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char samplePasswordBuffer[] =
|
||||||
|
"jill:upthehill\n"
|
||||||
|
"jack:fetchapail\n";
|
||||||
|
|
||||||
|
|
||||||
|
static const char samplePublicKeyBuffer[] =
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
|
||||||
|
"MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G"
|
||||||
|
"p2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTj"
|
||||||
|
"nEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPW"
|
||||||
|
"NmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pE"
|
||||||
|
"nIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel\n"
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqDwRVTRVk/wjPhoo66+Mztrc31KsxDZ"
|
||||||
|
"+kAV0139PHQ+wsueNpba6jNn5o6mUTEOrxrz0LMsDJOBM7CmG0983kF4gRIihECpQ0rcjO"
|
||||||
|
"P6BSfbVTE9mfIK5IsUiZGd8SoE9kSV2pJ2FvZeBQENoAxEFk0zZL9tchPS+OCUGbK4SDjz"
|
||||||
|
"uNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadru"
|
||||||
|
"biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI"
|
||||||
|
"RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n";
|
||||||
|
|
||||||
|
|
||||||
|
static int LoadPasswordBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list)
|
||||||
|
{
|
||||||
|
char* str = (char*)buf;
|
||||||
|
char* delimiter;
|
||||||
|
char* username;
|
||||||
|
char* password;
|
||||||
|
|
||||||
|
/* Each line of passwd.txt is in the format
|
||||||
|
* username:password\n
|
||||||
|
* This function modifies the passed-in buffer. */
|
||||||
|
|
||||||
|
if (list == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (buf == NULL || bufSz == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*str != 0) {
|
||||||
|
delimiter = strchr(str, ':');
|
||||||
|
username = str;
|
||||||
|
*delimiter = 0;
|
||||||
|
password = delimiter + 1;
|
||||||
|
str = strchr(password, '\n');
|
||||||
|
*str = 0;
|
||||||
|
str++;
|
||||||
|
if (PwMapNew(list, WOLFSSH_USERAUTH_PASSWORD,
|
||||||
|
(uint8_t*)username, (uint32_t)strlen(username),
|
||||||
|
(uint8_t*)password, (uint32_t)strlen(password)) == NULL ) {
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int LoadPublicKeyBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list)
|
||||||
|
{
|
||||||
|
char* str = (char*)buf;
|
||||||
|
char* delimiter;
|
||||||
|
uint8_t* publicKey64;
|
||||||
|
uint32_t publicKey64Sz;
|
||||||
|
uint8_t* username;
|
||||||
|
uint32_t usernameSz;
|
||||||
|
uint8_t publicKey[300];
|
||||||
|
uint32_t publicKeySz;
|
||||||
|
int decodeResult;
|
||||||
|
|
||||||
|
/* Each line of passwd.txt is in the format
|
||||||
|
* ssh-rsa AAAB3BASE64ENCODEDPUBLICKEYBLOB username\n
|
||||||
|
* This function modifies the passed-in buffer. */
|
||||||
|
if (list == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (buf == NULL || bufSz == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*str != 0) {
|
||||||
|
/* Skip the public key type. This example will always be ssh-rsa. */
|
||||||
|
delimiter = strchr(str, ' ');
|
||||||
|
str = delimiter + 1;
|
||||||
|
delimiter = strchr(str, ' ');
|
||||||
|
publicKey64 = (uint8_t*)str;
|
||||||
|
publicKey64Sz = (uint32_t)(delimiter - str);
|
||||||
|
str = delimiter + 1;
|
||||||
|
delimiter = strchr(str, '\n');
|
||||||
|
username = (uint8_t*)str;
|
||||||
|
usernameSz = (uint32_t)(delimiter - str);
|
||||||
|
str = delimiter + 1;
|
||||||
|
publicKeySz = sizeof(publicKey);
|
||||||
|
|
||||||
|
decodeResult = Base64_Decode(publicKey64, publicKey64Sz,
|
||||||
|
publicKey, &publicKeySz);
|
||||||
|
|
||||||
|
printf("Base64_Decode = %d\n", decodeResult);
|
||||||
|
|
||||||
|
if (PwMapNew(list, WOLFSSH_USERAUTH_PUBLICKEY,
|
||||||
|
username, usernameSz,
|
||||||
|
publicKey, publicKeySz) == NULL ) {
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wsUserAuth(uint8_t authType,
|
||||||
|
const WS_UserAuthData* authData,
|
||||||
|
void* ctx)
|
||||||
|
{
|
||||||
|
PwMapList* list;
|
||||||
|
PwMap* map;
|
||||||
|
uint8_t authHash[SHA256_DIGEST_SIZE];
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
fprintf(stderr, "wsUserAuth: ctx not set");
|
||||||
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authType != WOLFSSH_USERAUTH_PASSWORD &&
|
||||||
|
authType != WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||||
|
|
||||||
|
return WOLFSSH_USERAUTH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hash the password or public key with its length. */
|
||||||
|
{
|
||||||
|
Sha256 sha;
|
||||||
|
uint8_t flatSz[4];
|
||||||
|
wc_InitSha256(&sha);
|
||||||
|
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
|
||||||
|
c32toa(authData->sf.password.passwordSz, flatSz);
|
||||||
|
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||||
|
wc_Sha256Update(&sha,
|
||||||
|
authData->sf.password.password,
|
||||||
|
authData->sf.password.passwordSz);
|
||||||
|
}
|
||||||
|
else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||||
|
c32toa(authData->sf.publicKey.publicKeySz, flatSz);
|
||||||
|
wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
|
||||||
|
wc_Sha256Update(&sha,
|
||||||
|
authData->sf.publicKey.publicKey,
|
||||||
|
authData->sf.publicKey.publicKeySz);
|
||||||
|
}
|
||||||
|
wc_Sha256Final(&sha, authHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
list = (PwMapList*)ctx;
|
||||||
|
map = list->head;
|
||||||
|
|
||||||
|
while (map != NULL) {
|
||||||
|
if (authData->type == map->type &&
|
||||||
|
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 ?
|
||||||
|
WOLFSSH_USERAUTH_INVALID_PASSWORD :
|
||||||
|
WOLFSSH_USERAUTH_INVALID_PUBLICKEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WOLFSSH_USERAUTH_SUCCESS;
|
||||||
|
}
|
||||||
|
map = map->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WOLFSSH_USERAUTH_INVALID_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
WOLFSSH_CTX* ctx = NULL;
|
WOLFSSH_CTX* ctx = NULL;
|
||||||
|
PwMapList pwMapList;
|
||||||
SOCKET_T listenFd = 0;
|
SOCKET_T listenFd = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_WOLFSSH
|
#ifdef DEBUG_WOLFSSH
|
||||||
|
@ -335,6 +581,9 @@ int main(void)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&pwMapList, 0, sizeof(pwMapList));
|
||||||
|
wolfSSH_SetUserAuth(ctx, wsUserAuth);
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t buf[SCRATCH_BUFFER_SIZE];
|
uint8_t buf[SCRATCH_BUFFER_SIZE];
|
||||||
uint32_t bufSz;
|
uint32_t bufSz;
|
||||||
|
@ -360,6 +609,16 @@ int main(void)
|
||||||
fprintf(stderr, "Couldn't use key buffer.\n");
|
fprintf(stderr, "Couldn't use key buffer.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufSz = (uint32_t)strlen((char*)samplePasswordBuffer);
|
||||||
|
memcpy(buf, samplePasswordBuffer, bufSz);
|
||||||
|
buf[bufSz] = 0;
|
||||||
|
LoadPasswordBuffer(buf, bufSz, &pwMapList);
|
||||||
|
|
||||||
|
bufSz = (uint32_t)strlen((char*)samplePublicKeyBuffer);
|
||||||
|
memcpy(buf, samplePublicKeyBuffer, bufSz);
|
||||||
|
buf[bufSz] = 0;
|
||||||
|
LoadPublicKeyBuffer(buf, bufSz, &pwMapList);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_bind(&listenFd, SERVER_PORT_NUMBER, 0);
|
tcp_bind(&listenFd, SERVER_PORT_NUMBER, 0);
|
||||||
|
@ -376,6 +635,7 @@ int main(void)
|
||||||
fprintf(stderr, "Couldn't allocate SSH data.\n");
|
fprintf(stderr, "Couldn't allocate SSH data.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
|
||||||
|
|
||||||
if (listen(listenFd, 5) != 0)
|
if (listen(listenFd, 5) != 0)
|
||||||
err_sys("tcp listen failed");
|
err_sys("tcp listen failed");
|
||||||
|
@ -391,6 +651,7 @@ int main(void)
|
||||||
pthread_detach(thread);
|
pthread_detach(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PwMapListDelete(&pwMapList);
|
||||||
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
if (wolfSSH_Cleanup() != WS_SUCCESS) {
|
||||||
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
203
src/internal.c
203
src/internal.c
|
@ -1360,65 +1360,176 @@ static int DoUserAuthRequest(WOLFSSH* ssh,
|
||||||
uint8_t* buf, uint32_t len, uint32_t* idx)
|
uint8_t* buf, uint32_t len, uint32_t* idx)
|
||||||
{
|
{
|
||||||
uint32_t begin = *idx;
|
uint32_t begin = *idx;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t valueSz;
|
uint8_t authNameId;
|
||||||
char value[32];
|
uint32_t authNameSz;
|
||||||
uint8_t authNameId;
|
WS_UserAuthData authData;
|
||||||
|
|
||||||
(void)ssh;
|
GetUint32(&authData.usernameSz, buf, len, &begin);
|
||||||
(void)len;
|
authData.username = buf + begin;
|
||||||
|
begin += authData.usernameSz;
|
||||||
|
|
||||||
DumpOctetString(buf, len);
|
GetUint32(&authData.serviceNameSz, buf, len, &begin);
|
||||||
ato32(buf + begin, &valueSz);
|
authData.serviceName = buf + begin;
|
||||||
begin += LENGTH_SZ;
|
begin += authData.serviceNameSz;
|
||||||
|
|
||||||
XMEMCPY(value, buf + begin, valueSz);
|
GetUint32(&authNameSz, buf, len, &begin);
|
||||||
begin += valueSz;
|
authNameId = NameToId((const char*)(buf + begin), authNameSz);
|
||||||
value[valueSz] = 0;
|
begin += authNameSz;
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: userName = %s", value);
|
|
||||||
|
|
||||||
ato32(buf + begin, &valueSz);
|
|
||||||
begin += LENGTH_SZ;
|
|
||||||
|
|
||||||
XMEMCPY(value, buf + begin, valueSz);
|
|
||||||
begin += valueSz;
|
|
||||||
value[valueSz] = 0;
|
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: serviceName = %s", value);
|
|
||||||
|
|
||||||
ato32(buf + begin, &valueSz);
|
|
||||||
begin += LENGTH_SZ;
|
|
||||||
|
|
||||||
XMEMCPY(value, buf + begin, valueSz);
|
|
||||||
begin += valueSz;
|
|
||||||
value[valueSz] = 0;
|
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: authName = %s", value);
|
|
||||||
authNameId = NameToId(value, valueSz);
|
|
||||||
|
|
||||||
if (authNameId == ID_USERAUTH_PASSWORD) {
|
if (authNameId == ID_USERAUTH_PASSWORD) {
|
||||||
uint8_t pwChanged;
|
WS_UserAuthData_Password* pw = &authData.sf.password;
|
||||||
ret = GetBoolean(&pwChanged, buf, len, &begin);
|
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: pwChanged = %s",
|
authData.type = WOLFSSH_USERAUTH_PASSWORD;
|
||||||
(pwChanged ? "TRUE" : "FALSE"));
|
ret = GetBoolean(&pw->hasNewPassword, buf, len, &begin);
|
||||||
if (!pwChanged) {
|
ret = GetUint32(&pw->passwordSz, buf, len, &begin);
|
||||||
ret = GetString(value, &valueSz, buf, len, &begin);
|
pw->password = buf + begin;
|
||||||
if (ret == WS_SUCCESS)
|
begin += pw->passwordSz;
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: password = %s", value);
|
|
||||||
else
|
if (pw->hasNewPassword) {
|
||||||
WLOG(WS_LOG_DEBUG, "DUAR: password = error? %d", ret);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Skip the password change. Maybe error out since we aren't
|
/* Skip the password change. Maybe error out since we aren't
|
||||||
* supporting password changes at this time. */
|
* supporting password changes at this time. */
|
||||||
|
ret = GetUint32(&pw->newPasswordSz, buf, len, &begin);
|
||||||
|
pw->newPassword = buf + begin;
|
||||||
|
begin += pw->newPasswordSz;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pw->newPassword = NULL;
|
||||||
|
pw->newPasswordSz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh->ctx->userAuthCb != NULL) {
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUAR: Checking the password");
|
||||||
|
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PASSWORD,
|
||||||
|
&authData, ssh->userAuthCtx);
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUAR: password check successful");
|
||||||
|
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUAR: password check failed");
|
||||||
|
SendUserAuthFailure(ssh, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUAR: No user auth callback");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (authNameId == ID_USERAUTH_PUBLICKEY) {
|
else if (authNameId == ID_USERAUTH_PUBLICKEY) {
|
||||||
} else
|
WS_UserAuthData_PublicKey* pk = &authData.sf.publicKey;
|
||||||
|
|
||||||
|
authData.type = WOLFSSH_USERAUTH_PUBLICKEY;
|
||||||
|
ret = GetBoolean(&pk->hasSignature, buf, len, &begin);
|
||||||
|
GetUint32(&pk->publicKeyTypeSz, buf, len, &begin);
|
||||||
|
pk->publicKeyType = buf + begin;
|
||||||
|
begin += pk->publicKeyTypeSz;
|
||||||
|
GetUint32(&pk->publicKeySz, buf, len, &begin);
|
||||||
|
pk->publicKey = buf + begin;
|
||||||
|
begin += pk->publicKeySz;
|
||||||
|
|
||||||
|
if (pk->hasSignature) {
|
||||||
|
GetUint32(&pk->signatureSz, buf, len, &begin);
|
||||||
|
pk->signature = buf + begin;
|
||||||
|
begin += pk->signatureSz;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pk->signature = NULL;
|
||||||
|
pk->signatureSz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh->ctx->userAuthCb != NULL) {
|
||||||
|
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PUBLICKEY,
|
||||||
|
&authData, ssh->userAuthCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pk->signature == NULL) {
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUAR: Send the PK OK!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t checkDigest[MAX_ENCODED_SIG_SZ];
|
||||||
|
uint32_t checkDigestSz = 0;
|
||||||
|
uint8_t encDigest[MAX_ENCODED_SIG_SZ];
|
||||||
|
uint32_t encDigestSz;
|
||||||
|
|
||||||
|
{
|
||||||
|
RsaKey key;
|
||||||
|
uint8_t* n;
|
||||||
|
uint32_t nSz;
|
||||||
|
uint8_t* e;
|
||||||
|
uint32_t eSz;
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
GetUint32(&nSz, pk->publicKey, pk->publicKeySz, &i);
|
||||||
|
i += nSz;
|
||||||
|
GetUint32(&eSz, pk->publicKey, pk->publicKeySz, &i);
|
||||||
|
e = pk->publicKey + i;
|
||||||
|
i += eSz;
|
||||||
|
GetUint32(&nSz, pk->publicKey, pk->publicKeySz, &i);
|
||||||
|
n = authData.sf.publicKey.publicKey + i;
|
||||||
|
|
||||||
|
wc_InitRsaKey(&key, ssh->ctx->heap);
|
||||||
|
ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, &key);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
GetUint32(&nSz, pk->signature, pk->signatureSz, &i);
|
||||||
|
i += nSz;
|
||||||
|
GetUint32(&nSz, pk->signature, pk->signatureSz, &i);
|
||||||
|
n = pk->signature + i;
|
||||||
|
ret = wc_RsaSSL_Verify(n, nSz, checkDigest,
|
||||||
|
sizeof(checkDigest), &key);
|
||||||
|
wc_FreeRsaKey(&key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
checkDigestSz = (uint32_t)ret;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Sha sha;
|
||||||
|
uint8_t digest[SHA_DIGEST_SIZE];
|
||||||
|
|
||||||
|
wc_InitSha(&sha);
|
||||||
|
c32toa(ssh->sessionIdSz, digest);
|
||||||
|
wc_ShaUpdate(&sha, digest, UINT32_SZ);
|
||||||
|
wc_ShaUpdate(&sha, ssh->sessionId, ssh->sessionIdSz);
|
||||||
|
digest[0] = MSGID_USERAUTH_REQUEST;
|
||||||
|
wc_ShaUpdate(&sha, digest, MSG_ID_SZ);
|
||||||
|
|
||||||
|
/* The rest of the fields in the signature are already
|
||||||
|
* in the buffer. Just need to account for the sizes. */
|
||||||
|
wc_ShaUpdate(&sha, buf + *idx,
|
||||||
|
authData.usernameSz + authData.serviceNameSz +
|
||||||
|
authNameSz + BOOLEAN_SZ +
|
||||||
|
authData.sf.publicKey.publicKeyTypeSz +
|
||||||
|
authData.sf.publicKey.publicKeySz + (UINT32_SZ * 5));
|
||||||
|
ShaFinal(&sha, digest);
|
||||||
|
|
||||||
|
encDigestSz = wc_EncodeSignature(encDigest, digest,
|
||||||
|
SHA_DIGEST_SIZE, SHAh);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
volatile int compare;
|
||||||
|
volatile int sizeCompare;
|
||||||
|
|
||||||
|
compare = ConstantCompare(encDigest, checkDigest, encDigestSz);
|
||||||
|
sizeCompare = encDigestSz != checkDigestSz;
|
||||||
|
|
||||||
|
if (compare || sizeCompare || ret < 0) {
|
||||||
|
SendUserAuthFailure(ssh, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
SendUserAuthFailure(ssh, 0);
|
SendUserAuthFailure(ssh, 0);
|
||||||
|
|
||||||
*idx = begin;
|
*idx = begin;
|
||||||
|
|
||||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
|
||||||
|
|
||||||
return WS_SUCCESS;
|
return WS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2652,7 +2763,7 @@ int SendServiceAccept(WOLFSSH* ssh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char cannedAuths[] = "password";
|
static const char cannedAuths[] = "publickey";
|
||||||
static const uint32_t cannedAuthsSz = sizeof(cannedAuths) - 1;
|
static const uint32_t cannedAuthsSz = sizeof(cannedAuths) - 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
25
src/ssh.c
25
src/ssh.c
|
@ -487,6 +487,31 @@ int wolfSSH_stream_send(WOLFSSH* ssh, uint8_t* buf, uint32_t bufSz)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wolfSSH_SetUserAuth(WOLFSSH_CTX* ctx, WS_CallbackUserAuth cb)
|
||||||
|
{
|
||||||
|
if (ctx != NULL) {
|
||||||
|
ctx->userAuthCb = cb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wolfSSH_SetUserAuthCtx(WOLFSSH* ssh, void* userAuthCtx)
|
||||||
|
{
|
||||||
|
if (ssh != NULL) {
|
||||||
|
ssh->userAuthCtx = userAuthCtx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* wolfSSH_GetUserAuthCtx(WOLFSSH* ssh)
|
||||||
|
{
|
||||||
|
if (ssh != NULL) {
|
||||||
|
return ssh->userAuthCtx;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz,
|
static int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz,
|
||||||
int format, int type)
|
int format, int type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,16 +134,17 @@ WOLFSSH_LOCAL void ShrinkBuffer(Buffer* buf, int);
|
||||||
|
|
||||||
/* our wolfSSH Context */
|
/* our wolfSSH Context */
|
||||||
struct WOLFSSH_CTX {
|
struct WOLFSSH_CTX {
|
||||||
void* heap; /* heap hint */
|
void* heap; /* heap hint */
|
||||||
WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */
|
WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */
|
||||||
WS_CallbackIOSend ioSendCb; /* I/O Send Callback */
|
WS_CallbackIOSend ioSendCb; /* I/O Send Callback */
|
||||||
|
WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */
|
||||||
|
|
||||||
uint8_t* cert; /* Owned by CTX */
|
uint8_t* cert; /* Owned by CTX */
|
||||||
uint32_t certSz;
|
uint32_t certSz;
|
||||||
uint8_t* caCert; /* Owned by CTX */
|
uint8_t* caCert; /* Owned by CTX */
|
||||||
uint32_t caCertSz;
|
uint32_t caCertSz;
|
||||||
uint8_t* privateKey; /* Owned by CTX */
|
uint8_t* privateKey; /* Owned by CTX */
|
||||||
uint32_t privateKeySz;
|
uint32_t privateKeySz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,8 +249,11 @@ struct WOLFSSH {
|
||||||
|
|
||||||
HandshakeInfo* handshake;
|
HandshakeInfo* handshake;
|
||||||
|
|
||||||
|
void* userAuthCtx;
|
||||||
uint8_t* userName;
|
uint8_t* userName;
|
||||||
uint32_t userNameSz;
|
uint32_t userNameSz;
|
||||||
|
uint8_t* pkBlob;
|
||||||
|
uint32_t pkBlobSz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,16 +66,51 @@ WOLFSSH_API const char* wolfSSH_get_error_name(const WOLFSSH*);
|
||||||
/* I/O callbacks */
|
/* I/O callbacks */
|
||||||
typedef int (*WS_CallbackIORecv)(WOLFSSH*, void*, uint32_t, void*);
|
typedef int (*WS_CallbackIORecv)(WOLFSSH*, void*, uint32_t, void*);
|
||||||
typedef int (*WS_CallbackIOSend)(WOLFSSH*, void*, uint32_t, void*);
|
typedef int (*WS_CallbackIOSend)(WOLFSSH*, void*, uint32_t, void*);
|
||||||
|
|
||||||
WOLFSSH_API void wolfSSH_SetIORecv(WOLFSSH_CTX*, WS_CallbackIORecv);
|
WOLFSSH_API void wolfSSH_SetIORecv(WOLFSSH_CTX*, WS_CallbackIORecv);
|
||||||
WOLFSSH_API void wolfSSH_SetIOSend(WOLFSSH_CTX*, WS_CallbackIOSend);
|
WOLFSSH_API void wolfSSH_SetIOSend(WOLFSSH_CTX*, WS_CallbackIOSend);
|
||||||
|
|
||||||
WOLFSSH_API void wolfSSH_SetIOReadCtx(WOLFSSH*, void*);
|
WOLFSSH_API void wolfSSH_SetIOReadCtx(WOLFSSH*, void*);
|
||||||
WOLFSSH_API void wolfSSH_SetIOWriteCtx(WOLFSSH*, void*);
|
WOLFSSH_API void wolfSSH_SetIOWriteCtx(WOLFSSH*, void*);
|
||||||
|
|
||||||
WOLFSSH_API void* wolfSSH_GetIOReadCtx(WOLFSSH*);
|
WOLFSSH_API void* wolfSSH_GetIOReadCtx(WOLFSSH*);
|
||||||
WOLFSSH_API void* wolfSSH_GetIOWriteCtx(WOLFSSH*);
|
WOLFSSH_API void* wolfSSH_GetIOWriteCtx(WOLFSSH*);
|
||||||
|
|
||||||
|
/* User Authentication callback */
|
||||||
|
|
||||||
|
typedef struct WS_UserAuthData_Password {
|
||||||
|
uint8_t* password;
|
||||||
|
uint32_t passwordSz;
|
||||||
|
/* The following are present for future use. */
|
||||||
|
uint8_t hasNewPassword;
|
||||||
|
uint8_t* newPassword;
|
||||||
|
uint32_t newPasswordSz;
|
||||||
|
} WS_UserAuthData_Password;
|
||||||
|
|
||||||
|
typedef struct WS_UserAuthData_PublicKey {
|
||||||
|
uint8_t* publicKeyType;
|
||||||
|
uint32_t publicKeyTypeSz;
|
||||||
|
uint8_t* publicKey;
|
||||||
|
uint32_t publicKeySz;
|
||||||
|
uint8_t hasSignature;
|
||||||
|
uint8_t* signature;
|
||||||
|
uint32_t signatureSz;
|
||||||
|
} WS_UserAuthData_PublicKey;
|
||||||
|
|
||||||
|
typedef struct WS_UserAuthData {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t* username;
|
||||||
|
uint32_t usernameSz;
|
||||||
|
uint8_t* serviceName;
|
||||||
|
uint32_t serviceNameSz;
|
||||||
|
union {
|
||||||
|
WS_UserAuthData_Password password;
|
||||||
|
WS_UserAuthData_PublicKey publicKey;
|
||||||
|
} sf;
|
||||||
|
} WS_UserAuthData;
|
||||||
|
|
||||||
|
typedef int (*WS_CallbackUserAuth)(uint8_t, const WS_UserAuthData*, void*);
|
||||||
|
WOLFSSH_API void wolfSSH_SetUserAuth(WOLFSSH_CTX*, WS_CallbackUserAuth);
|
||||||
|
WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*);
|
||||||
|
WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
|
||||||
|
|
||||||
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
|
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
|
||||||
const uint8_t*, uint32_t, int);
|
const uint8_t*, uint32_t, int);
|
||||||
WOLFSSH_API int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX*,
|
WOLFSSH_API int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX*,
|
||||||
|
@ -104,6 +139,21 @@ enum WS_FormatTypes {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum WS_UserAuthTypes {
|
||||||
|
WOLFSSH_USERAUTH_PASSWORD,
|
||||||
|
WOLFSSH_USERAUTH_PUBLICKEY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum WS_UserAuthResults {
|
||||||
|
WOLFSSH_USERAUTH_SUCCESS,
|
||||||
|
WOLFSSH_USERAUTH_FAILURE,
|
||||||
|
WOLFSSH_USERAUTH_INVALID_USER,
|
||||||
|
WOLFSSH_USERAUTH_INVALID_PASSWORD,
|
||||||
|
WOLFSSH_USERAUTH_INVALID_PUBLICKEY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum WS_DisconnectReasonCodes {
|
enum WS_DisconnectReasonCodes {
|
||||||
WOLFSSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
|
WOLFSSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
|
||||||
WOLFSSH_DISCONNECT_PROTOCOL_ERROR = 2,
|
WOLFSSH_DISCONNECT_PROTOCOL_ERROR = 2,
|
||||||
|
|
Loading…
Reference in New Issue