SSH and SFTP Servers on OpenBSD 6.1 – Part 1



In this tutorial, we will continue to learn about OpenBSD 6 by setting up a SSH server alongside a SFTP server. As most of you may know, SSH is essential for remote administration. Nowadays, more and more network administration is done remotely and it is more important than ever to properly configure and secure outward facing services. Additionally, we often need to transfer files, either for patches, reuse configuration files or install additional applications, especially if your OpenBSD server is not Internet-accessible. In a later post of this tutorial, we will use a specific form of port knocking to hide the presence of our services to background scans to prevent brute-force and dictionary attacks. However for now, we will setup our SSH and SFTP servers. A companion video is available on YouTube.


While OpenBSD makes it easy to enable SSH and SFTP, we will do some additional preparation for increased robustness. First we will create the appropriate users and groups and then we will install each of these services within their own chroot directory to limit damage should ever these services get compromised. Once that done, we’ll enable the SSH daemon, including the internal SFTP service, and make sure they are accessible and working properly. Once done, we will customize and harden their configuration. For the purpose of this post, we will assume that you have a fresh install of OpenBSD 6.1 as if you just finished the steps listed in this previous tutorial, i.e. SSHD was NOT enabled during installation.

Creating the Chroot Directories

While optional, enclosing your services in chroot, especially the one exposed to external hosts, is an excellent security practice. Ideally, they should even be on their own partition. To keep the scope of this post on SSH and SFTP, we will simply create a new tree node and setup our chroot containers from there:

We will then install the basic required files from the OpenBSD 6.1 CD to create our chroot. Within the SSH chroot:
# mount -t cd9660 /dev/cd0a /mnt

And unarchive the base packages unto our chroot:

In any chroot, we need the /dev  directory to exist and populated with the required sub directory. Fortunately, OpenBSD makes it easy for us to do so using the MAKEDEV script:

Finally, we will link the shared libraries required by most programs with out chroot and enable our new sandbox:

The chroot directory doesn’t require any special action since it doesn’t need to execute any program. The only thing left to do now is to set the ownership and permissions:

Creating the users and groups

This step is optional if you intent to have this server only for your own personal use or a very few selected people. However if you expect your user base to grow and have different permissions, having groups makes it so much easier to manage your server while ensuring tighter controls on permissions. We’ll create 2 groups: ssh-users and ftp-users. Within each of these groups, we will have a single user. We’ll create ssh-user for accessing the SSH service and ftp-user for accessing the SFTP service by using the useradd and groupadd commands:

While adding groups requires no explanation, it is important to note that ftp-user requires some specific parameters. Namely, the shell is set to /sbin/nologin. FTP are not required to use a shell and are limited to the FTP server, which is actually integrated into the SSH daemon.

Setting up SSHD

In many cases, sshd will have been enabled during installation and automatically starts at boot. If you are unsure, you can quickly verify if the sshd is running:

If there’s no output, then the sshd is not started. Let’s quickly check that SSH works by first enabling and starting the service, and then testing it out. To enable the service, use the rcctl command:

Then start the daemon to actively listen for SSH connections:

And confirm that the SSH daemon is listening by using netstat:

And now, lets try to connect to our SSH service using the IPv6 loopback interface using  # ssh root@::1 . After entering your password, you should be greeted in your new shell.

Without much work, you already have a solid SSH server available within minutes with OpenBSD. However, let’s configure it further to our needs. We’ll stop the server for now:

First configuration items we will change is to disable remote root login and allow users part of the ssh-users group to access SSH. All configuration for the SSH and SFTP services are done thru the /etc/ssh/sshd_config file. Before editing it, you may want to make a backup to your /root directory. We will edit using the vi editor:

The first change we will make is to prevent the root account from using SSH. We’ll do this by setting the PermitRootLogin option to no. If the line is commented, uncommented it by deleting the ‘#‘:

Next we’ll specify SSH to use our specially created chroot sandbox for any SSH connection by adding or setting the following property:

And the last thing for now, we’ll allow only users part of the ssh-users and ftp-users groups to use SSH by setting this line in our configuration file:

Save you configuration and let’s restart our SSH server using rcctl to confirm these basic settings:

First, we should not be allow to login as root anymore. If you try to login as root, you should get denied access:

Excellent. Now let’s log as ssh-user and confirm we are in our chroot sandbox:

Setting up the SFTP Server

Now that we have a basic SSH server running, we’ll configure the basic SFTP server as well. The SFTP server is provided through the SSH daemon and as such, is configured via the sshd_config file as well. This is because SFTP is actually the FTP protocol tunneled through the SSH protocol. As such, the sshd includes a FTP server within itself. To enable SFTP, we simply need to tell sshd to

And ask sshd to use the internal-sftp subsystem by modifying the Subsystem sftp option to Subsystem sftp internal-sftp. Save the file again and restart the SSH server:

And let’s test our SFTP server.

You may run into a few issues here if something is misconfigured.  To help you diagnosed the problem, consult the /var/log/authlog. For example, you encounter this rather cryptic error message when trying to connect to your ftp server:  "Received message too long 1416128883" . This is often caused by the server producing an unexpected output message. In the context of OpenBSD. This may be caused by the banner send by default which is contained in /etc/motd, in which case you need to specify  Banner none in sections relating to the SFTP server.

You may also get disconnected as soon as you attempt to reach your SFTP server, in which case you will get an error message stating:

In which, you can check the log file to troubleshoot your problem

In this case, OpenBSD is complaining about the permissions set on the SFTP chroot directory. If they are too lax, sshd will simply refuse to allow connections to it. As such, make sure you have the appropriate directory permissions.

At this point, you have a server with SSH and SFTP enabled. You can be stop here if this configuration fills you needs, otherwise we can still customize furthermore the servers.

Additional Settings

For one thing, you may want to disable IPv4 if it’s not needed and allow only IPv6. In your sshd_config file, we will do so by setting the AddressFamily to inet6:

Another useful customization depending on your line of work is to change the SSH port. In this case, we will change the port to 443, which is usually reserved for HTTPS connections. The reason for that is that if I need to reach back to my server from a network with connection restrictions, local connections to remote hosts via port 443 is usually allows. In other words, if a firewall is blocking outbound connections to port 22, establishing as SSH connections via port 443 will usually be allowed, unless there are protocol restrictions in place. In any case, we can change the port with:

Depending on your level of paranoia, we can also tighten some controls relating to connectivity to mitigate brute-force or dictionary attacks:

The MaxStartups property is interesting and warrant further details. From the man page:

it specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections will be dropped until authentication succeeds or the LoginGraceTime expires for a connection.

It allows for unauthenticated connections to be denied at random in order to mitigate noisy scanning or DDoS from the Internet. In the example above, we specified the value “5:60:10“, which means that if 5 unauthenticated connections are alive, further unauthenticated connections will be refused with a 60% probability. If 10 unauthenticated connections are established, all further attempts will be denied.

And to further ensure additional security controls, confirm that the following parameters are commented so that the defaults value be used:

Authentication Modes

Another feature that you may want to customize based on your needs is how you or your users connect to the server. Three modes are usually considered to do so:

  • PubkeyAuthentication: requires your client to provide a public key in order to connect to your SSH client. If you have a limited number of users which connects from the same location, this is probably the best option. However if you intent to connect to your SSH server from multiple hosts, you would have to bring your public key with you.
  • PasswordAuthentication and ChallengeResponseAuthentication are very similar in practice. PasswordAuthentication request the client to provide a password via the SSH connection while the ChallengeResponseAuthentication can ask the client one or more question via a TTY. However in most cases, ChallengeResponseAuthentication is configured to ask a password and the only real difference is that the requesting client must type the password rather than providing it via the command line.

For example, the following command would not work with PasswordAuthentication set to “no” and ChallengeResponseAuthentication  set to “yes“:

That being said, there are ways to provide SSH password via the command line, such as using the sshpass package. There is therefore little difference between them. In this example, we configure these parameters as follow:

Hashing Known Hosts Files

When a client connects, the SSHD will store information about the client in the known_host file, which is located in ~/.ssh/. This file will contain the hostname of the client, its IP address and its key. This information is stored in plain text. An additional step to make the life of an intruder harder should your server get compromised is to obfuscated the data in this file be hashing its contents.

The listing above shows the contents of the file before hashing it. To tell SSHD to hash newly added data of the known_hosts file, we will add the following the HashKnownHosts line  in ~/.ssh/config.

From now on, all data added will be hashed. Should you need to hash data already residing in this file, use the command below:

We now have a very solid SSH server. You still have to remain vigilant about new vulnerabilities that may pop up for SSHD or one of its component. In the second part of this series, we’ll cloak our SSH server using some form of port knocking. For now, let’s just tweak our SFTP server slightly. Before that, let’s restart our server.

Final Touch on the SFTP server

We previously set our FTP chroot readonly, but we might want to upload some files to it. If we try it right now, we’ll get the following error message:

We’ll finish this tutorial by adding an upload directory and make it writable to the users of the ftp-users group:


We’ll conclude this part of the tutorial for now. In this post, we detailed how to enable a SSH server on OpenBSD 6.1. We also enabled SFTP and securely configure each service to increase robustness. That being said, nothing is impossible and vulnerabilities may remain: keys can be stolen or confiscated, misconfiguration of other services may be present or malicious internal users may still abuse the system. If you’re a network admin, make sure logging is enabled and more importantly, that logs are analyze either via software or if you have time, manually. In the next part of this tutorial, we will enable a form of port knocking to hide our SSH service to scanning from external hosts. By doing so, we will prevent detection by roaming threats and prevent or at least greatly limit effectiveness of brute force and dictionary attacks against our server.


Additional Readings

Installing Feng Office on OpenBSD 6.0


Feng Office is a Web project management application. It allows management of projects, tasks, documents and enables online collaboration with co-workers and other organizations. It can provide a multitude of business services including billing and scheduling among others. In the previous posts, we installed OpenBSD 6.0, setup our web server and then deployed WordPress on it. In this post, we continue to develop our web server by installing Feng Office.

Setting Up OpenBSD 6.0

Feng requires php-gd package for image processing. This package has dependencies on the xbase60.tgz OpenBSD package. If you did not install this set during the OpenBSD installation, you can do it now using these commands:

If you don’t have access to the Internet, you can simply use the archive from the OpenBSD 6.0 CD and unpack its contents using the command at the second line in the code listing above.

We can now proceed with installing the php-gd package. This can be done using the pkg_add application. When asked which version of the package you wish to download, select the same version as your current PHP installation. In this case, PHP 5.6.23 is installed. If you are unsure about yours, type  /usr/local/bin/php-5.6 --version to retrieve it.

Unlike Linux distributions, pkg_add does not automatically modify the required configuration files. As such, you need to manually modify the PHP configuration file to load the php-gd extension. Edit the php-5.6.ini with vi /etc/php-5.6.ini  file and add the following line in the extension section:

Since we modified the configuration file, we will need to restart the PHP service:

Now that we have setup OpenBSD to be compatible with Feng, we will configure the database and then move on to the actual install of the web application.

Setting Up the Database

In the previous posts, we installed MariaDB and set it up for a WordPress site. The same exact steps apply for the Feng Office application. Login into the MariaDB database with mysql -u root -p and follow these steps:

Create a database schema for the Feng Office application:

Then create a user for the application and select a strong password for it unlike the example below:

Afterwards, grant your new user the privileges require to modify your database. In this case, we allow the user all privileges on the db_feng database:

And then exit MariaDB by typing  quit . We are now ready to install the Feng Office application.

Installing Feng Office

You’ll first need to download the application from the Web using the ftp program. You’ll also need to install unzip since Feng Office uses a zip package. If you want to avoid installing the unzip package, you can always download Feng on another workstation, unzip it and repack it using tar. Then upload it to a third party location and re-download it using ftp. Otherwise install unzip with pkg_add unzip and then download Feng with ftp:

As we did in previous tutorial, we confirmed the integrity of the package. The MD5 hash is provided on the SourceForge website by clicking the “i” icon. We will now unzip Feng into its own directory on our web server:

Feng Office has quite a few files and after a few seconds, all files should be extracted. In order to run the installer, we first need to set specific permissions on some directories. As such, we’ll make sure the following directories are readable, writable and executable and change their ownership to the web server:

With this done, browse to your Feng Office home page from a remote workstation. You will be greeted by a welcome page which details the installation procedure. Click Next.

Welcome Page of the Feng Office Installer
The welcome page of the Feng Office installer

The second page of the installer verifies if all requirements for the application are met. If there is an item highlighted in red, then you will not be able to proceed. The most likely issues are limited file permissions and missing PHP extensions. If everything is green, click Next.

Requirements Verification for Installing Feng Office
Feng Office verifies if all requirements are met to install and use the application.

The third step is where you provide the information about the database. Fill in the required information with the specific values for your database setup. An example of valid values for our example are:

  • Database Type: MySQL
  • Hostname:
  • Username: fg_user
  • Password: p1234
  • Database Name: db_feng

You can leave the remaining settings to their default values and once satisfied, click Next again. You then reach the last page of the installer, which You’ll reach the installation page and you should get a Succcess! message Click on Finish.

Feng Office Administrator Account Creation Form
Administrator account form for Feng Office

After clicking Finish, you’ll be immediately redirect to the user account creation form. This is the final step before using the application is to create an Administrator account. Fill in the form and click Submit. You will be redirected to the login page. Login and that’s it! Next steps include configuring your new Feng Office application by creating users and customizing it. You should also remove write permission to the /var/www/htdocs/feng/config and change the ownership back to root:daemon.


Feng Office is widely used by multiple large public and private organizations and thus, is a fairly popular web application which like many others, fits perfectly with an OpenBSD 6.0 server. Like in the WordPress install, you should attempt to plug information leaks by removing README and CHANGELOG files and test your application via a rigorous penetration test. With a well-configured OpenBSD server and secure database, the likelihood a a major breach occurring is greatly reduced, but it always depends on how well or badly it’s configured and used.


See Also

Learn More

Installing WordPress on OpenBSD 6.0 with Httpd



In the previous posts, we setup a minimal but secure web server using OpenBSD 6.0. In this post, we start from a fresh install with httpd, MariaDB and PHP 5.6.23 setup on the host. In most cases, you may now want to install a web application on it. One of the most popular is WordPress. If you have followed all the steps in the previous tutorial, installing WordPress will be fairly easy. However, because the web server is sand boxed in OpenBSD, many issues can arise. Additionally, introduction of new application may also introduce new security concerns. In this tutorial, we go through the basics of setting the database and configuring the application. We’ll also assume that you have the networking aspect configured and working. You can also consult the accompanying video.

Setting Up WordPress 4.7 on OpenBSD 6.0

To install WordPress on OpenBSD 6.0 using the native httpd web server requires quite a few steps, but most are straightforward and requires only some Linux command shell knowledge. It’s a good idea to be well-versed in the Bash scripting language and basic Linux/OpenBSD knowledge. In any case, following the steps below will get you going with your new WordPress blog in no time.

Downloading WordPress

Once validated, unzip and untar the archive into your web root directory, likely /var/www/htdocs using:

This will untar all files into /var/www/htdocs/wordpress. Feel free to rename the wordpress directory to anything you’d like.

Configuring the Database

In previous post, we installed MariaDB and thus this section will assume you have installed this database application. Otherwise, refer to the documentation of your database to use the proper SQL statements to create databases, users and manage permissions.

Log into the MariaDB database using  mysql -u root -p your_password . If you are logging from a remote location, use the  -h host argument. Once logged in, we will conduct 3 steps:

    1. Create a database for the WordPress application:

    1. Create a user for WordPress to use in order to connect to the database by using the following SQL statement:

    1. Grant permissions to the new user in order to edit the database and tables as required:

Now, the WordPress application has a place to store data on our database. Before we proceed thought, I encourage you to look at the ~/.mysql_history for a glimpse of what happened while you were doing the steps above. As you will see, the password for the user has been logged into this file. Remove this file with rm ~/.mysql_history  and let’s disable logging to prevent such leaks by adding this line in your rc.conf.local file:

Installing WordPress

From a remote host, use your favorite browser and go to https://<your_address>/wordpress/ and the installer should popup automatically. The first step is create the configuration file by filling information about the database. So gather the following information, which we have from the previous section and click “Let’s Go“:

  1. Database name: Database name use with the “CREATE DATABASE” SQL statement, i.e. “db_wordpress
  2. Database username: Username enter in the “CREATE USER” SQL statement, i.e. “wp_user
  3. Database password: type in your password;
  4. Database host; Enter or ::1. Do not leave it as “localhost” as we want to use the sockets;
  5. Table prefix; Prefix for each table created. Unless you plan to have multiple WordPress sites, leave the default value.
Wordpress Installer Welcome Page
The WordPress Installer will guide you step-by-step on setting it up.

On the next page, enter the required data and click “Submit“. If every thing is setup right, you will be prompted to continue with the setup of the site. However, you may also get a blank “step2” page, i.e. the URL will be “setup-config.php?step=2” but nothing will show up. This problem can be caused by many different things. First, make sure you have setup PHP to use your MySQL database by enabling the proper extensions in the php-5.6.ini configuration file. See previous post for an explanation on how to do this.

Next issue you may encounter is a warning that WordPress cannot create the wp-config.php file. This is mostly due to permissions issues with /var/www/htdocs/wordpress/. The best option is to manually create the file by copy-pasting its contents. Another alternative is to temporarily change the permissions of the directory to allow write permissions with  chmod 777 /var/www/htdocs/wordpress for the installer to create the file. Doing so allows anyone to write and execute code to your directory and as such, it must be change immediately after you are finished installing and configuring WordPress.

Wordpress Fail to Create Wp-config.php
WordPress warns that it could not create the wp-config.file.

Quick Hardening

Before calling “Mission Accomplished”, take some time to test your new site and set the proper file permissions. Create a test post and try to upload an image to it. You may find that it fails, again because of permission issues. According to [1], you should have the following permissions for your WordPress install:

  • Folder set to 755;and
  • Files set to 644, except wp-config.php should be 440 or 400

This can be done with the following commands;

Furthermore, note the following quote from [1]:

No directories should ever be given 777, even upload directories. Since the php process is running as the owner of the files, it gets the owners permissions and can write to even a 755 directory.

Meaning that you should avoid the temptation to solve your uploads issues, or any other issues by setting full permissions, even the upload folder. Based on [2], all files outside the wp-content directory should be owned by your OpenBSD user account so they cannot be modified. The owner of the wp-content will be set to www and will be writable, allowing uploads of files themes and plugins. Note that once you chose your theme and plugins, you could further harden your blog by restricting the wp-content/themes and wp-content/plugins directories as some attackers hide web shells in those.

Retest to make sure it works.

Upload Failures due to Directory Permissions
Setting the minimal and proper permissions on the Uploads directory is critical.

One last quick thing you may want to do is delete unneeded installation files.  WordPress should have remove them for you, but just double check. You can also remove the readme.html and any release notes that may be present, this way, it will be harder for an attacker to find the version of your WordPress installation.


WordPress becomes insecure when adding plugins, which introduces the majority of new vulnerabilities. As such, attempt to avoid unnecessary plugins and themes and uninstall them once they are unneeded. Also enable auto-updates. There are quite further actions you can take to harden your WordPress install, and I’d recommend reading the reference at [1]. You can also review the database permissions you have granted to the “wp_user” in MariaDB, and possibly restrict them to simply INSERT/UPDATE/SELECT/DELETE instructions. Then test your installation with wp-scan, a great, free and open-source WordPress vulnerability assessment.


[1] Hardening WordPress, Core Directories/Files,, (accessed on 2017-01-09)

[2] Correct File Permissions for WordPress, StackOverflow,, (accessed on 2017-01-16)

See Also

Starting in Exploit Development – Day 04


Today, instead of following the FuzzySecurity tutorial, I’ve decided to solidify what I have learned so far by exploiting another FTP Server, this way we won’t yet stray far from the tutorial. We’ll exploit the PCMAN FTP 2.07 server.

The exploit is a buffer overflow in about any command send to the FTP server. We’ll attempt to exploit the STOR command. To do so, we basically reconstruct the Python script we’ve used in day 1:

Note that we are using a buffer of 3000 bytes. I’ve first attempted a payload size of 2000, but it failed to crash the server. At 3000, it was successful as you can see below:

Buffer Overflow in PCMAN FTP 2.07
We successfully smashed EIP with a payload of 3000 bytes in the STOR command.

Let’s replace our payload by a Metasploit pattern to find the offsets using !mona findmsp:

Mona showing at which offset EIP is overwritten
Mona found that EIP is being overwritten at offset 2006

Also interesting, is that SEH is not being overwritten here, so we cannot use the technique learned yesterday. The offset found, we can now start shaping our payload:

And we’ll test it to confirm everything is going smoothly:

EIP overwritten with "B"s
Our payload works, now we simply have to put the addresses and shell code needed

Ah ! Perfecto ! Now let’s figure out an address we can use to jump at [ESP]. We’ll do this using !mona jmp -r esp:

Search results for "jmp esp" in PCMAN 2.07
Search results for “jmp esp” instructions in memory for PCMAN FTP Server 2.07

Ideally, I would have like to find a “jmp esp” within the application itself, but all of them contained invalid bytes, so I’ll just use one from the Windows DLLs:

We’ll use the same payload as before, i.e. the windows\shell_bind_tcp as we are only interested in training purposes, so our final code will look like this:

And voila! I sometimes runs into issue when running the shell code on the target machine and it seems due to bad bytes in the shell, so this is something I’ll need to check out, i.e. how to determine which bytes should be avoided in the shell code. I usually fix it by regenerating a new payload in Metasploit. In any case, we have out shell:

Listening on port 4444
The exploit binded a shell on port 4444
Remote Shell from Exploiting PCMAN FTP 2.07
We successfully open a remote shell from the exploit in PCMAN FTP 2.07

All right, so now, we should be able to exploit basic buffer overflows from any simple program. Let’s move on…

Starting in Exploit Development – Day 01


I’ve always seen exploit research and development has the pinnacle of computer security, the ultimate black art of hacking, probably because writing exploit requires full understanding of low-level memory and CPU operations. And given the complexity required nowadays to not only find a vulnerability, but actually exploit it, given protection such as DEP, ASLR and EMET, keeps amazing me. Just tonight, a Chinese team successfully pwned Safari and Flash at the annual Pwn2Own[1]. They could have make serious money on the black market with these two exploits. So I asked myself recently: why don’t I start learning exploit development? There’s certainly a future in it.

As such, I’ll be starting at the bottom and follow the Fuzzy Security tutorials, which seems quite detailed. Today, I’ll be following part 1 and part 2, using a virtualized Windows XP 32-bit box. I’ve downloaded Immunity Debugger and and Metasploit, filling out those pesky registration form. Of course if you are not aware yet, use FakeNameGenerator and 10 Minute Mail, which work for all these sites. I’ve skipped since it wasn’t available for download anymore. You’ll also need Python 2.7+ for Immunity Debugger.

Basically, I have a quick setup of 2 virtual machines; one runs Windows 7 64-bit with Metasploit 4.8.2-1 and Python 2.7.6, the one is a Windows XP SP3 32-bit machine with Immunity Debugger, the script and the vulnerable FreeFloat FTP. With VirtualBox, I’ve set a Host-Only Adapter on both machines on the same virtual network. Copy the into the C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands folder. If you’re using something else than Backtrack or Kali, you’ll need to download and install a Ruby interpreter and the Development Kit to use the pattern_create.rb of Metasploit. When installing Ruby, make sure you select “Add Ruby executables to the environment path”. Finally, once you have, you need the “bundler” package for Metasploit. Within the Development Toolkit, run the “devkitvars.bat” file. This will add the DevKit to your PATH. Simply type “gem install bundler” and you should be on your way. Or so I thought…

Metasploit then complains it cannot find the rake-10.1.0 sources….What a pain.  That’s because the version or Ruby I’ve install contains Rack version 10.1.1 instead of version 10.1.0. To install the correct version use the following;

This will install the correct version. Unfortunately, the same problems happens with additional packages. After trying to install each of them manually, I got tired of it, so I try the “bundle install” command, which needs to be execute from “C:\metasploit\ruby\bin” folder;

WTF? I’m pretty sure I’ve just install this…whatever, let’s try again…

Dammit…After some Googling I find a forum post that recommends to try a few commands to clean the packages:

After a few seconds, seems that new packages are installed. I’m hopeful that I can finally start exploiting stuff…

At this point, I just give up and install every damn packages I need manually. After 10 minutes of this I just rage quit when the network_interface-1.0.0 package kept failing to install. I’ve downloaded an ISO of Kali. The only success I had tonight was overflowing the EIP register…guess I have a long way to go…

Overflow of EIP

[1] Mimoso, Michael. “Keen Team of China Takes Down Safari and Flash at Pwn2Own.” Threatpost English Global. (accessed March 13, 2014).