static char * gfs_pio_local_storage_calculate_digest(GFS_File gf, char *digest_type, size_t digest_size, size_t *digest_lengthp, unsigned char *digest, file_offset_t *filesizep) { struct gfs_file_section_context *vc = gf->view_context; const EVP_MD *md_type; int rv; static int openssl_initialized = 0; if (!openssl_initialized) { SSLeay_add_all_algorithms(); /* for EVP_get_digestbyname() */ openssl_initialized = 1; } if ((md_type = EVP_get_digestbyname(digest_type)) == NULL) return (GFARM_ERR_INVALID_ARGUMENT); /* note that this effectively breaks file offset. */ rv = gfs_digest_calculate_local( vc->fd, gf->buffer, GFS_FILE_BUFSIZE, md_type, &vc->md_ctx, digest_lengthp, digest, filesizep); if (rv != 0) return (gfarm_errno_to_error(rv)); return (NULL); }
//02 002 void config_encryption(const char *password, const char *method) { SSLeay_add_all_algorithms(); sodium_init(); _method = encryption_method_from_string(method); if (_method == ENCRYPTION_TABLE) { get_table((unsigned char *) password); cipher = CIPHER_TABLE; } else if (_method == ENCRYPTION_SALSA20 || _method == ENCRYPTION_CHACHA20) { cipher = CIPHER_SODIUM; _key_len = 32; unsigned char tmp[EVP_MAX_IV_LENGTH];; EVP_BytesToKey(EVP_aes_256_cfb(), EVP_md5(), NULL, (unsigned char *)password, strlen(password), 1, _key, tmp); shadowsocks_key = _key; } else { cipher = CIPHER_OPENSSL; const char *name = shadowsocks_encryption_names[_method]; if (_method == ENCRYPTION_RC4_MD5) { name = "RC4"; } _cipher = EVP_get_cipherbyname(name); if (_cipher == NULL) { // assert(0); // TODO printf("_cipher is nil! \r\nThe %s doesn't supported!\r\n please chose anthor!",name); } else { unsigned char tmp[EVP_MAX_IV_LENGTH]; _key_len = EVP_BytesToKey(_cipher, EVP_md5(), NULL, (unsigned char *)password, strlen(password), 1, _key, tmp); shadowsocks_key = _key; } // printf("%d\n", _key_len); } }
void ssh_SSLeay_add_all_algorithms(void) { SSLeay_add_all_algorithms(); /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); }
void libcrypto_init(void) { /* Add all algorithms known by SSL */ #if OPENSSL_VERSION_NUMBER >= 0x00905100L OpenSSL_add_all_algorithms(); #else SSLeay_add_all_algorithms(); #endif }
ikptr ikrt_ssleay_add_all_algorithms (ikpcb * pcb) { #if ((defined HAVE_DECL_SSLEAY_ADD_ALL_ALGORITHMS) && HAVE_DECL_SSLEAY_ADD_ALL_ALGORITHMS) SSLeay_add_all_algorithms(); return IK_VOID; #else feature_failure(__func__); #endif }
static inline int tls_setup(shout_tls_t *tls) { SSL_METHOD *meth; SSL_library_init(); SSL_load_error_strings(); SSLeay_add_all_algorithms(); SSLeay_add_ssl_algorithms(); meth = TLSv1_client_method(); if (!meth) goto error; tls->ssl_ctx = SSL_CTX_new(meth); if (!tls->ssl_ctx) goto error; SSL_CTX_set_default_verify_paths(tls->ssl_ctx); SSL_CTX_load_verify_locations(tls->ssl_ctx, tls->ca_file, tls->ca_directory); SSL_CTX_set_verify(tls->ssl_ctx, SSL_VERIFY_NONE, NULL); if (tls->client_certificate) { if (SSL_CTX_use_certificate_file(tls->ssl_ctx, tls->client_certificate, SSL_FILETYPE_PEM) != 1) goto error; if (SSL_CTX_use_PrivateKey_file(tls->ssl_ctx, tls->client_certificate, SSL_FILETYPE_PEM) != 1) goto error; } if (SSL_CTX_set_cipher_list(tls->ssl_ctx, tls->allowed_ciphers) <= 0) goto error; SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY); tls->ssl = SSL_new(tls->ssl_ctx); if (!tls->ssl) goto error; if (!SSL_set_fd(tls->ssl, tls->socket)) goto error; SSL_set_tlsext_host_name(tls->ssl, tls->host); SSL_set_connect_state(tls->ssl); tls->ssl_ret = SSL_connect(tls->ssl); return SHOUTERR_SUCCESS; error: if (tls->ssl) SSL_free(tls->ssl); if (tls->ssl_ctx) SSL_CTX_free(tls->ssl_ctx); return SHOUTERR_UNSUPPORTED; }
/* //////////////////////////// PRIVATE/PROTECTED //////////////////////////////////// */ OsStatus OsEncryption::init(Direction direction) { OsStatus retval = OS_FAILED; #if defined(OSENCRYPTION) release(); if (mKeyLen > 0 && mKey != NULL && mDataLen > 0 && mData != NULL) { ERR_clear_error(); SSLeay_add_all_algorithms(); mAlgorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC, PKCS5_DEFAULT_ITER, mSalt, mSaltLen); if (mAlgorithm != NULL) { EVP_CIPHER_CTX_init(&(mContext)); if (EVP_PBE_CipherInit(mAlgorithm->algorithm, (const char *)mKey, mKeyLen, mAlgorithm->parameter, &(mContext), (int)direction)) { int blockSize = EVP_CIPHER_CTX_block_size(&mContext); int allocLen = mDataLen + mHeaderLen + blockSize + 1; // plus 1 for null terminator on decrypt mResults = (unsigned char *)OPENSSL_malloc(allocLen); if (mResults == NULL) { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not allocate cryption buffer(size=%d)", allocLen); } else { retval = OS_SUCCESS; } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cipher"); } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cryption algorithm"); } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "No encryption key(%d) or data(%d) set.\n", mKeyLen, mDataLen); } #endif return retval; }
int main(int argc, char **argv) { FILE *fp; EVP_PKEY *pkey; X509 *cert; STACK_OF(X509) *ca = NULL; PKCS12 *p12; int i; if (argc != 4) { fprintf(stderr, "Usage: pkread p12file password opfile\n"); exit (1); } SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); if (!(fp = fopen(argv[1], "rb"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); exit(1); } p12 = d2i_PKCS12_fp(fp, NULL); fclose (fp); if (!p12) { fprintf(stderr, "Error reading PKCS#12 file\n"); ERR_print_errors_fp(stderr); exit (1); } if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) { fprintf(stderr, "Error parsing PKCS#12 file\n"); ERR_print_errors_fp(stderr); exit (1); } PKCS12_free(p12); if (!(fp = fopen(argv[3], "w"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); exit(1); } if (pkey) { fprintf(fp, "***Private Key***\n"); PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); } if (cert) { fprintf(fp, "***User Certificate***\n"); PEM_write_X509_AUX(fp, cert); } if (ca && sk_X509_num(ca)) { fprintf(fp, "***Other Certificates***\n"); for (i = 0; i < sk_X509_num(ca); i++) PEM_write_X509_AUX(fp, sk_X509_value(ca, i)); } fclose(fp); return 0; }
static int ssl_init(GF_DownloadManager *dm, u32 mode) { SSL_METHOD *meth; if (!dm) return 0; /* The SSL has already been initialized. */ if (dm->ssl_ctx) return 1; /* Init the PRNG. If that fails, bail out. */ init_prng(); if (RAND_status() != 1) goto error; SSL_library_init(); SSL_load_error_strings(); SSLeay_add_all_algorithms(); SSLeay_add_ssl_algorithms(); switch (mode) { case 0: meth = SSLv23_client_method(); break; case 1: meth = SSLv2_client_method(); break; case 2: meth = SSLv3_client_method(); break; case 3: meth = TLSv1_client_method(); break; default: goto error; } dm->ssl_ctx = SSL_CTX_new(meth); if (!dm->ssl_ctx) goto error; SSL_CTX_set_default_verify_paths(dm->ssl_ctx); SSL_CTX_load_verify_locations (dm->ssl_ctx, NULL, NULL); /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the certificate is invalid. We verify the certificate separately in ssl_check_certificate, which provides much better diagnostics than examining the error stack after a failed SSL_connect. */ SSL_CTX_set_verify(dm->ssl_ctx, SSL_VERIFY_NONE, NULL); /* Since fd_write unconditionally assumes partial writes (and handles them correctly), allow them in OpenSSL. */ SSL_CTX_set_mode(dm->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); return 1; error: if (dm->ssl_ctx) SSL_CTX_free(dm->ssl_ctx); dm->ssl_ctx = NULL; return 0; }
AXIS2_EXTERN pkcs12_keystore_t * AXIS2_CALL pkcs12_keystore_create_from_buffer( const axutil_env_t *env, axis2_char_t *buffer, axis2_char_t *password, int len) { pkcs12_keystore_t *keystore = NULL; EVP_PKEY *pvt_key = NULL; SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); keystore = (pkcs12_keystore_t*) AXIS2_MALLOC(env->allocator, sizeof (pkcs12_keystore_t)); if (!keystore) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_CREATION_FAILED, "Memory allocation error!"); return NULL; } keystore->keystore_file = NULL; keystore->keystore_password = password; keystore->other_certs = NULL; keystore->keystore = NULL; keystore->cert = NULL; keystore->pvt_key = NULL; if (!openssl_pkcs12_load_from_buffer(env, buffer, &keystore->keystore, len)) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_DEFAULT, "Error loading pkcs12 keystore from file"); return NULL; } if (!openssl_pkcs12_parse( env, keystore->keystore_password, keystore->keystore, &pvt_key, &keystore->cert, &keystore->other_certs)) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_CREATION_FAILED, "PKCS12 Key Store Parsing failed."); AXIS2_FREE(env->allocator, keystore); return NULL; } /* We only populate this since openssl_pkey_t is ref counted. */ if (pvt_key) { keystore->pvt_key = openssl_pkey_create(env); openssl_pkey_populate(keystore->pvt_key, env, pvt_key, (axis2_char_t*) keystore->keystore_file, OPENSSL_PKEY_TYPE_PRIVATE_KEY); } return keystore; }
// Setup OpenSSL void __fastcall util_openssl_init() { char* tbuf[64]; #ifdef WIN32 HMODULE g_hAdvLib = NULL; BOOLEAN (APIENTRY *g_CryptGenRandomPtr)(void*, ULONG) = NULL; #endif #ifdef _POSIX int l; #endif /* #ifdef _DEBUG CRYPTO_malloc_debug_init(); //CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); MemCheck_start(); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif */ SSLeay_add_all_algorithms(); SSLeay_add_all_ciphers(); SSLeay_add_all_digests(); SSL_library_init(); // TWO LEAKS COMING FROM THIS LINE. Seems to be a well known OpenSSL problem. SSL_load_error_strings(); ERR_load_crypto_strings(); // ONE LEAK IN LINUX // Add more random seeding in Windows (This is probably useful since OpenSSL in Windows has weaker seeding) #ifdef WIN32 //RAND_screen(); // On Windows, add more random seeding using a screen dump (this is very expensive). if ((g_hAdvLib = LoadLibrary(TEXT("ADVAPI32.DLL"))) != 0) g_CryptGenRandomPtr = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(g_hAdvLib,"SystemFunction036"); if (g_CryptGenRandomPtr != 0 && g_CryptGenRandomPtr(tbuf, 64) != 0) RAND_add(tbuf, 64, 64); // Use this high quality random as added seeding if (g_hAdvLib != NULL) FreeLibrary(g_hAdvLib); #endif // Add more random seeding in Linux (May be overkill since OpenSSL already uses /dev/urandom) #ifdef _POSIX // Under Linux we use "/dev/urandom" if available. This is the best source of random on Linux & variants FILE *pFile = fopen("/dev/urandom","rb"); if (pFile != NULL) { l = fread(tbuf, 1, 64, pFile); fclose(pFile); if (l > 0) RAND_add(tbuf, l, l); } #endif }
HybridSslConnection* hybrid_ssl_connect(const gchar *hostname, gint port, ssl_callback func, gpointer user_data) { BIO *buf_io; BIO *ssl_bio; HybridSslConnection *conn; g_return_val_if_fail(hostname != NULL, NULL); g_return_val_if_fail(port != 0, NULL); g_return_val_if_fail(func != NULL, NULL); SSLeay_add_all_algorithms(); SSL_load_error_strings(); SSL_library_init(); conn = g_new0(HybridSslConnection, 1); if (!(conn->ssl_ctx = SSL_CTX_new(SSLv23_client_method()))) { hybrid_debug_error("ssl", "initialize SSL CTX: %s", ERR_reason_error_string(ERR_get_error())); hybrid_ssl_connection_destory(conn); return NULL; } if (!(conn->ssl = ssl_new_with_certs(conn->ssl_ctx))) { hybrid_ssl_connection_destory(conn); return NULL; } SSL_set_mode(conn->ssl, SSL_MODE_AUTO_RETRY); buf_io = BIO_new(BIO_f_buffer()); ssl_bio = BIO_new(BIO_f_ssl()); BIO_set_ssl(ssl_bio, conn->ssl, BIO_NOCLOSE); BIO_push(buf_io, ssl_bio); conn->conn_cb = func; conn->conn_data = user_data; conn->rbio = buf_io; conn->conn = hybrid_proxy_connect(hostname, port, ssl_connect_cb, conn); return conn; }
void config_encryption(const char *password, const char *method) { SSLeay_add_all_algorithms(); _method = encryption_method_from_string(method); if (_method != EncryptionTable) { const char *name = encryption_names[_method]; _cipher = EVP_get_cipherbyname(name); if (_cipher == NULL) { // assert(0); // TODO } unsigned char tmp[EVP_MAX_IV_LENGTH]; _key_len = EVP_BytesToKey(_cipher, EVP_md5(), NULL, password, strlen(password), 1, _key, tmp); } else { get_table(password); } }
openssl_env * initssl() { if (sslenv_svr == 0) { if (openssl_init == 0) { openssl_init = 1; #ifdef HAVE_OPENSSL SSL_library_init(); if (_options.debug) SSL_load_error_strings(); SSLeay_add_all_algorithms(); SSLeay_add_ssl_algorithms(); #else matrixSslOpen(); syslog(LOG_DEBUG, "MatrixSslOpen()"); #endif } openssl_env_init(sslenv_svr = calloc(1, sizeof(openssl_env)), 0, 1); } return sslenv_svr; }
openssl_env * initssl_cli() { if (sslenv_cli == 0) { if (openssl_init == 0) { openssl_init = 1; #ifdef HAVE_OPENSSL SSL_library_init(); /*if (_options.debug) */SSL_load_error_strings(); SSLeay_add_all_algorithms(); SSLeay_add_ssl_algorithms(); #else matrixSslOpen(); CP_ERROR(1,"MatrixSslOpen()"); #endif } openssl_env_init(sslenv_cli = calloc(1, sizeof(openssl_env)), 0, 0); } return sslenv_cli; }
static sslsock *addsock(int fd) { sslsock *p; #ifdef HAVE_GNUTLS gnutls_certificate_credentials_t xcred; #endif if (socks) socks = (sslsock *) realloc(socks, sizeof(sslsock)*++sockcount); else socks = (sslsock *) malloc(sizeof(sslsock)*++sockcount); p = &socks[sockcount-1]; #if defined(HAVE_OPENSSL) || defined(HAVE_NSS_COMPAT) if(!ctx) { SSL_library_init(); SSL_load_error_strings(); #ifdef HAVE_SSLEAY SSLeay_add_all_algorithms(); #elif HAVE_OPENSSL OpenSSL_add_all_algorithms(); #endif ctx = SSL_CTX_new(SSLv23_client_method()); } p->ssl = SSL_new(ctx); SSL_set_fd(p->ssl, p->fd = fd); #elif defined(HAVE_GNUTLS) gnutls_global_init (); gnutls_certificate_allocate_credentials (&xcred); gnutls_init (&(p->session), GNUTLS_CLIENT); gnutls_set_default_priority (p->session); gnutls_credentials_set (p->session, GNUTLS_CRD_CERTIFICATE, xcred); p->fd = fd; gnutls_transport_set_ptr(p->session,(gnutls_transport_ptr_t)fd); #endif return p; }
int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData = {0}; WSAStartup(MAKEWORD(2, 2), &wsaData); SSLeay_add_all_algorithms(); pthread_t pid; ERR_load_BIO_strings(); SSL_library_init(); SSL_load_error_strings(); SSL *ssl = NULL; SSL_CTX *ctx = NULL; //这里要注意是client ctx = SSL_CTX_new(TLSv1_client_method()); if (ctx == NULL) { printf("ssl ctx new eer\n"); exit(-1); } transf_lock_cs = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); transf_lock_count = (long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); for (int i = 0; i < CRYPTO_num_locks(); i++) { transf_lock_count[i] = 0; pthread_mutex_init(&(transf_lock_cs[i]), NULL); } CRYPTO_set_id_callback((unsigned long(*)())transf_pthreads_thread_id); CRYPTO_set_locking_callback(transf_client_locking_callback); pthread_create(&pid, NULL, tcp_forwardlistenthread, ctx); pthread_join(pid, NULL); system("pause"); getchar(); SSL_CTX_free(ctx); WSACleanup(); return 0; }
int main(int argc, char **argv) { FILE *fp; EVP_PKEY *pkey; X509 *cert; PKCS12 *p12; if (argc != 5) { fprintf(stderr, "Usage: pkwrite infile password name p12file\n"); exit(1); } SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); if (!(fp = fopen(argv[1], "r"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); exit(1); } cert = PEM_read_X509(fp, NULL, NULL, NULL); rewind(fp); pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); fclose(fp); p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0); if(!p12) { fprintf(stderr, "Error creating PKCS#12 structure\n"); ERR_print_errors_fp(stderr); exit(1); } if (!(fp = fopen(argv[4], "wb"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); ERR_print_errors_fp(stderr); exit(1); } i2d_PKCS12_fp(fp, p12); PKCS12_free(p12); fclose(fp); return 0; }
struct CertKeyPair generateCertKeyPair() { BIO *bio_err; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; PKCS12 *p12 = NULL; CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS); p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0); if (p12 == NULL) { printf("Error generating a valid PKCS12 certificate.\n"); } // Debug Print statements //RSA_print_fp(stdout, pkey->pkey.rsa, 0); //X509_print_fp(stdout, x509); //PEM_write_PUBKEY(stdout, pkey); //PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL); //PEM_write_X509(stdout, x509); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif CRYPTO_cleanup_all_ex_data(); CRYPTO_mem_leaks(bio_err); BIO_free(bio_err); return (CertKeyPair){x509, pkey, p12}; }
void config_encryption(const char *password, const char *method) { SSLeay_add_all_algorithms(); _method = encryption_method_from_string(method); if (_method != ENCRYPTION_TABLE) { const char *name = shadowsocks_encryption_names[_method]; _cipher = EVP_get_cipherbyname(name); if (_cipher == NULL) { // assert(0); // TODO printf("_cipher is nil! \r\nThe %s doesn't supported!\r\n please chose anthor!",name); } else { unsigned char tmp[EVP_MAX_IV_LENGTH]; _key_len = EVP_BytesToKey(_cipher, EVP_md5(), NULL, (unsigned char *)password, strlen(password), 1, (unsigned char *)_key, tmp); shadowsocks_key = _key; } // printf("%d\n", _key_len); } else { get_table((unsigned char *)password); } }
int init(int argc, char *argv[], struct sslCheckOptions *options) { SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); // Init... memset(options, 0, sizeof(struct sslCheckOptions)); // ToDo: //xmlArg = 0; strcpy(options->host, "127.0.0.1"); options->service[0] = '\0'; options->bindLocalAddress = false; options->forceAddressFamily = FORCE_AF_UNSPEC; options->noFailed = false; options->reneg = false; options->starttls_ftp = false; options->starttls_imap = false; options->starttls_pop3 = false; options->starttls_smtp = false; options->starttls_xmpp = false; options->verbose = false; options->targets = NULL; options->connection_delay = 0; options->connection_time.tv_sec = 0; options->connection_time.tv_usec = 0; options->ssl_versions = ssl_all; options->pout = false; options->scan_mode = SSLSCAN_SCAN_MODE_FAST; SSL_library_init(); #ifdef IS_PY3K wchar_t progname[255 + 1]; mbstowcs(progname, argv[0], strlen(argv[0]) + 1); Py_SetProgramName(progname); #else /* IS_PY3K */ Py_SetProgramName(argv[0]); #endif /* IS_PY3K */ Py_Initialize(); PyObject *py_tmp = PySys_GetObject("path"); //PyList_Append(py_tmp, PyUnicode_FromString("./python")); PyObject *py_module = PyImport_ImportModule("sslscan"); if (py_module == NULL) { PyErr_Print(); // ToDo: return 1; } PyObject *py_func = PyObject_GetAttrString(py_module, "load_handlers"); if(py_func == NULL) { PyErr_Print(); // ToDo: return 1; } PyObject *py_args = PyTuple_New(0); PyObject *py_result = PyObject_CallObject(py_func, py_args); if(py_result == NULL) { PyErr_Print(); // ToDo: return 1; } options->py_config = PyObject_GetAttrString(py_module, "config"); options->py_output_handler = PyObject_GetAttrString(py_module, "output"); options->py_service_handler = PyObject_GetAttrString(py_module, "service"); return 0; }
/** * \fn resultP12ToPem p12ToPem (string, string) * \brief Convert P12 to PEM * \param string p12File Path to P12 file * \param string p12Passwd Password to open P12 file * \return result (bool ReturnCode, Int ErrorCode, String Comment, String PrivateKey, String Certificate) */ resultP12ToPem p12ToPem(string p12File, string p12Passwd) { FILE *fp; PKCS12 *p12 = NULL; EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca = NULL; BIO *o = BIO_new(BIO_s_mem()); string privateKey = ""; string certificate = ""; resultP12ToPem ret; ret.ReturnCode = false; ret.ErrorCode = 0; ret.Comment = ""; ret.PrivateKey = ""; ret.Certificate = ""; SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); if(!(fp = fopen(p12File.c_str(), "rb"))) { ret.ErrorCode = 1; ret.Comment = strerror(errno); return ret; } p12 = d2i_PKCS12_fp(fp, &p12); fclose (fp); if (!p12) { ret.ErrorCode = 2; ret.Comment = "Unable to open PKCS#12 file"; return ret; } if (!PKCS12_parse(p12, p12Passwd.c_str(), &pkey, &cert, &ca)) { ret.ErrorCode = 3; ret.Comment = "Unable to parse PKCS#12 file (wrong password ?)"; return ret; } PKCS12_free(p12); if (!(pkey && cert)) { ret.ErrorCode = 4; ret.Comment = "Certificate and/or key file doesn't exists"; } else { PEM_write_bio_PrivateKey(o, pkey, 0, 0, 0, NULL, 0); privateKey = x509ToString(o); PEM_write_bio_X509(o, cert); certificate = x509ToString(o); BIO_free(o); ret.ReturnCode = true; ret.ErrorCode = 0; ret.Comment = "All is fine"; ret.PrivateKey = privateKey; ret.Certificate = certificate; } return ret; }
bool ssl_init () { SSL_METHOD *meth; if (ssl_ctx) /* The SSL has already been initialized. */ return true; /* Init the PRNG. If that fails, bail out. */ init_prng (); if (RAND_status () != 1) { logprintf (LOG_NOTQUIET, _("Could not seed PRNG; consider using --random-file.\n")); goto error; } SSL_library_init (); SSL_load_error_strings (); SSLeay_add_all_algorithms (); SSLeay_add_ssl_algorithms (); switch (opt.secure_protocol) { case secure_protocol_auto: meth = SSLv23_client_method (); break; case secure_protocol_sslv2: meth = SSLv2_client_method (); break; case secure_protocol_sslv3: meth = SSLv3_client_method (); break; case secure_protocol_tlsv1: meth = TLSv1_client_method (); break; default: abort (); } ssl_ctx = SSL_CTX_new (meth); if (!ssl_ctx) goto error; SSL_CTX_set_default_verify_paths (ssl_ctx); SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory); /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the certificate is invalid. We verify the certificate separately in ssl_check_certificate, which provides much better diagnostics than examining the error stack after a failed SSL_connect. */ SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL); if (opt.cert_file) if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file, key_type_to_ssl_type (opt.cert_type)) != 1) goto error; if (opt.private_key) if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key, key_type_to_ssl_type (opt.private_key_type)) != 1) goto error; /* Since fd_write unconditionally assumes partial writes (and handles them correctly), allow them in OpenSSL. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); /* The OpenSSL library can handle renegotiations automatically, so tell it to do so. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY); return true; error: if (ssl_ctx) SSL_CTX_free (ssl_ctx); print_errors (); return false; }
/* * Main program for the daemon. */ int main(int ac, char **av) { extern char *optarg; extern int optind; int opt, j, i, fdsetsz, on = 1; int sock_in = -1, sock_out = -1, newsock = -1; pid_t pid; socklen_t fromlen; fd_set *fdset; struct sockaddr_storage from; const char *remote_ip; int remote_port; FILE *f; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; char *line; int listen_sock, maxfd; int startup_p[2], config_s[2]; int startups = 0; Key *key; Authctxt *authctxt; int ret, key_used = 0; Buffer cfg; char *pt; u_short ports[2] = {0,0}; /* Default MITM options */ memset(&mopt, 0x00, sizeof(mopt)); mopt.r_port = htons(22); mopt.resolve = 1; if (av[1] == NULL) usage(); /* Get route */ if ( (pt = strchr(av[1], ':')) != NULL) *pt++ = '\0'; if ( (long)(mopt.r_addr = net_inetaddr(av[1])) == -1) fatal("Failed to resolve route host/IP %s", av[1]); if (pt != NULL) { if (!ISPORT(atoi(pt))) fatal("Bad port number in route '%s'", pt); mopt.r_port = htons(atoi(pt)); } logit("Using static route to %s", net_sockstr_ip(mopt.r_addr, mopt.r_port, 0)); #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); #endif __progname = ssh_get_progname(av[0]); init_rng(); /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1)); for (i = 0; i < ac; i++) saved_argv[i] = xstrdup(av[i]); saved_argv[i] = NULL; #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ compat_init_setproctitle(ac, av); av = saved_argv; #endif if (geteuid() == 0 && setgroups(0, NULL) == -1) debug("setgroups(): %.200s", strerror(errno)); /* Initialize configuration options to their default values. */ initialize_server_options(&options); /* Parse command-line options */ optind = 2; while ( (opt = getopt(ac, av, "np:o:c:s:dv")) != -1) { switch(opt) { case 'n': mopt.resolve = 0; break; case 'd': if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; } else if (options.log_level < SYSLOG_LEVEL_DEBUG4) options.log_level++; break; case 'o': options.passwdlog = optarg; break; case 'c': options.c_logdir = optarg; break; case 's': options.s_logdir = optarg; break; case 'v': options.log_level = SYSLOG_LEVEL_VERBOSE; break; case 'p': options.ports_from_cmdline = 1; if (options.num_ports >= MAX_PORTS) { fprintf(stderr, "too many ports.\n"); exit(1); } options.ports[options.num_ports++] = a2port(optarg); if (options.ports[options.num_ports-1] == 0) { fprintf(stderr, "Bad port number.\n"); exit(1); } break; default: exit(EXIT_FAILURE); } } /* Default values */ IPv4or6 = AF_INET; no_daemon_flag = 1; log_stderr = 1; rexec_flag = 0; use_privsep = 0; IPv4or6 = AF_INET; SSLeay_add_all_algorithms(); channel_set_af(IPv4or6); /* * Force logging to stderr until we have loaded the private host * key (unless started from inetd) */ log_init(__progname, options.log_level == SYSLOG_LEVEL_NOT_SET ? SYSLOG_LEVEL_INFO : options.log_level, options.log_facility == SYSLOG_FACILITY_NOT_SET ? SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag); //target_connect(net_inetaddr("10.0.0.1"), htons(22), 2, SSH_PROTO_2); //exit(1); #ifdef _AIX /* * Unset KRB5CCNAME, otherwise the user's session may inherit it from * root's environment */ unsetenv("KRB5CCNAME"); #endif /* _AIX */ #ifdef _UNICOS /* Cray can define user privs drop all privs now! * Not needed on PRIV_SU systems! */ drop_cray_privs(); #endif seed_rng(); sensitive_data.server_key = NULL; sensitive_data.ssh1_host_key = NULL; sensitive_data.have_ssh1_key = 0; sensitive_data.have_ssh2_key = 0; /* Fetch our configuration */ buffer_init(&cfg); if (rexeced_flag) recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); else load_server_config(config_file_name, &cfg); parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, &cfg); if (!rexec_flag) buffer_free(&cfg); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); /* Check that there are no remaining arguments. */ if (optind < ac) { fprintf(stderr, "Extra argument %s.\n", av[optind]); exit(1); } debug("sshd version %.100s", SSH_VERSION); /* load private host keys */ sensitive_data.host_keys = xmalloc(options.num_host_key_files * sizeof(Key *)); for (i = 0; i < options.num_host_key_files; i++) sensitive_data.host_keys[i] = NULL; for (i = 0; i < options.num_host_key_files; i++) { key = key_load_private(options.host_key_files[i], "", NULL); sensitive_data.host_keys[i] = key; if (key == NULL) { error("Could not load host key: %s", options.host_key_files[i]); sensitive_data.host_keys[i] = NULL; continue; } switch (key->type) { case KEY_RSA1: sensitive_data.ssh1_host_key = key; sensitive_data.have_ssh1_key = 1; break; case KEY_RSA: case KEY_DSA: sensitive_data.have_ssh2_key = 1; break; } debug("private host key: #%d type %d %s", i, key->type, key_type(key)); } if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { logit("Disabling protocol version 2. Could not load host key"); options.protocol &= ~SSH_PROTO_2; } if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); } /* Check certain values for sanity. */ if (options.protocol & SSH_PROTO_1) { if (options.server_key_bits < 512 || options.server_key_bits > 32768) { fprintf(stderr, "Bad server key size.\n"); exit(1); } /* * Check that server and host key lengths differ sufficiently. This * is necessary to make double encryption work with rsaref. Oh, I * hate software patents. I dont know if this can go? Niels */ if (options.server_key_bits > BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED && options.server_key_bits < BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { options.server_key_bits = BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED; debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits); } } if (use_privsep) { struct passwd *pw; struct stat st; if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) fatal("Privilege separation user %s does not exist", SSH_PRIVSEP_USER); if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) fatal("Missing privilege separation directory: %s", _PATH_PRIVSEP_CHROOT_DIR); #ifdef HAVE_CYGWIN if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && (st.st_uid != getuid () || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) #else if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) #endif fatal("%s must be owned by root and not group or " "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); } /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); /* * Clear out any supplemental groups we may have inherited. This * prevents inadvertent creation of files with bad modes (in the * portable version at least, it's certainly possible for PAM * to create a file, and we can't control the code in every * module which might be used). */ if (setgroups(0, NULL) < 0) debug("setgroups() failed: %.200s", strerror(errno)); if (rexec_flag) { rexec_argv = xmalloc(sizeof(char *) * (rexec_argc + 2)); for (i = 0; i < rexec_argc; i++) { debug("rexec_argv[%d]='%s'", i, saved_argv[i]); rexec_argv[i] = saved_argv[i]; } rexec_argv[rexec_argc] = "-R"; rexec_argv[rexec_argc + 1] = NULL; } /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && !inetd_flag) log_stderr = 1; log_init(__progname, options.log_level, options.log_facility, log_stderr); /* * If not in debugging mode, and not started from inetd, disconnect * from the controlling terminal, and fork. The original process * exits. */ if (!(debug_flag || inetd_flag || no_daemon_flag)) { #ifdef TIOCNOTTY int fd; #endif /* TIOCNOTTY */ if (daemon(0, 0) < 0) fatal("daemon() failed: %.200s", strerror(errno)); /* Disconnect from the controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ } /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* Initialize the random number generator. */ arc4random_stir(); /* Chdir to the root directory so that the current disk can be unmounted if desired. */ chdir("/"); /* ignore SIGPIPE */ signal(SIGPIPE, SIG_IGN); /* Start listening for a socket, unless started from inetd. */ if (inetd_flag) { int fd; startup_pipe = -1; if (rexeced_flag) { close(REEXEC_CONFIG_PASS_FD); sock_in = sock_out = dup(STDIN_FILENO); if (!debug_flag) { startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); close(REEXEC_STARTUP_PIPE_FD); } } else { sock_in = dup(STDIN_FILENO); sock_out = dup(STDOUT_FILENO); } /* * We intentionally do not close the descriptors 0, 1, and 2 * as our code for setting the descriptors won't work if * ttyfd happens to be one of those. */ if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); if (fd > STDOUT_FILENO) close(fd); } debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); if ((options.protocol & SSH_PROTO_1) && sensitive_data.server_key == NULL) generate_ephemeral_server_key(); } else { for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; if (num_listen_socks >= MAX_LISTEN_SOCKS) fatal("Too many listen sockets. " "Enlarge MAX_LISTEN_SOCKS"); if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("getnameinfo failed"); continue; } /* Create socket for listening. */ listen_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (listen_sock < 0) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); continue; } if (set_nonblock(listen_sock) == -1) { close(listen_sock); continue; } /* * Set socket options. * Allow local port reuse in TIME_WAIT. */ if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); debug("Bind to port %s on %s.", strport, ntop); /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { if (!ai->ai_next) error("Bind to port %s on %s failed: %.200s.", strport, ntop, strerror(errno)); close(listen_sock); continue; } listen_socks[num_listen_socks] = listen_sock; num_listen_socks++; /* Start listening on the port. */ logit("SSH MITM Server listening on %s port %s.", ntop, strport); if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) fatal("listen: %.100s", strerror(errno)); } freeaddrinfo(options.listen_addrs); if (!num_listen_socks) fatal("Cannot bind any address."); if (options.protocol & SSH_PROTO_1) generate_ephemeral_server_key(); /* * Arrange to restart on SIGHUP. The handler needs * listen_sock. */ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); /* Arrange SIGCHLD to be caught. */ signal(SIGCHLD, main_sigchld_handler); /* Write out the pid file after the sigterm handler is setup */ if (!debug_flag) { /* * Record our pid in /var/run/sshd.pid to make it * easier to kill the correct sshd. We don't want to * do this before the bind above because the bind will * fail if there already is a daemon, and this will * overwrite any old pid in the file. */ f = fopen(options.pid_file, "wb"); if (f == NULL) { error("Couldn't create pid file \"%s\": %s", options.pid_file, strerror(errno)); } else { fprintf(f, "%ld\n", (long) getpid()); fclose(f); } } /* setup fd set for listen */ fdset = NULL; maxfd = 0; for (i = 0; i < num_listen_socks; i++) if (listen_socks[i] > maxfd) maxfd = listen_socks[i]; /* pipes connected to unauthenticated childs */ startup_pipes = xmalloc(options.max_startups * sizeof(int)); for (i = 0; i < options.max_startups; i++) startup_pipes[i] = -1; /* * Stay listening for connections until the system crashes or * the daemon is killed with a signal. */ for (;;) { if (received_sighup) sighup_restart(); if (fdset != NULL) xfree(fdset); fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); fdset = (fd_set *)xmalloc(fdsetsz); memset(fdset, 0, fdsetsz); for (i = 0; i < num_listen_socks; i++) FD_SET(listen_socks[i], fdset); for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1) FD_SET(startup_pipes[i], fdset); /* Wait in select until there is a connection. */ ret = select(maxfd+1, fdset, NULL, NULL, NULL); if (ret < 0 && errno != EINTR) error("select: %.100s", strerror(errno)); if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); close_listen_socks(); unlink(options.pid_file); exit(255); } if (key_used && key_do_regen) { generate_ephemeral_server_key(); key_used = 0; key_do_regen = 0; } if (ret < 0) continue; for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1 && FD_ISSET(startup_pipes[i], fdset)) { /* * the read end of the pipe is ready * if the child has closed the pipe * after successful authentication * or if the child has died */ close(startup_pipes[i]); startup_pipes[i] = -1; startups--; } for (i = 0; i < num_listen_socks; i++) { if (!FD_ISSET(listen_socks[i], fdset)) continue; fromlen = sizeof(from); debug("Awaiting client"); newsock = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen); if (newsock < 0) { if (errno != EINTR && errno != EWOULDBLOCK) error("accept: %.100s", strerror(errno)); continue; } if (unset_nonblock(newsock) == -1) { close(newsock); continue; } if (drop_connection(startups) == 1) { debug("drop connection #%d", startups); close(newsock); continue; } if (pipe(startup_p) == -1) { close(newsock); continue; } if (rexec_flag && socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) { error("reexec socketpair: %s", strerror(errno)); close(newsock); close(startup_p[0]); close(startup_p[1]); continue; } for (j = 0; j < options.max_startups; j++) if (startup_pipes[j] == -1) { startup_pipes[j] = startup_p[0]; if (maxfd < startup_p[0]) maxfd = startup_p[0]; startups++; break; } /* * Got connection. Fork a child to handle it, unless * we are in debugging mode. */ if (debug_flag) { /* * In debugging mode. Close the listening * socket, and start processing the * connection without forking. */ debug("Server will not fork when running in debugging mode."); close_listen_socks(); sock_in = newsock; sock_out = newsock; close(startup_p[0]); close(startup_p[1]); startup_pipe = -1; pid = getpid(); if (rexec_flag) { send_rexec_state(config_s[0], &cfg); close(config_s[0]); } break; } else { /* * Normal production daemon. Fork, and have * the child process the connection. The * parent continues listening. */ if ((pid = fork()) == 0) { /* * Child. Close the listening and max_startup * sockets. Start using the accepted socket. * Reinitialize logging (since our pid has * changed). We break out of the loop to handle * the connection. */ startup_pipe = startup_p[1]; close_startup_pipes(); close_listen_socks(); sock_in = newsock; sock_out = newsock; log_init(__progname, options.log_level, options.log_facility, log_stderr); close(config_s[0]); break; } } /* Parent. Stay in the loop. */ if (pid < 0) error("fork: %.100s", strerror(errno)); else debug("Forked child %ld.", (long)pid); close(startup_p[1]); if (rexec_flag) { send_rexec_state(config_s[0], &cfg); close(config_s[0]); close(config_s[1]); } /* Mark that the key has been used (it was "given" to the child). */ if ((options.protocol & SSH_PROTO_1) && key_used == 0) { /* Schedule server key regeneration alarm. */ signal(SIGALRM, key_regeneration_alarm); alarm(options.key_regeneration_time); key_used = 1; } arc4random_stir(); /* Close the new socket (the child is now taking care of it). */ close(newsock); } /* child process check (or debug mode) */ if (num_listen_socks < 0) break; } } /* This is the child processing a new connection. */ setproctitle("%s", "[MITM]"); log_init("mitm-server", options.log_level, options.log_facility, log_stderr); alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); packet_set_connection(sock_in, sock_out); sshd_exchange_identification(sock_in, sock_out); packet_set_nonblocking(); /* perform the key exchange */ if (compat20) do_ssh2_kex(); else do_ssh1_kex(); mitm_ssh(sock_in); /* Unreached */ exit(1); }
/* * Main program for the ssh client. */ int main(int ac, char **av) { int i, opt, exit_status, use_syslog; char *p, *cp, *line, buf[256]; struct stat st; struct passwd *pw; int dummy, timeout_ms; extern int optind, optreset; extern char *optarg; struct servent *sp; Forward fwd; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); __progname = ssh_get_progname(av[0]); init_rng(); /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). */ original_real_uid = getuid(); original_effective_uid = geteuid(); /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are * ready to create the privileged port, and will permanently drop * them when the port has been created (actually, when the connection * has been made, as we may need to create the port several times). */ PRIV_END; #ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } #endif /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { logit("You don't exist, go away!"); exit(255); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); /* * Set our umask to something reasonable, as some files are created * with the default umask. This will make them world-readable but * writable only by the owner, which is ok for all files for which we * don't set the modes explicitly. */ umask(022); /* * Initialize option structure to indicate that no values have been * set. */ initialize_options(&options); /* Parse command-line arguments. */ host = NULL; use_syslog = 0; again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; break; case '2': options.protocol = SSH_PROTO_2; break; case '4': options.address_family = AF_INET; break; case '6': options.address_family = AF_INET6; break; case 'n': stdin_null_flag = 1; break; case 'f': fork_after_authentication_flag = 1; stdin_null_flag = 1; break; case 'x': options.forward_x11 = 0; break; case 'X': options.forward_x11 = 1; break; case 'y': use_syslog = 1; break; case 'Y': options.forward_x11 = 1; options.forward_x11_trusted = 1; break; case 'g': options.gateway_ports = 1; break; case 'O': if (strcmp(optarg, "check") == 0) muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; else if (strcmp(optarg, "exit") == 0) muxclient_command = SSHMUX_COMMAND_TERMINATE; else fatal("Invalid multiplex command."); break; case 'P': /* deprecated */ options.use_privileged_port = 0; break; case 'a': options.forward_agent = 0; break; case 'A': options.forward_agent = 1; break; case 'k': options.gss_deleg_creds = 0; break; case 'K': options.gss_authentication = 1; options.gss_deleg_creds = 1; break; case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " "not accessible: %s.\n", optarg, strerror(errno)); break; } if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) fatal("Too many identity files specified " "(max %d)", SSH_MAX_IDENTITY_FILES); options.identity_files[options.num_identity_files++] = xstrdup(optarg); break; case 'I': #ifdef SMARTCARD options.smartcard_device = xstrdup(optarg); #else fprintf(stderr, "no support for smartcards.\n"); #endif break; case 't': if (tty_flag) force_tty_flag = 1; tty_flag = 1; break; case 'v': if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; } else { if (options.log_level < SYSLOG_LEVEL_DEBUG3) options.log_level++; break; } /* FALLTHROUGH */ case 'V': fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); if (opt == 'V') exit(0); break; case 'w': if (options.tun_open == -1) options.tun_open = SSH_TUNMODE_DEFAULT; options.tun_local = a2tun(optarg, &options.tun_remote); if (options.tun_local == SSH_TUNID_ERR) { fprintf(stderr, "Bad tun device '%s'\n", optarg); exit(255); } break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': if (optarg[0] == '^' && optarg[2] == 0 && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; else if (strlen(optarg) == 1) options.escape_char = (u_char) optarg[0]; else if (strcmp(optarg, "none") == 0) options.escape_char = SSH_ESCAPECHAR_NONE; else { fprintf(stderr, "Bad escape character '%s'.\n", optarg); exit(255); } break; case 'c': if (ciphers_valid(optarg)) { /* SSH2 only */ options.ciphers = xstrdup(optarg); options.cipher = SSH_CIPHER_INVALID; } else { /* SSH1 only */ options.cipher = cipher_number(optarg); if (options.cipher == -1) { fprintf(stderr, "Unknown cipher type '%s'\n", optarg); exit(255); } if (options.cipher == SSH_CIPHER_3DES) options.ciphers = "3des-cbc"; else if (options.cipher == SSH_CIPHER_BLOWFISH) options.ciphers = "blowfish-cbc"; else options.ciphers = (char *)-1; } break; case 'm': if (mac_valid(optarg)) options.macs = xstrdup(optarg); else { fprintf(stderr, "Unknown mac type '%s'\n", optarg); exit(255); } break; case 'M': if (options.control_master == SSHCTL_MASTER_YES) options.control_master = SSHCTL_MASTER_ASK; else options.control_master = SSHCTL_MASTER_YES; break; case 'p': options.port = a2port(optarg); if (options.port <= 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(255); } break; case 'l': options.user = optarg; break; case 'L': if (parse_forward(&fwd, optarg, 0, 0)) add_local_forward(&options, &fwd); else { fprintf(stderr, "Bad local forwarding specification '%s'\n", optarg); exit(255); } break; case 'R': if (parse_forward(&fwd, optarg, 0, 1)) { add_remote_forward(&options, &fwd); } else { fprintf(stderr, "Bad remote forwarding specification " "'%s'\n", optarg); exit(255); } break; case 'D': if (parse_forward(&fwd, optarg, 1, 0)) { add_local_forward(&options, &fwd); } else { fprintf(stderr, "Bad dynamic forwarding specification " "'%s'\n", optarg); exit(255); } break; case 'C': options.compression = 1; break; case 'N': no_shell_flag = 1; no_tty_flag = 1; break; case 'T': no_tty_flag = 1; break; case 'o': dummy = 1; line = xstrdup(optarg); if (process_config_line(&options, host ? host : "", line, "command-line", 0, &dummy) != 0) exit(255); xfree(line); break; case 's': subsystem_flag = 1; break; case 'S': if (options.control_path != NULL) free(options.control_path); options.control_path = xstrdup(optarg); break; case 'b': options.bind_address = optarg; break; case 'F': config = optarg; break; default: usage(); } } ac -= optind; av += optind; if (ac > 0 && !host && **av != '-') { if (strrchr(*av, '@')) { p = xstrdup(*av); cp = strrchr(p, '@'); if (cp == NULL || cp == p) usage(); options.user = p; *cp = '\0'; host = ++cp; } else host = *av; if (ac > 1) { optind = optreset = 1; goto again; } ac--, av++; } /* Check that we got a host name. */ if (!host) usage(); SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); /* Initialize the command to execute on remote host. */ buffer_init(&command); /* * Save the command to execute on the remote host in a buffer. There * is no limit on the length of the command, except by the maximum * packet size. Also sets the tty flag if there is no command. */ if (!ac) { /* No command specified - execute shell on a tty. */ tty_flag = 1; if (subsystem_flag) { fprintf(stderr, "You must specify a subsystem to invoke.\n"); usage(); } } else { /* A command has been specified. Store it into the buffer. */ for (i = 0; i < ac; i++) { if (i) buffer_append(&command, " ", 1); buffer_append(&command, av[i], strlen(av[i])); } } /* Cannot fork to background if no command. */ if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) fatal("Cannot fork into background without a command " "to execute."); /* Allocate a tty by default if no command specified. */ if (buffer_len(&command) == 0) tty_flag = 1; /* Force no tty */ if (no_tty_flag) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { if (tty_flag) logit("Pseudo-terminal will not be allocated because " "stdin is not a terminal."); tty_flag = 0; } /* * Initialize "log" output. Since we are the client all output * actually goes to stderr. */ log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, !use_syslog); /* * Read per-user configuration file. Ignore the system wide config * file if the user specifies a config file on the command line. */ if (config != NULL) { if (!read_config_file(config, host, &options, 0)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); (void)read_config_file(buf, host, &options, 1); /* Read systemwide configuration file after use config. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options, 0); } /* Fill configuration defaults. */ fill_default_options(&options); channel_set_af(options.address_family); /* reinit */ log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog); seed_rng(); if (options.user == NULL) options.user = xstrdup(pw->pw_name); /* Get default port if port has not been set. */ if (options.port == 0) { sp = getservbyname(SSH_SERVICE_NAME, "tcp"); options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; } if (options.local_command != NULL) { char thishost[NI_MAXHOST]; if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); snprintf(buf, sizeof(buf), "%d", options.port); debug3("expanding LocalCommand: %s", options.local_command); cp = options.local_command; options.local_command = percent_expand(cp, "d", pw->pw_dir, "h", options.hostname? options.hostname : host, "l", thishost, "n", host, "r", options.user, "p", buf, "u", pw->pw_name, (char *)NULL); debug3("expanded LocalCommand: %s", options.local_command); xfree(cp); } if (options.hostname != NULL) host = options.hostname; /* force lowercase for hostkey matching */ if (options.host_key_alias != NULL) { for (p = options.host_key_alias; *p; p++) if (isupper(*p)) *p = (char)tolower(*p); } if (options.proxy_command != NULL && strcmp(options.proxy_command, "none") == 0) { xfree(options.proxy_command); options.proxy_command = NULL; } if (options.control_path != NULL && strcmp(options.control_path, "none") == 0) { xfree(options.control_path); options.control_path = NULL; } if (options.control_path != NULL) { char thishost[NI_MAXHOST]; if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); snprintf(buf, sizeof(buf), "%d", options.port); cp = tilde_expand_filename(options.control_path, original_real_uid); xfree(options.control_path); options.control_path = percent_expand(cp, "p", buf, "h", host, "r", options.user, "l", thishost, (char *)NULL); xfree(cp); } if (muxclient_command != 0 && options.control_path == NULL) fatal("No ControlPath specified for \"-O\" command"); if (options.control_path != NULL) muxclient(options.control_path); timeout_ms = options.connection_timeout * 1000; /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, options.address_family, options.connection_attempts, &timeout_ms, options.tcp_keep_alive, #ifdef HAVE_CYGWIN options.use_privileged_port, #else original_effective_uid == 0 && options.use_privileged_port, #endif options.proxy_command) != 0) exit(255); if (timeout_ms > 0) debug3("timeout: %d ms remain after connect", timeout_ms); /* * If we successfully made the connection, load the host private key * in case we will need it later for combined rsa-rhosts * authentication. This must be done before releasing extra * privileges, because the file is only readable by root. * If we cannot access the private keys, load the public keys * instead and try to execute the ssh-keysign helper instead. */ sensitive_data.nkeys = 0; sensitive_data.keys = NULL; sensitive_data.external_keysign = 0; if (options.rhosts_rsa_authentication || options.hostbased_authentication) { sensitive_data.nkeys = 3; sensitive_data.keys = xcalloc(sensitive_data.nkeys, sizeof(Key)); PRIV_START; sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL, NULL); sensitive_data.keys[1] = key_load_private_type(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); sensitive_data.keys[2] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); PRIV_END; if (options.hostbased_authentication == 1 && sensitive_data.keys[0] == NULL && sensitive_data.keys[1] == NULL && sensitive_data.keys[2] == NULL) { sensitive_data.keys[1] = key_load_public( _PATH_HOST_DSA_KEY_FILE, NULL); sensitive_data.keys[2] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } } /* * Get rid of any extra privileges that we may have. We will no * longer need them. Also, extra privileges could make it very hard * to read identity files and other non-world-readable files from the * user's home directory if it happens to be on a NFS volume where * root is mapped to nobody. */ if (original_effective_uid == 0) { PRIV_START; permanently_set_uid(pw); } /* * Now that we are back to our own permissions, create ~/.ssh * directory if it doesn't already exist. */ snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); if (stat(buf, &st) < 0) if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); /* load options.identity_files */ load_public_identity_files(); /* Expand ~ in known host file names. */ /* XXX mem-leaks: */ options.system_hostfile = tilde_expand_filename(options.system_hostfile, original_real_uid); options.user_hostfile = tilde_expand_filename(options.user_hostfile, original_real_uid); options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, original_real_uid); options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, original_real_uid); signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw, timeout_ms); /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { if (sensitive_data.keys[i] != NULL) { /* Destroys contents safely */ debug3("clear hostkey %d", i); key_free(sensitive_data.keys[i]); sensitive_data.keys[i] = NULL; } } xfree(sensitive_data.keys); } for (i = 0; i < options.num_identity_files; i++) { if (options.identity_files[i]) { xfree(options.identity_files[i]); options.identity_files[i] = NULL; } if (options.identity_keys[i]) { key_free(options.identity_keys[i]); options.identity_keys[i] = NULL; } } exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child */ if (proxy_command_pid > 1) kill(proxy_command_pid, SIGHUP); return exit_status; }
int main(int argc, char **argv) { Buffer b; Options options; Key *keys[2], *key = NULL; struct passwd *pw; int key_fd[2], i, found, version = 2, fd; u_char *signature, *data; char *host; u_int slen, dlen; u_int32_t rnd[256]; /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) exit(1); /* Leave /dev/null fd iff it is attached to stderr */ if (fd > 2) close(fd); key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); original_real_uid = getuid(); /* XXX readconf.c needs this */ if ((pw = getpwuid(original_real_uid)) == NULL) fatal("getpwuid failed"); pw = pwcopy(pw); permanently_set_uid(pw); init_rng(); seed_rng(); arc4random_stir(); #ifdef DEBUG_SSH_KEYSIGN log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); #endif /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", _PATH_HOST_CONFIG_FILE); if (key_fd[0] == -1 && key_fd[1] == -1) fatal("could not open any host key"); SSLeay_add_all_algorithms(); for (i = 0; i < 256; i++) rnd[i] = arc4random(); RAND_seed(rnd, sizeof(rnd)); found = 0; for (i = 0; i < 2; i++) { keys[i] = NULL; if (key_fd[i] == -1) continue; keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, NULL, NULL); close(key_fd[i]); if (keys[i] != NULL) found = 1; } if (!found) fatal("no hostkey found"); buffer_init(&b); if (ssh_msg_recv(STDIN_FILENO, &b) < 0) fatal("ssh_msg_recv failed"); if (buffer_get_char(&b) != version) fatal("bad version"); fd = buffer_get_int(&b); if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) fatal("bad fd"); if ((host = get_local_name(fd)) == NULL) fatal("cannot get sockname for fd"); data = buffer_get_string(&b, &dlen); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); xfree(host); found = 0; for (i = 0; i < 2; i++) { if (keys[i] != NULL && key_equal(key, keys[i])) { found = 1; break; } } if (!found) fatal("no matching hostkey found"); if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) fatal("key_sign failed"); xfree(data); /* send reply */ buffer_clear(&b); buffer_put_string(&b, signature, slen); if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1) fatal("ssh_msg_send failed"); return (0); }
int ssh_main(int ac, char **av) { if ( ac < 5 ) { printf("usage: <user> <host> <password> <cmd>\n"); return ( -1 ); } int i, r, exit_status, use_syslog; char *argv0, buf[MAXPATHLEN]; struct stat st; struct passwd *pw; int timeout_ms; Sensitive sensitive_data; extern int optind, optreset; extern char *optarg; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ // sanitise_stdfd(); __progname = ssh_get_progname(av[0]); init_rng(); /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). */ original_real_uid = getuid(); original_effective_uid = geteuid(); /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are * ready to create the privileged port, and will permanently drop * them when the port has been created (actually, when the connection * has been made, as we may need to create the port several times). */ PRIV_END; #ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } #endif /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { logit("You don't exist, go away!"); return (-1); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); /* * Set our umask to something reasonable, as some files are created * with the default umask. This will make them world-readable but * writable only by the owner, which is ok for all files for which we * don't set the modes explicitly. */ umask(022); /* * Initialize option structure to indicate that no values have been * set. */ initialize_options(&options); use_syslog = 0; argv0 = av[0]; options.user = av[1]; // xstrdup host = av[2]; //xstrdup(av[2]); strncpy(options.password, av[3], sizeof(options.password)); buffer_init(&command); buffer_append(&command, av[4], strlen(av[4])); tty_flag = 0; options.port = 22; options.strict_host_key_checking = 0; // options.log_level = SYSLOG_LEVEL_DEBUG3; SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); /* * Initialize "log" output. Since we are the client all output * actually goes to stderr. */ log_init(argv0, options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, !use_syslog); /* Fill configuration defaults. */ fill_default_options(&options); channel_set_af(options.address_family); /* reinit */ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); seed_rng(); timeout_ms = options.connection_timeout * 1000; /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, options.address_family, options.connection_attempts, &timeout_ms, options.tcp_keep_alive, #ifdef HAVE_CYGWIN options.use_privileged_port, #else original_effective_uid == 0 && options.use_privileged_port, #endif options.proxy_command) != 0) return -1; if (timeout_ms > 0) debug3("timeout: %d ms remain after connect", timeout_ms); /* * If we successfully made the connection, load the host private key * in case we will need it later for combined rsa-rhosts * authentication. This must be done before releasing extra * privileges, because the file is only readable by root. * If we cannot access the private keys, load the public keys * instead and try to execute the ssh-keysign helper instead. */ sensitive_data.nkeys = 0; sensitive_data.keys = NULL; sensitive_data.external_keysign = 0; /* * Get rid of any extra privileges that we may have. We will no * longer need them. Also, extra privileges could make it very hard * to read identity files and other non-world-readable files from the * user's home directory if it happens to be on a NFS volume where * root is mapped to nobody. */ if (original_effective_uid == 0) { PRIV_START; permanently_set_uid(pw); } signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw, timeout_ms); /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { if (sensitive_data.keys[i] != NULL) { /* Destroys contents safely */ debug3("clear hostkey %d", i); key_free(sensitive_data.keys[i]); sensitive_data.keys[i] = NULL; } } xfree(sensitive_data.keys); } for (i = 0; i < options.num_identity_files; i++) { if (options.identity_files[i]) { xfree(options.identity_files[i]); options.identity_files[i] = NULL; } if (options.identity_keys[i]) { key_free(options.identity_keys[i]); options.identity_keys[i] = NULL; } } exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child */ if (proxy_command_pid > 1) kill(proxy_command_pid, SIGHUP); return exit_status; }
int main(int argc, char **argv) { FILE *fp = NULL; EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca = NULL; PKCS12 *p12 = NULL; char *pass = strdup(""); int i; if (argc != 2) { fprintf(stderr, "[!] Usage: %s certificate.p12\n", argv[0]); exit(1); } printf("[+] Initializing OpenSSL\n"); SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); printf("[+] Opening PKCS#12 certificate\n"); if (!(fp = fopen(argv[1], "r"))) { fprintf(stderr, "[!] Unable to open certificate `%s'\n", argv[1]); goto endpkcs12; } if (chdir(dirname(argv[1])) == -1) { fprintf(stderr, "[!] Unable to change directory to `%s'\n", dirname(argv[1])); goto endpkcs12; } p12 = d2i_PKCS12_fp(fp, NULL); fclose(fp); fp = NULL; if (!p12) { fprintf(stderr, "[!] Unable to parse PKCS#12 certificate: %s\n", ERR_reason_error_string(ERR_get_error())); goto endpkcs12; } while (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) { ca = NULL; free(pass); if (getpassword("[?] Password: "******"[!] PKCS#12 certificate is incomplete\n"); goto endpkcs12; } #define PEM_w(path, call) \ do { \ if (!(fp = fopen(path, "w"))) { \ fprintf(stderr, "[!] Unable to open `%s'\n", path); \ goto endpkcs12; \ } \ printf("[+] Write certificate to `%s'\n", path); \ call; \ fclose(fp); fp = NULL; \ } while(0) PEM_w("user.pem", PEM_write_X509(fp, cert)); PEM_w("user.key", PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL)); PEM_w("cacert.pem", for (i = 0; i < sk_X509_num(ca); i++) PEM_write_X509(fp, sk_X509_value(ca, i))); sk_free(ca); X509_free(cert); EVP_PKEY_free(pkey); exit(0); endpkcs12: if (pass) free(pass); if (ca) sk_free(ca); if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); if (p12) PKCS12_free(p12); if (fp) fclose(fp); exit(1); }
/* * Main program for the ssh client. */ int main(int ac, char **av) { int i, opt, exit_status; u_short fwd_port, fwd_host_port; char sfwd_port[6], sfwd_host_port[6]; char *p, *cp, buf[256]; struct stat st; struct passwd *pw; int dummy; extern int optind, optreset; extern char *optarg; __progname = get_progname(av[0]); init_rng(); /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). */ original_real_uid = getuid(); original_effective_uid = geteuid(); /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are * ready to create the privileged port, and will permanently drop * them when the port has been created (actually, when the connection * has been made, as we may need to create the port several times). */ PRIV_END; #ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } #endif /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { log("You don't exist, go away!"); exit(1); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); /* * Set our umask to something reasonable, as some files are created * with the default umask. This will make them world-readable but * writable only by the owner, which is ok for all files for which we * don't set the modes explicitly. */ umask(022); /* Initialize option structure to indicate that no values have been set. */ initialize_options(&options); /* Parse command-line arguments. */ host = NULL; again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; break; case '2': options.protocol = SSH_PROTO_2; break; case '4': IPv4or6 = AF_INET; break; case '6': IPv4or6 = AF_INET6; break; case 'n': stdin_null_flag = 1; break; case 'f': fork_after_authentication_flag = 1; stdin_null_flag = 1; break; case 'x': options.forward_x11 = 0; break; case 'X': options.forward_x11 = 1; break; case 'g': options.gateway_ports = 1; break; case 'P': /* deprecated */ options.use_privileged_port = 0; break; case 'a': options.forward_agent = 0; break; case 'A': options.forward_agent = 1; break; #ifdef AFS case 'k': options.kerberos_tgt_passing = 0; options.afs_token_passing = 0; break; #endif case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " "does not exist.\n", optarg); break; } if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) fatal("Too many identity files specified " "(max %d)", SSH_MAX_IDENTITY_FILES); options.identity_files[options.num_identity_files++] = xstrdup(optarg); break; case 'I': #ifdef SMARTCARD options.smartcard_device = xstrdup(optarg); #else fprintf(stderr, "no support for smartcards.\n"); #endif break; case 't': if (tty_flag) force_tty_flag = 1; tty_flag = 1; break; case 'v': if (0 == debug_flag) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { options.log_level++; break; } else fatal("Too high debugging level."); /* fallthrough */ case 'V': fprintf(stderr, "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n", SSH_VERSION, PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSLeay()); if (opt == 'V') exit(0); break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': if (optarg[0] == '^' && optarg[2] == 0 && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; else if (strlen(optarg) == 1) options.escape_char = (u_char) optarg[0]; else if (strcmp(optarg, "none") == 0) options.escape_char = SSH_ESCAPECHAR_NONE; else { fprintf(stderr, "Bad escape character '%s'.\n", optarg); exit(1); } break; case 'c': if (ciphers_valid(optarg)) { /* SSH2 only */ options.ciphers = xstrdup(optarg); options.cipher = SSH_CIPHER_ILLEGAL; } else { /* SSH1 only */ options.cipher = cipher_number(optarg); if (options.cipher == -1) { fprintf(stderr, "Unknown cipher type '%s'\n", optarg); exit(1); } if (options.cipher == SSH_CIPHER_3DES) options.ciphers = "3des-cbc"; else if (options.cipher == SSH_CIPHER_BLOWFISH) options.ciphers = "blowfish-cbc"; else options.ciphers = (char *)-1; } break; case 'm': if (mac_valid(optarg)) options.macs = xstrdup(optarg); else { fprintf(stderr, "Unknown mac type '%s'\n", optarg); exit(1); } break; case 'p': options.port = a2port(optarg); if (options.port == 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(1); } break; case 'l': options.user = optarg; break; case 'L': case 'R': if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]", sfwd_port, buf, sfwd_host_port) != 3 && sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]", sfwd_port, buf, sfwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'\n", optarg); usage(); /* NOTREACHED */ } if ((fwd_port = a2port(sfwd_port)) == 0 || (fwd_host_port = a2port(sfwd_host_port)) == 0) { fprintf(stderr, "Bad forwarding port(s) '%s'\n", optarg); exit(1); } if (opt == 'L') add_local_forward(&options, fwd_port, buf, fwd_host_port); else if (opt == 'R') add_remote_forward(&options, fwd_port, buf, fwd_host_port); break; case 'D': fwd_port = a2port(optarg); if (fwd_port == 0) { fprintf(stderr, "Bad dynamic port '%s'\n", optarg); exit(1); } add_local_forward(&options, fwd_port, "socks4", 0); break; case 'C': options.compression = 1; break; case 'N': no_shell_flag = 1; no_tty_flag = 1; break; case 'T': no_tty_flag = 1; break; case 'o': dummy = 1; if (process_config_line(&options, host ? host : "", optarg, "command-line", 0, &dummy) != 0) exit(1); break; case 's': subsystem_flag = 1; break; case 'b': options.bind_address = optarg; break; case 'F': config = optarg; break; default: usage(); } } ac -= optind; av += optind; if (ac > 0 && !host && **av != '-') { if (strrchr(*av, '@')) { p = xstrdup(*av); cp = strrchr(p, '@'); if (cp == NULL || cp == p) usage(); options.user = p; *cp = '\0'; host = ++cp; } else host = *av; if (ac > 1) { optind = optreset = 1; goto again; } ac--, av++; } /* Check that we got a host name. */ if (!host) usage(); SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); channel_set_af(IPv4or6); /* Initialize the command to execute on remote host. */ buffer_init(&command); /* * Save the command to execute on the remote host in a buffer. There * is no limit on the length of the command, except by the maximum * packet size. Also sets the tty flag if there is no command. */ if (!ac) { /* No command specified - execute shell on a tty. */ tty_flag = 1; if (subsystem_flag) { fprintf(stderr, "You must specify a subsystem to invoke.\n"); usage(); } } else { /* A command has been specified. Store it into the buffer. */ for (i = 0; i < ac; i++) { if (i) buffer_append(&command, " ", 1); buffer_append(&command, av[i], strlen(av[i])); } } /* Cannot fork to background if no command. */ if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) fatal("Cannot fork into background without a command to execute."); /* Allocate a tty by default if no command specified. */ if (buffer_len(&command) == 0) tty_flag = 1; /* Force no tty */ if (no_tty_flag) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ if (!isatty(fileno(stdin)) && !force_tty_flag) { if (tty_flag) log("Pseudo-terminal will not be allocated because stdin is not a terminal."); tty_flag = 0; } /* * Initialize "log" output. Since we are the client all output * actually goes to stderr. */ log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, 1); /* * Read per-user configuration file. Ignore the system wide config * file if the user specifies a config file on the command line. */ if (config != NULL) { if (!read_config_file(config, host, &options)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); (void)read_config_file(buf, host, &options); /* Read systemwide configuration file after use config. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options); } /* Fill configuration defaults. */ fill_default_options(&options); /* reinit */ log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); seed_rng(); if (options.user == NULL) options.user = xstrdup(pw->pw_name); if (options.hostname != NULL) host = options.hostname; if (options.proxy_command != NULL && strcmp(options.proxy_command, "none") == 0) options.proxy_command = NULL; /* Disable rhosts authentication if not running as root. */ #ifdef HAVE_CYGWIN /* Ignore uid if running under Windows */ if (!options.use_privileged_port) { #else if (original_effective_uid != 0 || !options.use_privileged_port) { #endif debug("Rhosts Authentication disabled, " "originating port will not be trusted."); options.rhosts_authentication = 0; } /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, IPv4or6, options.connection_attempts, #ifdef HAVE_CYGWIN options.use_privileged_port, #else original_effective_uid == 0 && options.use_privileged_port, #endif options.proxy_command) != 0) exit(1); /* * If we successfully made the connection, load the host private key * in case we will need it later for combined rsa-rhosts * authentication. This must be done before releasing extra * privileges, because the file is only readable by root. * If we cannot access the private keys, load the public keys * instead and try to execute the ssh-keysign helper instead. */ sensitive_data.nkeys = 0; sensitive_data.keys = NULL; sensitive_data.external_keysign = 0; if (options.rhosts_rsa_authentication || options.hostbased_authentication) { sensitive_data.nkeys = 3; sensitive_data.keys = xmalloc(sensitive_data.nkeys * sizeof(Key)); PRIV_START; sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL); sensitive_data.keys[1] = key_load_private_type(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL); sensitive_data.keys[2] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); PRIV_END; if (options.hostbased_authentication == 1 && sensitive_data.keys[0] == NULL && sensitive_data.keys[1] == NULL && sensitive_data.keys[2] == NULL) { sensitive_data.keys[1] = key_load_public( _PATH_HOST_DSA_KEY_FILE, NULL); sensitive_data.keys[2] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } } /* * Get rid of any extra privileges that we may have. We will no * longer need them. Also, extra privileges could make it very hard * to read identity files and other non-world-readable files from the * user's home directory if it happens to be on a NFS volume where * root is mapped to nobody. */ seteuid(original_real_uid); setuid(original_real_uid); /* * Now that we are back to our own permissions, create ~/.ssh * directory if it doesn\'t already exist. */ snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); if (stat(buf, &st) < 0) if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); /* load options.identity_files */ load_public_identity_files(); /* Expand ~ in known host file names. */ /* XXX mem-leaks: */ options.system_hostfile = tilde_expand_filename(options.system_hostfile, original_real_uid); options.user_hostfile = tilde_expand_filename(options.user_hostfile, original_real_uid); options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, original_real_uid); options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, original_real_uid); signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ /* Log into the remote system. This never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { for (i = 0; i < sensitive_data.nkeys; i++) { if (sensitive_data.keys[i] != NULL) { /* Destroys contents safely */ debug3("clear hostkey %d", i); key_free(sensitive_data.keys[i]); sensitive_data.keys[i] = NULL; } } xfree(sensitive_data.keys); } for (i = 0; i < options.num_identity_files; i++) { if (options.identity_files[i]) { xfree(options.identity_files[i]); options.identity_files[i] = NULL; } if (options.identity_keys[i]) { key_free(options.identity_keys[i]); options.identity_keys[i] = NULL; } } exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child */ if (proxy_command_pid > 1) kill(proxy_command_pid, SIGHUP); return exit_status; } static void x11_get_proto(char **_proto, char **_data) { char line[512]; static char proto[512], data[512]; FILE *f; int got_data = 0, i; char *display; struct stat st; *_proto = proto; *_data = data; proto[0] = data[0] = '\0'; if (!options.xauth_location || (stat(options.xauth_location, &st) == -1)) { debug("No xauth program."); } else { if ((display = getenv("DISPLAY")) == NULL) { debug("x11_get_proto: DISPLAY not set"); return; } /* Try to get Xauthority information for the display. */ if (strncmp(display, "localhost:", 10) == 0) /* * Handle FamilyLocal case where $DISPLAY does * not match an authorization entry. For this we * just try "xauth list unix:displaynum.screennum". * XXX: "localhost" match to determine FamilyLocal * is not perfect. */ snprintf(line, sizeof line, "%s list unix:%s 2>" _PATH_DEVNULL, options.xauth_location, display+10); else snprintf(line, sizeof line, "%s list %.200s 2>" _PATH_DEVNULL, options.xauth_location, display); debug2("x11_get_proto: %s", line); f = popen(line, "r"); if (f && fgets(line, sizeof(line), f) && sscanf(line, "%*s %511s %511s", proto, data) == 2) got_data = 1; if (f) pclose(f); } /* * If we didn't get authentication data, just make up some * data. The forwarding code will check the validity of the * response anyway, and substitute this data. The X11 * server, however, will ignore this fake data and use * whatever authentication mechanisms it was using otherwise * for the local connection. */ if (!got_data) { u_int32_t rand = 0; log("Warning: No xauth data; using fake authentication data for X11 forwarding."); strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); for (i = 0; i < 16; i++) { if (i % 4 == 0) rand = arc4random(); snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff); rand >>= 8; } }
bool ssl_init (void) { SSL_METHOD const *meth; long ssl_options = 0; #if OPENSSL_VERSION_NUMBER >= 0x00907000 if (ssl_true_initialized == 0) { OPENSSL_config (NULL); ssl_true_initialized = 1; } #endif if (ssl_ctx) /* The SSL has already been initialized. */ return true; /* Init the PRNG. If that fails, bail out. */ init_prng (); if (RAND_status () != 1) { logprintf (LOG_NOTQUIET, _("Could not seed PRNG; consider using --random-file.\n")); goto error; } #if OPENSSL_VERSION_NUMBER >= 0x00907000 OPENSSL_load_builtin_modules(); ENGINE_load_builtin_engines(); CONF_modules_load_file(NULL, NULL, CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE); #endif SSL_library_init (); SSL_load_error_strings (); SSLeay_add_all_algorithms (); SSLeay_add_ssl_algorithms (); switch (opt.secure_protocol) { #ifndef OPENSSL_NO_SSL2 case secure_protocol_sslv2: meth = SSLv2_client_method (); break; #endif #ifndef OPENSSL_NO_SSL3 case secure_protocol_sslv3: meth = SSLv3_client_method (); break; #endif case secure_protocol_auto: case secure_protocol_pfs: meth = SSLv23_client_method (); ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; break; case secure_protocol_tlsv1: meth = TLSv1_client_method (); break; #if OPENSSL_VERSION_NUMBER >= 0x10001000 case secure_protocol_tlsv1_1: meth = TLSv1_1_client_method (); break; case secure_protocol_tlsv1_2: meth = TLSv1_2_client_method (); break; #else case secure_protocol_tlsv1_1: logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.1\n")); goto error; case secure_protocol_tlsv1_2: logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.2\n")); goto error; #endif default: logprintf (LOG_NOTQUIET, _("OpenSSL: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol); logprintf (LOG_NOTQUIET, _("Please report this issue to [email protected]\n")); abort (); } /* The type cast below accommodates older OpenSSL versions (0.9.8) where SSL_CTX_new() is declared without a "const" argument. */ ssl_ctx = SSL_CTX_new ((SSL_METHOD *)meth); if (!ssl_ctx) goto error; if (ssl_options) SSL_CTX_set_options (ssl_ctx, ssl_options); /* OpenSSL ciphers: https://www.openssl.org/docs/apps/ciphers.html * Since we want a good protection, we also use HIGH (that excludes MD4 ciphers and some more) */ if (opt.secure_protocol == secure_protocol_pfs) SSL_CTX_set_cipher_list (ssl_ctx, "HIGH:MEDIUM:!RC4:!SRP:!PSK:!RSA:!aNULL@STRENGTH"); SSL_CTX_set_default_verify_paths (ssl_ctx); SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory); if (opt.crl_file) { X509_STORE *store = SSL_CTX_get_cert_store (ssl_ctx); X509_LOOKUP *lookup; if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ())) || (!X509_load_crl_file (lookup, opt.crl_file, X509_FILETYPE_PEM))) goto error; X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the certificate is invalid. We verify the certificate separately in ssl_check_certificate, which provides much better diagnostics than examining the error stack after a failed SSL_connect. */ SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL); /* Use the private key from the cert file unless otherwise specified. */ if (opt.cert_file && !opt.private_key) { opt.private_key = opt.cert_file; opt.private_key_type = opt.cert_type; } if (opt.cert_file) if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file, key_type_to_ssl_type (opt.cert_type)) != 1) goto error; if (opt.private_key) if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key, key_type_to_ssl_type (opt.private_key_type)) != 1) goto error; /* Since fd_write unconditionally assumes partial writes (and handles them correctly), allow them in OpenSSL. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); /* The OpenSSL library can handle renegotiations automatically, so tell it to do so. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY); return true; error: if (ssl_ctx) SSL_CTX_free (ssl_ctx); print_errors (); return false; }