La cosa più importante da fare è comunicare. Chiedi alle persone su ports@openbsd.org se stanno lavorando sullo stesso port. Dillo all'autore del software originale, compresi i problemi che potresti incontrare. Se le informazioni sulla licenza non sembrano corrette, diglielo. Se hai dovuto fare i salti mortali per compilare il port, digli cosa può sistemare. Se stanno sviluppando solo per Linux e sembrano ignorare il resto del mondo Unix, cerca di cambiare il loro punto di vista.
La COMUNICAZIONE fa la differenza fra un port di successo e un port che verrà lentamente abbandonato da tutti.
Per prima cosa leggi le informazioni in questa pagina. Quindi dai un occhio ai documenti indicati, specialmente la checklist per il porting su OpenBSD.
Testa, poi ri-testa e infine testa ancora!
Sottometti il port. Crea un tarball gzippato della directory del port. Puoi metterlo su un server FTP o HTTP pubblico, spedendo il suo indirizzo a ports@openbsd.org o spedisci il port, codificato mime, allo stesso indirizzo. Scegli il metodo migliore per te.
/usr/local/etc/rc.d./usr/local è spesso condivisa fra più macchine tramite NFS.
Per questo motivo i file di configurazione specifici di una macchina non
possono essere contenuti in /usr/local, /etc è
il deposito centrale per i file di configurazione della macchina.
Inoltre, la politica di OpenBSD è di non aggiornare mai automaticamente i
file in /etc. I port che hanno bisogno di specifiche
impostazioni di boot dovrebbero avvertire l'amministratore di cosa fare
anziché installare file alla cieca.
-lcrypt.libc standard.
/usr/ports/infrastructure/db/user.list.
$OpenBSD$ al
Makefile. Importando un port da un altro sistema assicurati di lasciare
anche il loro tag nel Makefile.
strcat/strcpy/strcmp/sprintf. In generale,
sprintf dovrebbe essere sostituita con snprintf.
/tmp con link simbolici a file più
strategici, come /etc/master.passwd.
fopen che freopen
creano un nuovo file o ne aprono uno esistente in
scrittura. Un attaccante potrebbe creare un link simbolico da
/etc/master.passwd a /tmp/addrpool_dump.
Appena lo apri, il tuo file delle password viene modificato. Già, anche
con un unlink subito prima. Restringi solo il campo delle
possibilità. Usa piuttosto open con
O_CREAT|O_EXCL e fdopen.
mktemp. Dai
retta agli avvertimenti del linker bsd sul suo utilizzo. Devono
essere corretti. Non è facile come code>s/mktemp/mkstemp/g.
mktemp(3) di OpenBSD
current per maggiori informazioni. Codice che usa corretamente
mkstemp comprende il sorgente di ed o
mail. Un raro esempio di codice che usa corretamente
mktemp può essere trovato nel port di rsync.
startx. Come
programma setuid, potevi lanciare startx con qualunque file come script.
Se il file non era uno shell script valido, si otteneva un messaggio di
errore, insieme alla prima riga del file in questione, senza ulteriori
verifiche sui permessi. Molto utile per ottenere la prima riga del file
shadow delle password, considerando che comincia spesso con la riga di
root. Non aprire il file, e poi fai un fstat sul descrittore
aperto per verificare se avresti dovuto essere in grado di aprirlo
(altrimenti l'attaccante giocherà con /dev/rst0 e riavvolgerà il nastro)
-- aprilo con le informazioni uid/gid/grouplist corrette.
popen e
system. Usa invece fork, pipe
e execve
/dev/fd/0.
inetd e aggingere
le voci corrispondenti in inetd.conf. Devi conoscere la
giusta magia per scrivere demoni corretti. Si può dire che non conviene
scrivere programmi setuid se non si sa come si fa.
xkobo per un cambiamento del
genere.
PATH (non usare mai code>system con un percorso non
assoluto, evita execvp), ma anche molto più sottili come
le impostazioni local, il fuso orario, termcap, eccetera. Fai attenzione
alla transitività: anche se prendi tutte le precauzioni, i programmi che
chiami direttamente non lo faranno necessariamente.Non usare
mai system in programmi privilegiati,
costruisci la tua riga di comando, un ambiente controllato e chiama
execve direttamente. La man page di perlsec
è una buona guida per questi problemi.
issetugid di OpenBSD affronta questo problema,
dal punto di vista dell'autore di librerie. Non provare a portare
librerie se non afferri fino in fondo questo problema.
__OpenBSD__ dovrebbe essere usato di rado, se non mai.
Costrutti ome
#if defined(__NetBSD__) || defined(__FreeBSD__)
sono spesso fuori luogo. Non aggiungere __OpenBSD__ alla
cieca. Cerca invece di capire cosa sta succedendo, e quale funzionalità
è effettivamente richiesta. La pagine di manuale sono spesso utili, dato
che includono commenti storici, spiegando quando una certa funzionalità
è stata inclusa in BSD. Verificare il valore numerico di BSD
a seconda delle release è spesso il modo giusto. Vedi
The NetBSD pkgsrc guide
per maggiori informazioni.
BSD è una pessima idea. Cerca di includere
sys/param.h. Non solo definisce BSD, ma gli dà
anche un valore corretto. Il frammento di codice corretto sarebbe:
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
tcgetattr funziona
anziché se sei su BSD 4.3 o successivo, o SystemVR4. Questi tipi di test
confondono solo il problema. Un modo di procedere può essere, ad esempio,
fare prove su un sistema particolare, impostare un gruppo di define
HAVE_TCGETATTR, quindi passare al sistema successivo.
Questa tecnica permette di separare i test sulle funzionalità dai sistemi
operativi. Nella fretta, un porter può aggiungere l'intero insieme di
define -DHAVE_XXX al Makefile. Può anche aggiungere o
scrivere in un file di configurazione di verificare quella funzionalità
e aggiungerla automaticamente. Come esempio da non seguire, vedi il
sorgente di nethack 3.2.2: ipotizza un mare di cose in base al tipo di
sistema. La maggior parte di queste ipotesi sono obsolete e non
riflettono più la realtà: le funzioni POSIX sono molto più utili delle
vecchie differenze fra BSD e SystemV, tanto che ormai alcune funzioni BSD
tradizionali sono supportate solo tramite le librerie di compatibilità.
#define POSIX_C_SOURCE in tutto il progetto, non quando ti
pare.
unistd.h, fcntl.h o
termios.h.
La man page indica spesso dove si trova il prototipo. Potresti aver
bisogno di un altro gruppo di macro HAVE_XXX per procurarti
il file giusto. Non preoccuparti di includere lo stesso file due volte,
i file include hanno guardie che prevengono ogni tipo di stranezze.unsigned long al posto di
size_t). Inoltre, alcuni compilatori, come il gcc di
OpenBSD, fanno un lavoro migliore con alcune funzioni usatissime come
strlen se si includono i file header corretti.
/* prototype part */
#ifdef USE_OWN_GCVT
char *foo_gcvt(double number, size_t ndigit, char *buf);
#else
/* include correct file */
#include <stdlib.h>
/* use system function */
#define foo_gcvt gcvt
#endif
/* definition part */
#ifdef USE_OWN_GCVT
char *foo_gcvt(double number, size_t ndigit, char *buf)
{
/* proper definition */
}
/* typical use */
s = foo_gcvt(n, 15, b);
bsd.port.mk impostano il percorso
degli installer. In particolare, impostano di cercare prima in
/usr/bin e /bin che in
/usr/local/bin e /usr/X11R6/bin.
${NO_SHARED_LIBS} è impostato a yes (attenzione, può essere
definito solo dopo l'inclusione di bsd.port.mk). Se il tuo
port ha un configure GNU, aggiungi semplicemente la riga
CONFIGURE_ARGS += ${CONFIGURE_SHARED} al Makefile.
bsd.port.mk, dato che si suppone che chiunque aggiorni
l'intero albero dei port, compreso bsd.port.mk.
NEED_VERSION è ormai obsoleto.
update-plist per generare e aggiornare
le packing-list anziché fare le cose a mano.
Puoi commentare le righe che non ti servono.
update-plist può identificare la maggior parte dei tipi di
file e copiare la maggior parte delle annotazioni extra correttamente.
USE_SYSTRACE=Yes a /etc/mk.conf per
individuare script, Makefiles, etc. non corretti.
curses.h/libcurses/libtermlib sono le
``new curses''. Modifica:ncurses.h ==> curses.h_USE_OLD_CURSES_ prima di includere curses.h
(di solito in un Makefile) e linkando con -locurses.
sgtty
BSD alla nuova famiglia POSIX tcgetattr. Evita il vecchio
stile nel nuovo codice. Del codice può definire
tcgetattr come sinonimo del vecchio sgtty, ma
questo è al massimo una via di fuga su OpenBSD.
Il codice sorgente di xterm è un ottimo esempio di cosa non
fare. Cerca di rendere corrette le funzionalità del tuo sistema: vuoi un
tipo che immagazzini lo stato del tuo terminale (possibile typedef),
vuoi una funzione che ricavi lo stato corrente e una funzione che imposti
il nuovo stato. Le funzioni che modifichino questo stato sono più
difficili, dato che variano a seconda del sistema. Inoltre, ricorda che
dovrai gestire casi in cui non sei connesso a un terminale e che devi
gestire i segnali: non solo di termine, ma anche background
(SIGTSTP). Dovresti sempre lasciare il terminale in uno
stato corretto. Fai i test con una vecchia shell, come sh, che non
resetta in alcun modo il terminale alla fine del programma.
TERMCAP e farlo funzionare correttamente.
sigaction per essere sicuro di una specifica semantica
insieme ad altre chiamate di sistema menzionate nella man page
corrispondente.