• chevron_right

      New Release Alert: OpenSSH 9.2/9.2p1 Upgraded with Security and Improvements

      TREND OCEANS · Monday, 6 February, 2023 - 05:46

    OpenSSH 9.2 and 9.2p1: security fixes and other improvements were released this week, giving system administrators and users the latest in secure remote access protocols. Read more

    #linux #debian #ubuntu #bsd #openssh #ssh #dev #sysadmin #devops #developers

    • Nu chevron_right

      OpenBSD's pledge and unveil from Python

      pubsub.kikeriki.at / null_program · Wednesday, 15 September, 2021 - 02:46 · 23 minutes

    <p><em>This article was discussed <a href="https://news.ycombinator.com/item?id=28535255">on Hacker News</a>.</em></p> <p>Years ago, OpenBSD gained two new security system calls, <a href="https://man.openbsd.org/pledge.2"><code class="language-plaintext highlighter-rouge">pledge(2)</code></a> (originally <a href="https://www.openbsd.org/papers/tame-fsec2015/mgp00001.html"><code class="language-plaintext highlighter-rouge">tame(2)</code></a>) and <a href="https://man.openbsd.org/unveil.2"><code class="language-plaintext highlighter-rouge">unveil</code></a>. In both, an application surrenders capabilities at run-time. The idea is to perform initialization like usual, then drop capabilities before handling untrusted input, limiting unwanted side effects. This feature is applicable even where type safety isn’t an issue, such as Python, where a program might still get tricked into accessing sensitive files or making network connections when it shouldn’t. So how can a Python program access these system calls?</p> <p>As <a href="/blog/2021/06/29/">discussed previously</a>, it’s quite easy to access C APIs from Python through its <a href="https://docs.python.org/3/library/ctypes.html"><code class="language-plaintext highlighter-rouge">ctypes</code></a> package, and this is no exception. In this article I show how to do it. Here’s the full source if you want to dive in: <a href="https://github.com/skeeto/scratch/tree/master/misc/openbsd.py"><strong><code class="language-plaintext highlighter-rouge">openbsd.py</code></strong></a>.</p> <!--more--> <p>I’ve chosen these extra constraints:</p> <ul> <li> <p>As extra safety features, unnecessary for correctness, attempts to call these functions on systems where they don’t exist will silently do nothing, as though they succeeded. They’re provided as a best effort.</p> </li> <li> <p>Systems other than OpenBSD may support these functions, now or in the future, and it would be nice to automatically make use of them when available. This means no checking for OpenBSD specifically but instead <em>feature sniffing</em> for their presence.</p> </li> <li> <p>The interfaces should be Pythonic as though they were implemented in Python itself. Raise exceptions for errors, and accept strings since they’re more convenient than bytes.</p> </li> </ul> <p>For reference, here are the function prototypes:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">pledge</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">promises</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">execpromises</span><span class="p">);</span> <span class="kt">int</span> <span class="nf">unveil</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">path</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">permissions</span><span class="p">);</span> </code></pre></div></div> <p>The <a href="https://flak.tedunangst.com/post/string-interfaces">string-oriented interface of <code class="language-plaintext highlighter-rouge">pledge</code></a> will make this a whole lot easier to implement.</p> <h3 id="finding-the-functions">Finding the functions</h3> <p>The first step is to grab functions through <code class="language-plaintext highlighter-rouge">ctypes</code>. Like a lot of Python documentation, this area is frustratingly imprecise and under-documented. I want to grab a handle to the already-linked libc and search for either function. However, getting that handle is a little different on each platform, and in the process I saw four different exceptions, only one of which is documented.</p> <p>I came up with passing None to <code class="language-plaintext highlighter-rouge">ctypes.CDLL</code>, which ultimately just passes <code class="language-plaintext highlighter-rouge">NULL</code> to <a href="https://man.openbsd.org/dlopen.3"><code class="language-plaintext highlighter-rouge">dlopen(3)</code></a>. That’s really all I wanted. Currently on Windows this is a TypeError. Once the handle is in hand, try to access the <code class="language-plaintext highlighter-rouge">pledge</code> attribute, which will fail with AttributeError if it doesn’t exist. In the event of any exception, just assume the behavior isn’t available. If found, I also define the function prototype for <code class="language-plaintext highlighter-rouge">ctypes</code>.</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">_pledge</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">try</span><span class="p">:</span> <span class="n">_pledge</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">CDLL</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">use_errno</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="n">pledge</span> <span class="n">_pledge</span><span class="p">.</span><span class="n">restype</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_int</span> <span class="n">_pledge</span><span class="p">.</span><span class="n">argtypes</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_char_p</span><span class="p">,</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_char_p</span> <span class="k">except</span> <span class="nb">Exception</span><span class="p">:</span> <span class="n">_pledge</span> <span class="o">=</span> <span class="bp">None</span> </code></pre></div></div> <p>Catching a broad Exception isn’t great, but it’s the best we can do since the documentation is incomplete. From this block I’ve seen TypeError, AttributeError, FileNotFoundError, and OSError. I wouldn’t be surprised if there are more possibilities, and I don’t want to risk missing them.</p> <p>Note that I’m catching Exception rather than using a bare <code class="language-plaintext highlighter-rouge">except</code>. My code will not catch KeyboardInterrupt nor SystemExit. This is deliberate, and I never want to catch these.</p> <p>The same story for <code class="language-plaintext highlighter-rouge">unveil</code>:</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">_unveil</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">try</span><span class="p">:</span> <span class="n">_unveil</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">CDLL</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">use_errno</span><span class="o">=</span><span class="bp">True</span><span class="p">).</span><span class="n">unveil</span> <span class="n">_unveil</span><span class="p">.</span><span class="n">restype</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_int</span> <span class="n">_unveil</span><span class="p">.</span><span class="n">argtypes</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_char_p</span><span class="p">,</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">c_char_p</span> <span class="k">except</span> <span class="nb">Exception</span><span class="p">:</span> <span class="n">_unveil</span> <span class="o">=</span> <span class="bp">None</span> </code></pre></div></div> <h3 id="pythonic-wrappers">Pythonic wrappers</h3> <p>The next and final step is to wrap the low-level call in an interface that hides their C and <code class="language-plaintext highlighter-rouge">ctypes</code> nature.</p> <p>Python strings must be encoded to bytes before they can be passed to C functions. Rather than make the caller worry about this, we’ll let them pass friendly strings and have the wrapper do the conversion. Either may also be <code class="language-plaintext highlighter-rouge">NULL</code>, so None is allowed.</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">pledge</span><span class="p">(</span><span class="n">promises</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">execpromises</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">_pledge</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># unimplemented </span> <span class="n">r</span> <span class="o">=</span> <span class="n">_pledge</span><span class="p">(</span><span class="bp">None</span> <span class="k">if</span> <span class="n">promises</span> <span class="ow">is</span> <span class="bp">None</span> <span class="k">else</span> <span class="n">promises</span><span class="p">.</span><span class="n">encode</span><span class="p">(),</span> <span class="bp">None</span> <span class="k">if</span> <span class="n">execpromises</span> <span class="ow">is</span> <span class="bp">None</span> <span class="k">else</span> <span class="n">execpromises</span><span class="p">.</span><span class="n">encode</span><span class="p">())</span> <span class="k">if</span> <span class="n">r</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span> <span class="n">errno</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">get_errno</span><span class="p">()</span> <span class="k">raise</span> <span class="nb">OSError</span><span class="p">(</span><span class="n">errno</span><span class="p">,</span> <span class="n">os</span><span class="p">.</span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">))</span> </code></pre></div></div> <p>As usual, a return of -1 means there was an error, in which case we fetch <code class="language-plaintext highlighter-rouge">errno</code> and raise the appropriate OSError.</p> <p><code class="language-plaintext highlighter-rouge">unveil</code> works a little differently since the first argument is a path. Python functions that accept paths, such as <code class="language-plaintext highlighter-rouge">open</code>, generally accept either strings or bytes. On unix-like systems, <a href="https://simonsapin.github.io/wtf-8/">paths are fundamentally bytestrings</a> and not necessarily Unicode, so it’s necessary to accept bytes. Since strings are nearly always more convenient, they take both. The <code class="language-plaintext highlighter-rouge">unveil</code> wrapper here will do the same. If it’s a string, encode it, otherwise pass it straight through.</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">unveil</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="bp">None</span><span class="p">],</span> <span class="n">permissions</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">_unveil</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># unimplemented </span> <span class="n">r</span> <span class="o">=</span> <span class="n">_unveil</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">encode</span><span class="p">()</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">path</span><span class="p">,</span> <span class="bp">None</span> <span class="k">if</span> <span class="n">permissions</span> <span class="ow">is</span> <span class="bp">None</span> <span class="k">else</span> <span class="n">permissions</span><span class="p">.</span><span class="n">encode</span><span class="p">())</span> <span class="k">if</span> <span class="n">r</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span> <span class="n">errno</span> <span class="o">=</span> <span class="n">ctypes</span><span class="p">.</span><span class="n">get_errno</span><span class="p">()</span> <span class="k">raise</span> <span class="nb">OSError</span><span class="p">(</span><span class="n">errno</span><span class="p">,</span> <span class="n">os</span><span class="p">.</span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">))</span> </code></pre></div></div> <p>That’s it!</p> <h3 id="trying-it-out">Trying it out</h3> <p>Let’s start with <code class="language-plaintext highlighter-rouge">unveil</code>. Initially a process has access to the whole file system with the usual restrictions. On the first call to <code class="language-plaintext highlighter-rouge">unveil</code> it’s immediately restricted to some subset of the tree. Each call reveals a little more until a final <code class="language-plaintext highlighter-rouge">NULL</code> which locks it in place for the rest of the process’s existence.</p> <p>Suppose a program has been tricked into accessing your shell history, perhaps by mishandling a path:</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">hackme</span><span class="p">():</span> <span class="k">try</span><span class="p">:</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">pathlib</span><span class="p">.</span><span class="n">Path</span><span class="p">.</span><span class="n">home</span><span class="p">()</span> <span class="o">/</span> <span class="s">".bash_history"</span><span class="p">):</span> <span class="k">print</span><span class="p">(</span><span class="s">"You've been hacked!"</span><span class="p">)</span> <span class="k">except</span> <span class="nb">FileNotFoundError</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s">"Blocked by unveil."</span><span class="p">)</span> <span class="n">hackme</span><span class="p">()</span> </code></pre></div></div> <p>If you’re a Bash user, this prints:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>You've been hacked! </code></pre></div></div> <p>Using our new feature to restrict the program’s access first:</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># restrict access to static program data </span><span class="n">unveil</span><span class="p">(</span><span class="s">"/usr/share"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="n">unveil</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="n">hackme</span><span class="p">()</span> </code></pre></div></div> <p>On OpenBSD this now prints:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Blocked by unveil. </code></pre></div></div> <p>Working just as it should!</p> <p>With <code class="language-plaintext highlighter-rouge">pledge</code> we declare what abilities we’d like to keep by supplying a list of promises, <em>pledging</em> to use only those abilities afterward. A common case is the <code class="language-plaintext highlighter-rouge">stdio</code> promise which allows reading and writing of open files, but not <em>opening</em> files. A program might open its log file, then drop the ability to open files while retaining the ability to write to its log.</p> <p>An invalid or unknown promise is an error. Does that work?</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt;&gt;&gt; pledge("doesntexist", None) OSError: [Errno 22] Invalid argument </code></pre></div></div> <p>So far so good. How about the functionality itself?</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pledge</span><span class="p">(</span><span class="s">"stdio"</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="n">hackme</span><span class="p">()</span> </code></pre></div></div> <p>The program is instantly killed when making the disallowed system call:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Abort trap (core dumped) </code></pre></div></div> <p>If you want something a little softer, include the <code class="language-plaintext highlighter-rouge">error</code> promise:</p> <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pledge</span><span class="p">(</span><span class="s">"stdio error"</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="n">hackme</span><span class="p">()</span> </code></pre></div></div> <p>Instead it’s an exception, which will be a lot easier to debug when it comes to Python, so you probably always want to use it.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OSError: [Errno 78] Function not implemented </code></pre></div></div> <p>The core dump isn’t going to be much help to a Python program, so you probably always want to use this promise. In general you need to be extra careful about <code class="language-plaintext highlighter-rouge">pledge</code> in complex runtimes like Python’s which may reasonably need to do many arbitrary, undocumented things at any time.</p>
    • It chevron_right

      NomadBSD 1.4 Release Brings A New GUI to Easily Install Browsers & Other Important Improvements

      pubsub.do.nohost.me / ItsFoss News · Friday, 5 March, 2021 - 09:01

    NomadBSD 1.4 lets you easily install Brave, Chrome, and Vivaldi using a GUI and includes several improvements.

    The post NomadBSD 1.4 Release Brings A New GUI to Easily Install Browsers & Other Important Improvements appeared first on It's FOSS News .

    • It chevron_right

      Homura: A WINE-based Game Launcher for BSD

      pubsub.dcentralisedmedia.com / ItsFoss · Friday, 8 January, 2021 - 08:27 · 3 minutes

    BSD isn’t just for servers. People use it for desktop as well and perform common tasks including casual gaming. To help make that possible, we are going to look at an app that allows you to run Windows games on FreeBSD.

    What is Homura?

    Homura on GhostBSD

    Homura is a tool that allows you to play Windows games on FreeBSD. It was inspired by Lutris . It allows you to install and manage several Windows game and game store launchers. It mainly uses Wine, but also comes with a number of fixes and workarounds to get the games working.

    Homura’s creator, Alexander Vereeken , said that he created the application because “when I started using FreeBSD, there was no useful utility to set up games or launcher in wine, so I created one myself.” At the time, Wine was the only option. The Linux version of Steam did not exist.

    Homura install list Homura install list

    Here is a list of the things you can install with Homura:

    • Anarchy Online
    • Arc
    • Bethesda launcher
    • Blizzard launcher
    • Diablo II
    • Discord
    • Drakensang Online
    • GOG
    • Growtopia
    • League of Legends
    • Origin launcher
    • PokeMMO
    • Pokemon Uranium
    • RuneScape
    • Steam
    • Subway Surfers
    • Teamspeak
    • Tropix 2
    • UC Browser
    • Uplay
    • Wargaming Game Center
    • Itch.io

    Homura is named after a character in an anime named Madoka Magica . It was originally hosted on GitHub before the creator moved to GitLab. It is currently hosted on Codeberg. Hopefully, it will stay there for now.

    Homura about window Homura

    Installing Homura Game Launcher on BSD

    You can install Homura from the FreeBSD repo with this command:

    pkg install games/homura

    You can also build and install it from the ports collection using this command.

    cd /usr/ports/games/homura/ && make install clean

    Once it is installed, you can run Homura by selecting it from the menu or typing Homura in the command line. (The name must be capitalized in the terminal or it will not work.)

    If you install Steam via Homura, you need to launch it from Homura. If you launch it from the operating system’s menu, it won’t display currently.

    Steam’s library and store tabs are displayed by a built-in web browser. For some reason, that does not work on FreeBSD. But if you launch Steam from Homura’s menu, it will use a list mode that works without issue.

    Experience

    I installed Homura on GhostBSD and used it to install Steam. Afterward, I installed a couple of games to test it out. Not all of the games I tried worked, mainly because they tried to use or install a Windows-specific piece of software that was unavailable. However, I was able to play one of my favorite games, Microsoft’s Rise of Nations, without any issue. (My test turned into a couple of hours of gameplay.)

    Homura Main Menu Homura Main Menu

    I also tried to install the GOG launcher. For some reason, it didn’t work for me. The loading screen would pop up and nothing would happen. I’m planning to file an issue. I didn’t test any of the installer/launchers because I don’t use them.

    Final Thoughts

    Not everything worked smoothly with Homura, but I could play some of my favorite games.

    Rise of Nation on BSD Rise of Nation on BSD

    This app is the classic case of a user who had a need and decided to fill it. In doing so, he makes life easier for others. Hopefully, this application will make it a little easier for people to start using FreeBSD as their operating system.

    If you found this article interesting, please take a minute to share it on social media, Hacker News, or Reddit .