Kaynağa Gözat

ssh: utilize system-wide auth

Sergey Alirzaev 5 yıl önce
ebeveyn
işleme
f3e0f52f95

+ 1 - 1
modules/HTTP_Server/http_server.c

@@ -1783,7 +1783,7 @@ char *HTTP_ChangeUserPwd(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t le
                 if (GetParamValue(tempStr, "newpass=", tmp, &valueLen)) {
                     url_decode(password, sizeof(password), tmp);
                     valueLen = strlen(password);
-                    memcpy(sSettings.sAuth[user_id].password, password, 11);
+                    memcpy(sSettings.sAuth[user_id].password, password, sizeof(sSettings.sAuth[user_id].password));
 
                     telnet_act = false;
 

+ 1 - 1
modules/HTTP_Server/my_ssl_server.c

@@ -2018,7 +2018,7 @@ char *HTTP_ChangeUserPwd(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t le
                 if (GetParamValue(tempStr, "newpass=", tmp, &valueLen)) {
                     url_decode(password, sizeof(password), tmp);
                     valueLen = strlen(password);
-                    memcpy(sSettings.sAuth[user_id].password, password, 11);
+                    memcpy(sSettings.sAuth[user_id].password, password, sizeof(sSettings.sAuth[user_id].password));
 
                     HTTP_SaveSettings();
                     log_event_data(LOG_PSW_CHANGE, name_login);

+ 22 - 0
modules/SSH_Server/cli.c

@@ -364,3 +364,25 @@ void cli_hello(cli_state_t *cli_state)
 	const char hello[] = "hello\r\n>";
 	cli_state->send(cli_state->num_connect, hello, sizeof(hello));
 }
+
+user_level_t cli_auth_user(char *user, char *password)
+{
+	user_level_t rv = MAX_USER_LEVELS;
+	char WebPassword[MAX_WEB_PASSWD_LEN];
+	char WebLogin[MAX_WEB_LOGIN_LEN];
+	uint8_t valueLen, user_id;
+	for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
+		GetUserLogin(user_id, WebLogin, &valueLen);
+		GetUserPassword(user_id, WebPassword, &valueLen);
+
+		/* Check login and password */
+		if ((strncmp(WebLogin, user, MAX_WEB_LOGIN_LEN) == 0) &&
+			(strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
+
+			/* Login and pass are valid */
+			rv = user_id;
+			break;
+		}
+	}
+	return rv;
+}

+ 1 - 0
modules/SSH_Server/cli.h

@@ -58,5 +58,6 @@ void cli_init(void);
 void cli_getchar(cli_state_t *s, char incoming_char);
 cli_state_t *alloc_state(void);
 void cli_hello(cli_state_t *cli_state);
+user_level_t cli_auth_user(char *user, char *password);
 
 #endif

+ 13 - 291
modules/SSH_Server/server.c

@@ -65,26 +65,6 @@ typedef struct {
 #endif
 #define SCRATCH_BUFFER_SZ 1200
 
-
-static byte find_char(const byte* str, const byte* buf, word32 bufSz)
-{
-    const byte* cur;
-
-    while (bufSz) {
-        cur = str;
-        while (*cur != '\0') {
-            if (*cur == *buf)
-                return *cur;
-            cur++;
-        }
-        buf++;
-        bufSz--;
-    }
-
-    return 0;
-}
-
-
 /*
 static int dump_stats(thread_ctx_t* ctx)
 {
@@ -153,6 +133,9 @@ static void *server_worker(void* vArgs)
     int ret;
     thread_ctx_t* threadCtx = (thread_ctx_t*)vArgs;
 
+    user_level_t user_id;
+    wolfSSH_SetUserAuthCtx(threadCtx->ssh, &user_id);
+
     if (!threadCtx->nonBlock)
         ret = wolfSSH_accept(threadCtx->ssh);
     else
@@ -272,268 +255,27 @@ static INLINE void c32toa(word32 u32, byte* c)
     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 {
-    byte type;
-    byte username[32];
-    word32 usernameSz;
-    byte p[SHA256_DIGEST_SIZE];
-    struct PwMap* next;
-} PwMap;
-
-
-typedef struct PwMapList {
-    PwMap* head;
-} PwMapList;
-
-
-static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username,
-                       word32 usernameSz, const byte* p, word32 pSz)
-{
-    PwMap* map;
-
-    map = (PwMap*)malloc(sizeof(PwMap));
-    if (map != NULL) {
-        Sha256 sha;
-        byte 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));
-            free(cur);
-        }
-    }
-}
-
-
-static const char samplePasswordBuffer[] =
-    "jill:upthehill\n"
-    "jack:fetchapail\n";
-
-
-static const char samplePublicKeyEccBuffer[] =
-    "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
-    "BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25"
-    "qUzgDtH7oyaQROUnNvk= hansel\n"
-    "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
-    "BBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1Hh"
-    "IZzRYecXh7SG9P4GhRY= gretel\n";
-
-
-static const char samplePublicKeyRsaBuffer[] =
-    "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(byte* buf, word32 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, ':');
-        if (delimiter == NULL) {
-            return -1;
-        }
-        username = str;
-        *delimiter = 0;
-        password = delimiter + 1;
-        str = strchr(password, '\n');
-        if (str == NULL) {
-            return -1;
-        }
-        *str = 0;
-        str++;
-        if (PwMapNew(list, WOLFSSH_USERAUTH_PASSWORD,
-                     (byte*)username, (word32)strlen(username),
-                     (byte*)password, (word32)strlen(password)) == NULL ) {
-
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-
-static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list)
+static int wsUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
 {
-    char* str = (char*)buf;
-    char* delimiter;
-    byte* publicKey64;
-    word32 publicKey64Sz;
-    byte* username;
-    word32 usernameSz;
-    byte  publicKey[300];
-    word32 publicKeySz;
-
-    /* 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, ' ');
-        if (delimiter == NULL) {
-            return -1;
-        }
-        str = delimiter + 1;
-        delimiter = strchr(str, ' ');
-        if (delimiter == NULL) {
-            return -1;
-        }
-        publicKey64 = (byte*)str;
-        *delimiter = 0;
-        publicKey64Sz = (word32)(delimiter - str);
-        str = delimiter + 1;
-        delimiter = strchr(str, '\n');
-        if (delimiter == NULL) {
-            return -1;
-        }
-        username = (byte*)str;
-        *delimiter = 0;
-        usernameSz = (word32)(delimiter - str);
-        str = delimiter + 1;
-        publicKeySz = sizeof(publicKey);
-
-        if (Base64_Decode(publicKey64, publicKey64Sz,
-                          publicKey, &publicKeySz) != 0) {
-
-            return -1;
-        }
-
-        if (PwMapNew(list, WOLFSSH_USERAUTH_PUBLICKEY,
-                     username, usernameSz,
-                     publicKey, publicKeySz) == NULL ) {
-
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-
-static int wsUserAuth(byte authType,
-                      WS_UserAuthData* authData,
-                      void* ctx)
-{
-    PwMapList* list;
-    PwMap* map;
-    byte authHash[SHA256_DIGEST_SIZE];
+    user_level_t *user_id = ctx;
 
     if (ctx == NULL) {
         printf("wsUserAuth: ctx not set");
         return WOLFSSH_USERAUTH_FAILURE;
     }
 
-    if (authType != WOLFSSH_USERAUTH_PASSWORD &&
-        authType != WOLFSSH_USERAUTH_PUBLICKEY) {
+    if (authType != WOLFSSH_USERAUTH_PASSWORD) {
 
         return WOLFSSH_USERAUTH_FAILURE;
     }
 
-    /* Hash the password or public key with its length. */
-    {
-        Sha256 sha;
-        byte 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->usernameSz == map->usernameSz &&
-            memcmp(authData->username, map->username, map->usernameSz) == 0) {
-
-            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;
-            }
-        }
-        map = map->next;
+    // the incoming password is not zero-terminated
+    char password[MAX_WEB_PASSWD_LEN];
+    strncpy(password, authData->sf.password.password, sizeof(password));
+    password[min(MAX_WEB_PASSWD_LEN - 1, authData->sf.password.passwordSz)] = 0;
+    *user_id = cli_auth_user(authData->username, password);
+    if (*user_id != MAX_USER_LEVELS) {
+        return WOLFSSH_USERAUTH_SUCCESS;
     }
 
     return WOLFSSH_USERAUTH_INVALID_USER;
@@ -549,14 +291,12 @@ static void ssh_server(void *arg)
     #endif
     wolfSSH_Init();
     WOLFSSH_CTX* ctx = NULL;
-    PwMapList pwMapList;
     SOCKET_T listenFd = 0;
     word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
     word32 threadCount = 0;
     word16 port = 22;
     const char multipleConnections = 1;
     char useEcc = 1;
-    int  ch;
     char nonBlock = 0;
 
     if (wolfSSH_Init() != WS_SUCCESS) {
@@ -570,12 +310,10 @@ static void ssh_server(void *arg)
         exit(EXIT_FAILURE);
     }
 
-    memset(&pwMapList, 0, sizeof(pwMapList));
     wolfSSH_SetUserAuth(ctx, wsUserAuth);
     wolfSSH_CTX_SetBanner(ctx, serverBanner);
 
     {
-        const char* bufName;
         byte buf[SCRATCH_BUFFER_SZ];
         word32 bufSz;
 
@@ -589,18 +327,6 @@ static void ssh_server(void *arg)
             printf("Couldn't use key buffer.\n");
             exit(EXIT_FAILURE);
         }
-
-        bufSz = (word32)strlen(samplePasswordBuffer);
-        memcpy(buf, samplePasswordBuffer, bufSz);
-        buf[bufSz] = 0;
-        LoadPasswordBuffer(buf, bufSz, &pwMapList);
-
-        bufName = useEcc ? samplePublicKeyEccBuffer :
-                           samplePublicKeyRsaBuffer;
-        bufSz = (word32)strlen(bufName);
-        memcpy(buf, bufName, bufSz);
-        buf[bufSz] = 0;
-        LoadPublicKeyBuffer(buf, bufSz, &pwMapList);
     }
 
     tcp_listen(&listenFd, &port, 1, false, false);
@@ -626,7 +352,6 @@ static void ssh_server(void *arg)
             printf("Couldn't allocate SSH data.\n");
             exit(EXIT_FAILURE);
         }
-        wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
         /* Use the session object for its own highwater callback ctx */
         if (defaultHighwater > 0) {
             wolfSSH_SetHighwaterCtx(ssh, (void*)ssh);
@@ -660,7 +385,6 @@ static void ssh_server(void *arg)
 #endif /* SINGLE_THREADED */
     } while (multipleConnections);
 
-    PwMapListDelete(&pwMapList);
     wolfSSH_CTX_free(ctx);
     if (wolfSSH_Cleanup() != WS_SUCCESS) {
         printf("Couldn't clean up wolfSSH.\n");
@@ -669,8 +393,6 @@ static void ssh_server(void *arg)
 #if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
     wc_ecc_fp_free();  /* free per thread cache */
 #endif
-
-    return 0;
 }
 
 void ssh_server_init(void)