diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a4e23f8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.31) +project(libssh-test C) +set(CMAKE_C_STANDARD 23) + +include_directories(include) + +add_subdirectory(libssh) +include_directories(${libssh_BINARY_DIR}/include ${libssh_BINARY_DIR}) + +add_subdirectory(simple-server) diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..22c55a8 --- /dev/null +++ b/include/config.h @@ -0,0 +1,285 @@ +#ifndef CONFIG_H +#define CONFIG_H + +/* Name of package */ +#define PACKAGE "libssh" + +/* Version number of package */ +#define VERSION "0.11.2" + +#define SYSCONFDIR "etc" +#define BINARYDIR "libssh" +#define SOURCEDIR "libssh" + +/* Global bind configuration file path */ +#define GLOBAL_BIND_CONFIG "/etc/ssh/libssh_server_config" + +/* Global client configuration file path */ +#define GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config" + +/************************** HEADER FILES *************************/ + +/* Define to 1 if you have the header file. */ +// #define HAVE_ARGP_H 1 +/* #undef HAVE_ARGP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VALGRIND_VALGRIND_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTMP_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UTIL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UTIME_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +// #undef HAVE_IFADDRS_H + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_AES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WSPIAPI_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_DES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_ECDH_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_EC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_ECDSA_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTHREAD_H */ + +/* Define to 1 if you have elliptic curve cryptography in openssl */ +#define HAVE_OPENSSL_ECC 1 + +/* Define to 1 if you have elliptic curve cryptography in gcrypt */ +/* #undef HAVE_GCRYPT_ECC */ + +/* Define to 1 if you have elliptic curve cryptography */ +#define HAVE_ECC 1 + +/* Define to 1 if you have gl_flags as a glob_t struct member */ +#define HAVE_GLOB_GL_FLAGS_MEMBER 1 + +/* Define to 1 if you have gcrypt with ChaCha20/Poly1305 support */ +/* #undef HAVE_GCRYPT_CHACHA_POLY */ + +/*************************** FUNCTIONS ***************************/ + +/* Define to 1 if you have the `EVP_chacha20' function. */ +#define HAVE_OPENSSL_EVP_CHACHA20 1 + +/* Define to 1 if you have the `EVP_KDF_CTX_new_id' or `EVP_KDF_CTX_new` function. */ +/* #undef HAVE_OPENSSL_EVP_KDF_CTX */ + +/* Define to 1 if you have the `FIPS_mode' function. */ +/* #undef HAVE_OPENSSL_FIPS_MODE */ + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `_snprintf' function. */ +/* #undef HAVE__SNPRINTF */ + +/* Define to 1 if you have the `_snprintf_s' function. */ +/* #undef HAVE__SNPRINTF_S */ + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `_vsnprintf' function. */ +/* #undef HAVE__VSNPRINTF */ + +/* Define to 1 if you have the `_vsnprintf_s' function. */ +/* #undef HAVE__VSNPRINTF_S */ + +/* Define to 1 if you have the `isblank' function. */ +#define HAVE_ISBLANK 1 + +/* Define to 1 if you have the `strncpy' function. */ +#define HAVE_STRNCPY 1 + +/* Define to 1 if you have the `strndup' function. */ +#define HAVE_STRNDUP 1 + +/* Define to 1 if you have the `cfmakeraw' function. */ +#define HAVE_CFMAKERAW 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the `clock_gettime' function. */ +#define HAVE_CLOCK_GETTIME 1 + +/* Define to 1 if you have the `ntohll' function. */ +/* #undef HAVE_NTOHLL */ + +/* Define to 1 if you have the `htonll' function. */ +/* #undef HAVE_HTONLL */ + +/* Define to 1 if you have the `strtoull' function. */ +// #define HAVE_STRTOULL 1 + +/* Define to 1 if you have the `__strtoull' function. */ +/* #undef HAVE___STRTOULL */ + +/* Define to 1 if you have the `_strtoui64' function. */ +/* #undef HAVE__STRTOUI64 */ + +/* Define to 1 if you have the `glob' function. */ +// #undef HAVE_GLOB + +/* Define to 1 if you have the `explicit_bzero' function. */ +// #undef HAVE_EXPLICIT_BZERO + +/* Define to 1 if you have the `memset_s' function. */ +/* #undef HAVE_MEMSET_S */ + +/* Define to 1 if you have the `SecureZeroMemory' function. */ +/* #undef HAVE_SECURE_ZERO_MEMORY */ + +/* Define to 1 if you have the `cmocka_set_test_filter' function. */ +/* #undef HAVE_CMOCKA_SET_TEST_FILTER */ + +/* Define to 1 if we have support for blowfish */ +/* #undef HAVE_BLOWFISH */ + +/*************************** LIBRARIES ***************************/ + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#define HAVE_LIBCRYPTO 1 + +/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */ +/* #undef HAVE_LIBGCRYPT */ + +/* Define to 1 if you have the 'mbedTLS' library (-lmbedtls). */ +/* #undef HAVE_LIBMBEDCRYPTO */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +// #undef HAVE_PTHREAD + +/* Define to 1 if you have the `cmocka' library (-lcmocka). */ +/* #undef HAVE_CMOCKA */ + +/**************************** OPTIONS ****************************/ + +#define HAVE_GCC_THREAD_LOCAL_STORAGE 1 +/* #undef HAVE_MSC_THREAD_LOCAL_STORAGE */ + +// #undef HAVE_FALLTHROUGH_ATTRIBUTE +#define HAVE_UNUSED_ATTRIBUTE 1 +#define HAVE_WEAK_ATTRIBUTE 1 + +#define HAVE_CONSTRUCTOR_ATTRIBUTE 1 +#define HAVE_DESTRUCTOR_ATTRIBUTE 1 + +#define HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1 + +// #define HAVE_COMPILER__FUNC__ 1 +#define HAVE_COMPILER__FUNCTION__ 1 + +/* #undef HAVE_GCC_BOUNDED_ATTRIBUTE */ + +/* Define to 1 if you want to enable GSSAPI */ +/* #undef WITH_GSSAPI */ + +/* Define to 1 if you want to enable ZLIB */ +#ifdef CONFIG_LIBSSH_ZLIB +#define WITH_ZLIB +#endif + +/* Define to 1 if you want to enable SFTP */ +#define WITH_SFTP 1 + +/* Define to 1 if you want to enable server support */ +#define WITH_SERVER 1 + +/* Define to 1 if you want to enable DH group exchange algorithms */ +#define WITH_GEX 1 + +/* Define to 1 if you want to enable insecure none cipher and MAC */ +/* #undef WITH_INSECURE_NONE */ + +/* Define to 1 if you want to allow libssh to execute arbitrary commands from + * configuration files or options (match exec, proxy commands and OpenSSH-based + * proxy-jumps). */ +/* #undef WITH_EXEC */ + +/* Define to 1 if you want to enable blowfish cipher support */ +/* #undef WITH_BLOWFISH_CIPHER */ + +/* Define to 1 if you want to enable debug output for crypto functions */ +/* #undef DEBUG_CRYPTO */ + +/* Define to 1 if you want to enable debug output for packet functions */ +/* #undef DEBUG_PACKET */ + +/* Define to 1 if you want to enable pcap output support (experimental) */ +/* #undef WITH_PCAP */ + +/* Define to 1 if you want to enable calltrace debug output */ +/* #undef DEBUG_CALLTRACE */ + +/* Define to 1 if you want to enable NaCl support */ +/* #undef WITH_NACL */ + +/* Define to 1 if you want to enable PKCS #11 URI support */ +/* #undef WITH_PKCS11_URI */ + +/* Define to 1 if we want to build a support for PKCS #11 provider. */ +/* #undef WITH_PKCS11_PROVIDER */ + +/*************************** ENDIAN *****************************/ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +/* #undef WORDS_BIGENDIAN */ + +#ifndef HAVE_STRTOULL +#define HAVE_STRTOULL 1 +#endif + +#endif // CONFIG_H diff --git a/include/priv_key.h b/include/priv_key.h new file mode 100644 index 0000000..b94f7f6 --- /dev/null +++ b/include/priv_key.h @@ -0,0 +1,18 @@ +// +// Created by shinys on 25. 7. 7. +// + +#ifndef PRIV_KEY_H +#define PRIV_KEY_H + +#define HOST_KEY "-----BEGIN OPENSSH PRIVATE KEY-----\n"\ + "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n"\ + "QyNTUxOQAAACBEuxGuFijKm0An75X692FESyA7x/uvHLOk1GeXp/LiAwAAAIhH5v7UR+b+\n"\ + "1AAAAAtzc2gtZWQyNTUxOQAAACBEuxGuFijKm0An75X692FESyA7x/uvHLOk1GeXp/LiAw\n"\ + "AAAEBvitm9U5F/cyRVTEdl4Prs9E2kQJ6aL9QTASNxAqEZzkS7Ea4WKMqbQCfvlfr3YURL\n"\ + "IDvH+68cs6TUZ5en8uIDAAAAAAECAwQF\n"\ + "-----END OPENSSH PRIVATE KEY-----\n"\ + +#define HOST_PUB "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIES7Ea4WKMqbQCfvlfr3YURLIDvH+68cs6TUZ5en8uID" + +#endif //PRIV_KEY_H diff --git a/key/client b/key/client new file mode 100644 index 0000000..0cdbf8a --- /dev/null +++ b/key/client @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACBX4TdVjf7rx6z7m3+9Ravx71k2lQj4hvOGOp3LUuFUPAAAAIjnLRQf5y0U +HwAAAAtzc2gtZWQyNTUxOQAAACBX4TdVjf7rx6z7m3+9Ravx71k2lQj4hvOGOp3LUuFUPA +AAAEDnXiJwcHIl2lvWMpoIInnN47BW77pSYZz+ytfMsDaaflfhN1WN/uvHrPubf71Fq/Hv +WTaVCPiG84Y6nctS4VQ8AAAAAAECAwQF +-----END OPENSSH PRIVATE KEY----- diff --git a/key/client.pub b/key/client.pub new file mode 100644 index 0000000..499912a --- /dev/null +++ b/key/client.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFfhN1WN/uvHrPubf71Fq/HvWTaVCPiG84Y6nctS4VQ8 diff --git a/simple-server/CMakeLists.txt b/simple-server/CMakeLists.txt new file mode 100644 index 0000000..0f46cc7 --- /dev/null +++ b/simple-server/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(simple-server main.c) + +target_link_libraries(simple-server ssh::ssh) \ No newline at end of file diff --git a/simple-server/main.c b/simple-server/main.c new file mode 100644 index 0000000..e43803f --- /dev/null +++ b/simple-server/main.c @@ -0,0 +1,187 @@ +#include "config.h" + +#include +#include +#include + +#include +#include +#include + +#include "priv_key.h" + +#define BUF_SIZE 2049 + +#define USER "odroid" +#define PASSWORD "odroid" + +static int authenticated=0; +static int tries = 0; +static int error = 0; +static ssh_channel chan=NULL; + +static int auth_none(ssh_session session, + const char *user, + void *userdata) +{ + char buf[100]; + ssh_string banner = NULL; + + (void)userdata; /* unused */ + + ssh_set_auth_methods(session, + SSH_AUTH_METHOD_PASSWORD); + + sprintf(buf, "hello [%s]!\n", user); + banner = ssh_string_from_char(buf); + if (banner != NULL) { + ssh_send_issue_banner(session, banner); + } + ssh_string_free(banner); + + return SSH_AUTH_DENIED; +} + +static int auth_password(ssh_session session, const char *user, + const char *password, void *userdata){ + (void)userdata; + ssh_string banner = NULL; + printf("Authenticating user %s pwd %s\n",user, password); + if(strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){ + authenticated = 1; + printf("Authenticated\n"); + banner = ssh_string_from_char("Authenticated\n"); + ssh_send_issue_banner(session, banner); + ssh_string_free(banner); + return SSH_AUTH_SUCCESS; + } + if (tries >= 3){ + printf("Too many authentication tries\n"); + ssh_disconnect(session); + error = 1; + return SSH_AUTH_DENIED; + } + tries++; + return SSH_AUTH_DENIED; +} + +static int pty_request(ssh_session session, ssh_channel channel, const char *term, + int x,int y, int px, int py, void *userdata){ + (void) session; + (void) channel; + (void) userdata; + printf("Allocated terminal\n"); + printf("trem: %s, x: %d, y: %d, px: %d, py %d\n", term, x, y, px, py); + return 0; +} + +static int shell_request(ssh_session session, ssh_channel channel, void *userdata){ + (void)session; + (void)channel; + (void)userdata; + printf("Allocated shell\n"); + return 0; +} +struct ssh_channel_callbacks_struct channel_cb = { + .channel_pty_request_function = pty_request, + .channel_shell_request_function = shell_request +}; + +static ssh_channel new_session_channel(ssh_session session, void *userdata){ + (void) session; + (void) userdata; + if(chan != NULL) + return NULL; + printf("Allocated session channel\n"); + chan = ssh_channel_new(session); + ssh_callbacks_init(&channel_cb); + ssh_set_channel_callbacks(chan, &channel_cb); + return chan; +} + +int main(int argc, char **argv) +{ + ssh_session session = NULL; + ssh_bind sshbind = NULL; + ssh_event mainloop = NULL; + struct ssh_server_callbacks_struct cb = { + .userdata = NULL, + .auth_none_function = auth_none, + .auth_password_function = auth_password, + .channel_open_request_session_function = new_session_channel + }; + + char buf[BUF_SIZE]; + int i; + int r; + + sshbind=ssh_bind_new(); + session=ssh_new(); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, "11422"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, "0.0.0.0"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_IMPORT_KEY_STR, HOST_KEY); + + (void) argc; + (void) argv; + + if(ssh_bind_listen(sshbind)<0){ + printf("Error listening to socket: %s\n",ssh_get_error(sshbind)); + return 1; + } + r=ssh_bind_accept(sshbind,session); + if(r==SSH_ERROR){ + printf("error accepting a connection : %s\n",ssh_get_error(sshbind)); + return 1; + } + ssh_callbacks_init(&cb); + ssh_set_server_callbacks(session, &cb); + + if (ssh_handle_key_exchange(session)) { + printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); + return 1; + } + ssh_set_auth_methods(session,SSH_AUTH_METHOD_PASSWORD); + mainloop = ssh_event_new(); + ssh_event_add_session(mainloop, session); + + while (!(authenticated && chan != NULL)){ + if(error) + break; + r = ssh_event_dopoll(mainloop, -1); + if (r == SSH_ERROR){ + printf("Error : %s\n",ssh_get_error(session)); + ssh_disconnect(session); + return 1; + } + } + if(error){ + printf("Error, exiting loop\n"); + } else + printf("Authenticated and got a channel\n"); + do{ + i=ssh_channel_read(chan, buf, sizeof(buf) - 1, 0); + if(i>0) { + if (ssh_channel_write(chan, buf, i) == SSH_ERROR) { + printf("error writing to channel\n"); + return 1; + } + + buf[i] = '\0'; + printf("%s", buf); + fflush(stdout); + + if (buf[0] == '\x0d') { + if (ssh_channel_write(chan, "\n", 1) == SSH_ERROR) { + printf("error writing to channel\n"); + return 1; + } + + printf("\n"); + } + } + } while (i>0); + ssh_disconnect(session); + ssh_bind_free(sshbind); + ssh_finalize(); + return 0; +} \ No newline at end of file