예제 #1
0
static void torture_pki_duplicate_key_ecdsa(void **state)
{
    int rc;
    char *b64_key;
    char *b64_key_gen;
    ssh_key pubkey;
    ssh_key privkey;
    ssh_key privkey_dup;

    (void) state;

    rc = ssh_pki_import_pubkey_file(LIBSSH_ECDSA_TESTKEY ".pub", &pubkey);
    assert_true(rc == 0);

    rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
    assert_true(rc == 0);
    ssh_key_free(pubkey);

    rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
                                     NULL,
                                     NULL,
                                     NULL,
                                     &privkey);
    assert_true(rc == 0);

    privkey_dup = ssh_key_dup(privkey);
    assert_true(privkey_dup != NULL);

    rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
    assert_true(rc == SSH_OK);

    rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen);
    assert_true(rc == 0);

    assert_string_equal(b64_key, b64_key_gen);

    rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
    assert_true(rc == 0);

    ssh_key_free(pubkey);
    ssh_key_free(privkey);
    ssh_key_free(privkey_dup);
    ssh_string_free_char(b64_key);
    ssh_string_free_char(b64_key_gen);
}
예제 #2
0
static void
cockpit_ssh_data_free (CockpitSshData *data)
{
  if (data->context)
    g_main_context_unref (data->context);
  g_free (data->command);
  if (data->creds)
    cockpit_creds_unref (data->creds);
  g_free (data->expect_key);
  g_free (data->host_key);
  if (data->host_fingerprint)
    ssh_string_free_char (data->host_fingerprint);
  ssh_free (data->session);
  g_free (data->knownhosts_file);
  g_free (data);
}
예제 #3
0
gint
remmina_ssh_auth_gui (RemminaSSH *ssh, RemminaInitDialog *dialog, gboolean threaded)
{
	gchar *tips;
	gchar *keyname;
	gint ret;
	size_t len;
	guchar *pubkey;
	ssh_key server_pubkey;

	/* Check if the server's public key is known */
	ret = ssh_is_server_known (ssh->session);
	switch (ret)
	{
		case SSH_SERVER_KNOWN_OK:
			break;

		case SSH_SERVER_NOT_KNOWN:
		case SSH_SERVER_FILE_NOT_FOUND:
		case SSH_SERVER_KNOWN_CHANGED:
		case SSH_SERVER_FOUND_OTHER:
			if ( ssh_get_publickey(ssh->session, &server_pubkey) != SSH_OK )
			{
				remmina_ssh_set_error(ssh, "ssh_get_publickey() has failed: %s");
				return 0;
			}
			if ( ssh_get_publickey_hash(server_pubkey, SSH_PUBLICKEY_HASH_MD5, &pubkey, &len) != 0 ) {
				ssh_key_free(server_pubkey);
				remmina_ssh_set_error(ssh, "ssh_get_publickey_hash() has failed: %s");
				return 0;
			}
			ssh_key_free(server_pubkey);
			keyname = ssh_get_hexa (pubkey, len);

			if (threaded) gdk_threads_enter();
			if (ret == SSH_SERVER_NOT_KNOWN || ret == SSH_SERVER_FILE_NOT_FOUND)
			{
				ret = remmina_init_dialog_serverkey_unknown (dialog, keyname);
			}
			else
			{
				ret = remmina_init_dialog_serverkey_changed (dialog, keyname);
			}
			if (threaded)
			{	gdk_flush();gdk_threads_leave();}

			ssh_string_free_char(keyname);
			ssh_clean_pubkey_hash (&pubkey);
			if (ret != GTK_RESPONSE_OK) return -1;
			ssh_write_knownhost (ssh->session);
			break;
		case SSH_SERVER_ERROR:
		default:
			remmina_ssh_set_error (ssh, "SSH known host checking failed: %s");
		return 0;
	}

	/* Try empty password or existing password first */
	ret = remmina_ssh_auth (ssh, NULL);
	if (ret > 0) return 1;

	/* Requested for a non-empty password */
	if (ret < 0)
	{
		if (!dialog) return -1;

		switch (ssh->auth)
		{
			case SSH_AUTH_PASSWORD:
			tips = _("Authenticating %s's password to SSH server %s...");
			keyname = _("SSH password");
			break;
			case SSH_AUTH_PUBLICKEY:
			tips = _("Authenticating %s's identity to SSH server %s...");
			keyname = _("SSH private key passphrase");
			break;
			default:
			return FALSE;
		}

		if (ssh->auth != SSH_AUTH_AUTO_PUBLICKEY)
		{
			if (threaded) gdk_threads_enter();
			remmina_init_dialog_set_status (dialog, tips, ssh->user, ssh->server);

			ret = remmina_init_dialog_authpwd (dialog, keyname, FALSE);
			if (threaded)
			{	gdk_flush();gdk_threads_leave();}

			if (ret != GTK_RESPONSE_OK) return -1;
		}
		ret = remmina_ssh_auth (ssh, dialog->password);
	}

	if (ret <= 0)
	{
		return 0;
	}

	return 1;
}
예제 #4
0
int authenticate(ssh_session session){
  int rc;
  int method;
  char password[128] = {0};
  char *banner;

  // Try to authenticate
  rc = ssh_userauth_none(session, NULL);
  if (rc == SSH_AUTH_ERROR) {
    error(session);
    return rc;
  }

  method = ssh_auth_list(session);
  while (rc != SSH_AUTH_SUCCESS) {
    // Try to authenticate with public key first
    if (method & SSH_AUTH_METHOD_PUBLICKEY) {
      rc = ssh_userauth_autopubkey(session, NULL);
      if (rc == SSH_AUTH_ERROR) {
      	error(session);
        return rc;
      } else if (rc == SSH_AUTH_SUCCESS) {
        break;
      }
    }

    // Try to authenticate with keyboard interactive";
    if (method & SSH_AUTH_METHOD_INTERACTIVE) {
      rc = authenticate_kbdint(session, NULL);
      if (rc == SSH_AUTH_ERROR) {
      	error(session);
        return rc;
      } else if (rc == SSH_AUTH_SUCCESS) {
        break;
      }
    }

    if (ssh_getpass("Password: "******"%s\n",banner);
    ssh_string_free_char(banner);
  }

  return rc;
}
예제 #5
0
int verify_knownhost(ssh_session session)
{
char *hexa;

int state;

char buf[10];

unsigned char *hash = NULL;

size_t hlen;

ssh_key srv_pubkey;

int rc;

	state=ssh_is_server_known(session);

	rc = ssh_get_server_publickey(session, &srv_pubkey);

	if (rc < 0)
	{
		return -1;
	}

	rc = ssh_get_publickey_hash(srv_pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen);

	ssh_key_free(srv_pubkey);

	if (rc < 0)
	{
		return -1;
	}

	switch(state)
	{
		case SSH_SERVER_KNOWN_OK:
		/* Server found */
		break;

		case SSH_SERVER_KNOWN_CHANGED:

			fprintf(stderr,"Host key for server changed : server's one is now :\n");

			ssh_print_hexa("Public key hash",hash, hlen);

			ssh_clean_pubkey_hash(&hash);

			fprintf(stderr,"For security reason, connection will be stopped\n");

			return -1;

		case SSH_SERVER_FOUND_OTHER:

			fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");

			fprintf(stderr,"An attacker might change the default server key to confuse your client"
			"into thinking the key does not exist\n"
			"We advise you to rerun the client with -d or -r for more safety.\n");

			return -1;

		case SSH_SERVER_FILE_NOT_FOUND:

			fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");

			fprintf(stderr,"the file will be automatically created.\n");

			/* fallback to SSH_SERVER_NOT_KNOWN behavior */

		case SSH_SERVER_NOT_KNOWN:

			hexa = ssh_get_hexa(hash, hlen);

			fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");

			fprintf(stderr, "Public key hash: %s\n", hexa);

			ssh_string_free_char(hexa);

			if (fgets(buf, sizeof(buf), stdin) == NULL)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}
			if(strncasecmp(buf,"yes",3)!=0)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}

			fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");

			if (fgets(buf, sizeof(buf), stdin) == NULL)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}

			if(strncasecmp(buf,"yes",3)==0)
			{
				if (ssh_write_knownhost(session) < 0)
				{
					ssh_clean_pubkey_hash(&hash);

					fprintf(stderr, "error %s\n", strerror(errno));

					return -1;
				}
			}
		break;

		case SSH_SERVER_ERROR:

			ssh_clean_pubkey_hash(&hash);

			fprintf(stderr,"%s",ssh_get_error(session));

		return -1;
	}

	ssh_clean_pubkey_hash(&hash);

	return 0;
} /* int verify_knownhost */
예제 #6
0
/** @brief copies files from source location to destination
 * @param src source location
 * @param dest destination location
 * @param recursive Copy also directories
 */
static int do_copy(struct location *src, struct location *dest, int recursive) {
    int size;
    socket_t fd;
    struct stat s;
    int w, r;
    char buffer[16384];
    int total = 0;
    int mode;
    char *filename = NULL;
    /* recursive mode doesn't work yet */
    (void)recursive;
    /* Get the file name and size*/
    if (!src->is_ssh) {
        fd = fileno(src->file);
        if (fd < 0) {
            fprintf(stderr,
                    "Invalid file pointer, error: %s\n",
                    strerror(errno));
            return -1;
        }
        r = fstat(fd, &s);
        if (r < 0) {
            return -1;
        }
        size = s.st_size;
        mode = s.st_mode & ~S_IFMT;
        filename = ssh_basename(src->path);
    } else {
        size = 0;
        do {
            r = ssh_scp_pull_request(src->scp);
            if (r == SSH_SCP_REQUEST_NEWDIR) {
                ssh_scp_deny_request(src->scp, "Not in recursive mode");
                continue;
            }
            if (r == SSH_SCP_REQUEST_NEWFILE) {
                size = ssh_scp_request_get_size(src->scp);
                filename = strdup(ssh_scp_request_get_filename(src->scp));
                mode = ssh_scp_request_get_permissions(src->scp);
                //ssh_scp_accept_request(src->scp);
                break;
            }
            if (r == SSH_ERROR) {
                fprintf(stderr,
                        "Error: %s\n",
                        ssh_get_error(src->session));
                ssh_string_free_char(filename);
                return -1;
            }
        } while(r != SSH_SCP_REQUEST_NEWFILE);
    }

    if (dest->is_ssh) {
        r = ssh_scp_push_file(dest->scp, src->path, size, mode);
        //  snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
        if (r == SSH_ERROR) {
            fprintf(stderr,
                    "error: %s\n",
                    ssh_get_error(dest->session));
            ssh_string_free_char(filename);
            ssh_scp_free(dest->scp);
            dest->scp = NULL;
            return -1;
        }
    } else {
        if (!dest->file) {
            dest->file = fopen(filename, "w");
            if (!dest->file) {
                fprintf(stderr,
                        "Cannot open %s for writing: %s\n",
                        filename, strerror(errno));
                if (src->is_ssh) {
                    ssh_scp_deny_request(src->scp, "Cannot open local file");
                }
                ssh_string_free_char(filename);
                return -1;
            }
        }
        if (src->is_ssh) {
            ssh_scp_accept_request(src->scp);
        }
    }

    do {
        if (src->is_ssh) {
            r = ssh_scp_read(src->scp, buffer, sizeof(buffer));
            if (r == SSH_ERROR) {
                fprintf(stderr,
                        "Error reading scp: %s\n",
                        ssh_get_error(src->session));
                ssh_string_free_char(filename);
                return -1;
            }

            if (r == 0) {
                break;
            }
        } else {
            r = fread(buffer, 1, sizeof(buffer), src->file);
            if (r == 0) {
                break;
            }

            if (r < 0) {
                fprintf(stderr,
                        "Error reading file: %s\n",
                        strerror(errno));
                ssh_string_free_char(filename);
                return -1;
            }
        }

        if (dest->is_ssh) {
            w = ssh_scp_write(dest->scp, buffer, r);
            if (w == SSH_ERROR) {
                fprintf(stderr,
                        "Error writing in scp: %s\n",
                        ssh_get_error(dest->session));
                ssh_scp_free(dest->scp);
                dest->scp = NULL;
                ssh_string_free_char(filename);
                return -1;
            }
        } else {
            w = fwrite(buffer, r, 1, dest->file);
            if (w <= 0) {
                fprintf(stderr,
                        "Error writing in local file: %s\n",
                        strerror(errno));
                ssh_string_free_char(filename);
                return -1;
            }
        }
        total += r;

    } while(total < size);

    ssh_string_free_char(filename);
    printf("wrote %d bytes\n", total);
    return 0;
}
예제 #7
0
int SSH_Socket::authenticate_console()
{
    int rc;
    int method;
    char *banner;

    // Try to authenticate
    rc = ssh_userauth_none(session, nullptr);
    switch(rc)
    {
        case SSH_AUTH_ERROR:   //some error happened during authentication
            std::cout << "ssh_userauth_none SSH_AUTH_ERROR!" << std::endl;
            error();
            return rc;
        case SSH_AUTH_DENIED:  //no key matched
            std::cout << "ssh_userauth_none SSH_AUTH_DENIED!" << std::endl;
            break;
        case SSH_AUTH_SUCCESS: //you are now authenticated
            std::cout << "ssh_userauth_none SSH_AUTH_SUCCESS!" << std::endl;
            break;
        case SSH_AUTH_PARTIAL:
            //some key matched but you still have
            //to provide an other mean of authentication (like a password).
            std::cout << "ssh_userauth_none SSH_AUTH_PARTIAL!" << std::endl;
            break;
    }

    int failureCounter = 0;

    // Get a list of excepted Auth Sessions server wants.
    method = ssh_auth_list(session);
    while(rc != SSH_AUTH_SUCCESS && failureCounter < 20)
    {
/*
    Retrieve the public key with ssh_import_pubkey_file().
    Offer the public key to the SSH server using ssh_userauth_try_publickey().
     * If the return value is SSH_AUTH_SUCCESS, the SSH server accepts
     * to authenticate using the public key and you can go to the next step.
    Retrieve the private key, using the ssh_pki_import_privkey_file() function.
     * If a pass phrase is needed, either the pass phrase specified
     * as argument or a callback will be used.
    Authenticate using ssh_userauth_publickey() with your private key.
    Do not forget cleaning up memory using ssh_key_free().
*/
        // The function ssh_userauth_autopubkey() does this using the
        // available keys in "~/.ssh/" or ssh-agent. The return values are the following:
        // ** Public Key Needs more testing.
        if(method & SSH_AUTH_METHOD_PUBLICKEY)
        {
            rc = ssh_userauth_autopubkey(session, nullptr);
            switch(rc)
            {
                case SSH_AUTH_ERROR:   //some serious error happened during authentication
                    std::cout << "SSH_AUTH_METHOD_PUBLICKEY - SSH_AUTH_ERROR!" << std::endl;
                    error();
                    return rc;
                case SSH_AUTH_DENIED:  //no key matched
                    std::cout << "SSH_AUTH_METHOD_PUBLICKEY - SSH_AUTH_DENIED!" << std::endl;
                    ++failureCounter;
                    break;
                case SSH_AUTH_SUCCESS: //you are now authenticated
                    std::cout << "SSH_AUTH_METHOD_PUBLICKEY - SSH_AUTH_SUCCESS!" << std::endl;
                    break;
                case SSH_AUTH_PARTIAL:
                    // some key matched but you still have
                    // to provide an other mean of authentication (like a password).
                    std::cout << "SSH_AUTH_METHOD_PUBLICKEY - SSH_AUTH_PARTIAL!" << std::endl;
                    ++failureCounter;
                    break;
                default:
                    break;
            }
/*
            // Validate with specific public key file
            rc = ssh_userauth_try_publickey(session, NULL, "pubkey.pub");
            switch (rc)
            {
                case SSH_AUTH_ERROR:   //some serious error happened during authentication
                    printf("\r\n try_publickey - SSH_AUTH_ERROR! \r\n");
                    error(session);
                    return rc;
                case SSH_AUTH_DENIED:  //no key matched
                    printf("\r\n try_publickey - SSH_AUTH_DENIED! \r\n");
                    break;
                case SSH_AUTH_SUCCESS: //you are now authenticated
                    printf("\r\n try_publickey - SSH_AUTH_SUCCESS! \r\n");
                    break;
                case SSH_AUTH_PARTIAL: //some key matched but you still have to
                                       //provide an other mean of authentication (like a password).
                    printf("\r\n try_publickey - SSH_AUTH_PARTIAL! \r\n");
                    break;
                default:
                    break;
            }
             */
        }

        // Try to authenticate with keyboard interactive";
        if(method & SSH_AUTH_METHOD_INTERACTIVE)
        {
            //rc = authenticate_kbdint(session, NULL);
            switch(rc)
            {
                case SSH_AUTH_ERROR:   //some serious error happened during authentication
                    std::cout << "SSH_AUTH_METHOD_INTERACTIVE - SSH_AUTH_ERROR!" << std::endl;
                    error();
                    return rc;
                case SSH_AUTH_DENIED:  //no key matched
                    std::cout << "SSH_AUTH_METHOD_INTERACTIVE - SSH_AUTH_DENIED!" << std::endl;
                    ++failureCounter;
                    break;
                case SSH_AUTH_SUCCESS: //you are now authenticated
                    std::cout << "SSH_AUTH_METHOD_INTERACTIVE - SSH_AUTH_SUCCESS!" << std::endl;
                    break;
                case SSH_AUTH_PARTIAL: //some key matched but you still have to
                                       //provide an other mean of authentication (like a password).
                    std::cout << "SSH_AUTH_METHOD_INTERACTIVE - SSH_AUTH_PARTIAL!" << std::endl;
                    ++failureCounter;
                    break;
                default:
                    break;
            }
        }
        /*
        if (ssh_getpass("Password: "******"")
            {
                rc = ssh_userauth_password(session, nullptr, password.c_str());
                switch(rc)
                {
                    case SSH_AUTH_ERROR:   //some serious error happened during authentication
                        std::cout << "SSH_AUTH_METHOD_PASSWORD - SSH_AUTH_ERROR!" << std::endl;
                        error();
                        return rc;
                    case SSH_AUTH_DENIED:  //no key matched
                        std::cout << "SSH_AUTH_METHOD_PASSWORD - SSH_AUTH_DENIED!" << std::endl;
                        ++failureCounter;
                        break;
                    case SSH_AUTH_SUCCESS: //you are now authenticated
                        std::cout << "SSH_AUTH_METHOD_PASSWORD - SSH_AUTH_SUCCESS!" << std::endl;
                        break;
                    case SSH_AUTH_PARTIAL: //some key matched but you still have to
                                           // provide an other mean of authentication (like a password).
                        std::cout << "SSH_AUTH_METHOD_PASSWORD - SSH_AUTH_PARTIAL!" << std::endl;
                        ++failureCounter;
                        break;
                    default:
                        break;
                }
            }
        }
    }
    banner = ssh_get_issue_banner(session);
    if(banner)
    {
        std::cout << banner << std::endl;
        ssh_string_free_char(banner);
    }

    std::cout << " *** SSH Authenticate Completed." << std::endl;
    return rc;
}