Převod keystore mezi JKS a P12

No Comments

Převod funguje od verze JDK 6.

JKS → P12
keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12

P12 → JKS
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks

Jednoduchý kernelový modul pro FreeBSD

No Comments

Rozhodl jsem se pustit do velkého dobrodružství, a tím je vývoj ovladače pro jeden nejmenovaný distribuovaný filesystém na FreeBSD. Tedy pouze klienta. Odvážně se pouštím tam, kam se dosud nikdo nevydal…

Dobrá tedy, začněme s vytvářením kernelového modulu do FreeBSD. Tady je návod jak vytvořit jednoduchý modul, který při nahrání a odebrání z/do kernelu zapíše záznam do syslogu. Nic víc.

Události definované v module.h

První na co se podíváme, je hlavičkový soubor module.h (/usr/include/sys/module.h) Při nahrávání/odebírání modulu do kernelu se volá module event handler, který ošetřuje tyto události (dříve existovaly jen první tři, bez MOD_QUIESCE).

  • MOD_LOAD
  • MOD_UNLOAD
  • MOD_SHUTDOWN
  • MOD_QUIESCE
typedef enum modeventtype {
        MOD_LOAD,
        MOD_UNLOAD,
        MOD_SHUTDOWN,
        MOD_QUIESCE
} modeventtype_t;

typedef struct module *module_t;
typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);

Když je modul nahrán, tak je event handler zavolán s argumentem what nastaveným na hodnotu MOD_LOAD.

Při odstraňování, tedy po zavolání kldunload, je event handler volán s what nastaveným na MOD_QUIESCE. Jestliže se akce nezdaří, pak je vrácena nenulová hodnota. Pakliže odstraňování pokračuje, potom je what nastaven na MOD_UNLOAD. Když modul vrátí nenulovou hodnoty, pak se odstranění z jádra neprovede. Celé je to ještě složitější, když se to provádí na více modulech naráz.

Rozdíl mezi MOD_QUIESCE a MOD_UNLOAD je v tom, že MOD_QUIESCE může skončit s chybou když je modul právě používán, ale MOD_UNLOAD skončí s chybou jen když je nemožné nemožné jej odstranit (existují odkazy na paměť, které nemohou být zrušeny).

Jestliže je vypínán systém, pak what je MOD_SHUTDOWN.

U nepodporovaných a nerozeznaných hodnot what může modul vracet EOPNOTSUPP

DECLARE_MODULE v module.h

Dalším krokem je prolinkování s kernelem. Stačí prostě zavolat DECLARE_MODULE.

#define DECLARE_MODULE(name, data, sub, order)

Macro má čtyři argumenty:

  • name
  • Jméno modulu, které se volá v SYSINIT() k identifikaci modulu.

  • data
  • Struktura moduledata_t, která má dvě položky, oficiální jméno modulu a ukzatel na fuknci obsluhující události (event handler).

  • sub
  • Odkazuje na SYSINIT() macro, a určuje typ systémových rozhraní. Platné hodnoty obsahuje sysinit_sub_id v . Např. SI_SUB_DRIVERS se použije pro ovladač.

  • order
  • Opet pro SYSINIT(). Určuje pořadí v jakém bude modul nahrán. Platné hodnoty jsou SI_ORDER_FIRST, SI_ORDER_SECOND, SI_ORDER_THIRD, SI_ORDER_FOURTH, SI_ORDER_MIDDLE, SI_ORDER_ANY.

Pro úplnost přikládám i celý soubor module.h, může se ještě hodit. :-)

/*-
 * Copyright (c) 1997 Doug Rabson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: src/sys/sys/module.h,v 1.25.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $
 */

#ifndef _SYS_MODULE_H_
#define _SYS_MODULE_H_

/*
 * Module metadata types
 */
#define MDT_DEPEND      1               /* argument is a module name */
#define MDT_MODULE      2               /* module declaration */
#define MDT_VERSION     3               /* module version(s) */

#define MDT_STRUCT_VERSION      1       /* version of metadata structure */
#define MDT_SETNAME     "modmetadata_set"

typedef enum modeventtype {
        MOD_LOAD,
        MOD_UNLOAD,
        MOD_SHUTDOWN,
        MOD_QUIESCE
} modeventtype_t;

typedef struct module *module_t;
typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);

/*
 * Struct for registering modules statically via SYSINIT.
 */
typedef struct moduledata {
        const char      *name;          /* module name */
        modeventhand_t  evhand;         /* event handler */
        void            *priv;          /* extra data */
} moduledata_t;

/*
 * A module can use this to report module specific data to the user via
 * kldstat(2).
 */
typedef union modspecific {
        int     intval;
        u_int   uintval;
        long    longval;
        u_long  ulongval;
} modspecific_t;

/*
 * Module dependency declarartion
 */
struct mod_depend {
        int     md_ver_minimum;
        int     md_ver_preferred;
        int     md_ver_maximum;
};

/*
 * Module version declaration
 */
struct mod_version {
        int     mv_version;
};

struct mod_metadata {
        int             md_version;     /* structure version MDTV_* */
        int             md_type;        /* type of entry MDT_* */
        void            *md_data;       /* specific data */
        const char      *md_cval;       /* common string label */
};

#ifdef  _KERNEL

#include <sys/linker_set.h>

#define MODULE_METADATA(uniquifier, type, data, cval)                   \
        static struct mod_metadata _mod_metadata##uniquifier = {        \
                MDT_STRUCT_VERSION,                                     \
                type,                                                   \
                data,                                                   \
                cval                                                    \
        };                                                              \
        DATA_SET(modmetadata_set, _mod_metadata##uniquifier)

#define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax)               \
        static struct mod_depend _##module##_depend_on_##mdepend = {    \
                vmin,                                                   \
                vpref,                                                  \
                vmax                                                    \
        };                                                              \
        MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND,        \
            &_##module##_depend_on_##mdepend, #mdepend)

/*
 * Every kernel has a 'kernel' module with the version set to
 * __FreeBSD_version.  We embed a MODULE_DEPEND() inside every module
 * that depends on the 'kernel' module.  It uses the current value of
 * __FreeBSD_version as the minimum and preferred versions.  For the
 * maximum version it rounds the version up to the end of its branch
 * (i.e. M99999 for M.x).  This allows a module built on M.x to work
 * on M.y systems where y >= x, but fail on M.z systems where z < x.
 */
#define MODULE_KERNEL_MAXVER    (roundup(__FreeBSD_version, 100000) - 1)

#define DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver)      \
        MODULE_DEPEND(name, kernel, __FreeBSD_version,                  \
            __FreeBSD_version, maxver);                 \
        MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name);          \
        SYSINIT(name##module, sub, order, module_register_init, &data); \
        struct __hack

#define DECLARE_MODULE(name, data, sub, order)                          \
        DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)

/*
 * The module declared with DECLARE_MODULE_TIED can only be loaded
 * into the kernel with exactly the same __FreeBSD_version.
 *
 * Use it for modules that use kernel interfaces that are not stable
 * even on STABLE/X branches.
 */
#define DECLARE_MODULE_TIED(name, data, sub, order)                             \
        DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)

#define MODULE_VERSION(module, version)                                 \
        static struct mod_version _##module##_version = {               \
                version                                                 \
        };                                                              \
        MODULE_METADATA(_##module##_version, MDT_VERSION,               \
            &_##module##_version, #module)

extern struct sx modules_sx;

#define MOD_XLOCK       sx_xlock(&modules_sx)
#define MOD_SLOCK       sx_slock(&modules_sx)
#define MOD_XUNLOCK     sx_xunlock(&modules_sx)
#define MOD_SUNLOCK     sx_sunlock(&modules_sx)
#define MOD_LOCK_ASSERT sx_assert(&modules_sx, SX_LOCKED)
#define MOD_XLOCK_ASSERT        sx_assert(&modules_sx, SX_XLOCKED)

struct linker_file;

void    module_register_init(const void *);
int     module_register(const struct moduledata *, struct linker_file *);
module_t        module_lookupbyname(const char *);
module_t        module_lookupbyid(int);
int     module_quiesce(module_t);
void    module_reference(module_t);
void    module_release(module_t);
int     module_unload(module_t);
int     module_getid(module_t);
module_t        module_getfnext(module_t);
const char *    module_getname(module_t);
void    module_setspecific(module_t, modspecific_t *);
struct linker_file *module_file(module_t);

#ifdef  MOD_DEBUG
extern int mod_debug;
#define MOD_DEBUG_REFS  1

#define MOD_DPF(cat, args) do {                                         \
        if (mod_debug & MOD_DEBUG_##cat)                                \
                printf(args);                                           \
} while (0)

#else   /* !MOD_DEBUG */

#define MOD_DPF(cat, args)
#endif
#endif  /* _KERNEL */

#define MAXMODNAME      32

struct module_stat {
        int             version;        /* set to sizeof(struct module_stat) */
        char            name[MAXMODNAME];
        int             refs;
        int             id;
        modspecific_t   data;
};

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
int     modnext(int _modid);
int     modfnext(int _modid);
int     modstat(int _modid, struct module_stat *_stat);
int     modfind(const char *_name);
__END_DECLS

#endif

#endif  /* !_SYS_MODULE_H_ */

Jadený modul

Pojďme využít předchozích znalostí k vytvoření primitivního modulu, a trochu oprášíme znalost jazyka ANSI C. Následující zdrojový soubor jsem vytvořil ve zvláštním adresáři, třeba /root/KIVFS, a pojmenoval kivfs-FreeBSD-client.c

#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/syslog.h>

/* 
 * Load handler that deals with the loading and unloading of a KLD.
 */
static int load_module(struct module *m, int event, void *arg)
{
    int error = 0;
    switch (event)
    {
        case MOD_LOAD:                            /* kldload */
            log(LOG_INFO, "KIVFS module loaded\n");
            break;

        case MOD_QUIESCE:                         /* kldunload */
            log(LOG_INFO, "KIVFS module will be unloaded\n");
            break;

        case MOD_UNLOAD:                          /* kldunload */
            log(LOG_INFO, "KIVFS module unloaded\n");
            break;

        default:
            error = EOPNOTSUPP;
            break;
    }
    return(error);
}

static moduledata_t kivfs_module =
{
    "kivfs",
    load_module,
    NULL
};

DECLARE_MODULE(kivfs, kivfs_module, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);

A k němu odpovídající Makefile. KMOD je jméno modulu, a SRCS je jméno zdrojového souboru.

KMOD= kivfs
SRCS= kivfs-freebsd-client.c
.include <bsd.kmod.mk>

Ted v našem adresáři spustíme příkaz make, a bude hotovo. No není to jednoduché?

# make
Warning: Object directory not changed from original /root/KIVFS
@ -> /usr/src/sys
machine -> /usr/src/sys/amd64/include
cc -O2 -pipe -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -I. -I@ -I@/contrib/altq -I@/../include -I/usr/include -finline-limit=8000 -fno-common -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -fformat-extensions -std=c99 -c kld.c
ld -d -warn-common -r -d -o kivfs.ko kivfs-freebsd-client.o
:> export_syms
awk -f /sys/conf/kmod_syms.awk kivfs.ko export_syms | xargs -J% objcopy % kivfs.ko
objcopy --strip-debug kivfs.ko
#

Pokud nedojde k nějaké chybě, která nastat prostě nemůže :), tak už stačí jen modul nahrát, a podívat se do syslogu.

# kldload  ./kivfs.ko
# kldunload ./kivfs.ko
# tail -3 /var/log/messages
Nov 27 21:35:29  kernel: KIVFS module loaded
Nov 27 21:35:33  kernel: KIVFS module will be unloaded
Nov 27 21:35:33  kernel: KIVFS module unloaded
#

Závěr

Dál už tady mám jenom nožičky a závěr. K napsání tohoto článku mne vedla snaha udělat si v dané problematice jasno. Řekl bych, že to pomohlo. Snad to pomůže i někomu dalšímu.

jaderné moduly ve FreeBSD

No Comments

Ve FreeBSD se jaderné moduly nazívají KLD, a ovládají se těmito příkazy:

  • kldload – nahraje kernelový modul
  • kldunload – odstraní z kernelu modul
  • kldstat – vypíše aktuálně nahrané moduly

Moduly se běžně nahrávají z těchto adresářů /boot/kernel a /boot/modules, případně z cesty kterou nadefinujeme pomocí kldconfig. Aktuálně platné adresáře vypíše příkaz kldconfig -r.

Pro nahrání modulu je tedy potřeba nakopírovat jej do správného adresáře, nebo použít absolutní/relativní cestu k souboru modulu (koncovka .ko).

# kldload -v kivfs
Loaded kivfs, id=2
#
# kldstat
Id Refs Address            Size     Name
 1    3 0xffffffff80100000 c9fe20   kernel
 2    1 0xffffffff80e22000 13a      kivfs.ko
#
# kldunload kivfs
# tail -2 /var/log/messages
Nov 26 21:18:16  kernel: KIVFS loaded
Nov 26 21:22:33  kernel: KIVFS unloaded
#
# kldstat
Id Refs Address            Size     Name
 1    3 0xffffffff80100000 c9fe20   kernel
#

administrace Weblogic bez znalosti hesla (storeUserConfig)

No Comments

Weblogic již od pradávna nabízí přístup k administraci ne jen přes webovou konzoli (http://url:port/console), ale i pomocí příkazové řádky. Je zde starší weblogic.Admin nebo weblogic.Deployer, ale hlavně v současné době preferovaný WLST.

Když se připojujete na daný server, tak musíte vždy zadat jméno a heslo. Vyplňovat jméno a heslo někam do scriptu není to pravé, a od toho tu je storeUserConfig. Jedná se o dva soubory, první (user configuration file) obsahuje zacryptované uživatelské jméno a heslo a druhý (key file) obsahuje klíč pro odcryptování.

weblogic.Admin

(POZOR: weblogic.Admin je již nepodporovaný)

Vygenerování UserConfigFile a UserKeyFile:

#!/usr/bin/sh
JAVA_HOME=/opt/bea/wls8.1_SP6/jdk
CLASSPATH=/opt/bea/wls8.1_SP6/weblogic81/server/lib/weblogic.jar

WLSURL=t3://server_name:port
USERNAME=system
PASSWORD=password

U_CONFIG_FILE=~/.user_config_file
U_KEY_FILE=~/.user_key_file

# Vygenerování souborů
$JAVA_HOME/bin/java -cp $CLASSPATH weblogic.Admin -url $WLSURL -username $USERNAME -password $PASSWORD -userconfigfile ${U_CONFIG_FILE} -userkeyfile ${U_KEY_FILE} STOREUSERCONFIG 

Místo parametrů -username a -password je potřeba použít -userconfigfile a -userkeyfile, přičemž jejich hodnoty jsou cesty k těmto souborům.

java weblogic.Admin -url $WLSURL -username $USERNAME -password $PASSWORD
java weblogic.Admin -url $WLSURL -userconfigfile ${U_CONFIG_FILE} -userkeyfile ${U_KEY_FILE}

oficiální dokumentace…

WLST

Syntaxe ve WLST:
storeUserConfig([userConfigFile], [userKeyFile], [nm])
Generování storeUserConfig ve WLST:

wls:/mydomain/serverConfig>  storeUserConfig('c:/myFiles/myuserconfigfile.secure', 'c:/myFiles/myuserkeyfile.secure')
Creating the key file can reduce the security of your system if it is not kept in a secured location after it is created. Do you want to create the key file? y or n
y
The username and password that were used for this current WLS connection are stored in c:/myFiles/mysuserconfigfile.secure and c:/myFiles/myuserkeyfile.secure
wls:/mydomain/serverConfig>

Doporučuji vynechat oba parametry, soubory se pak vygenerují v HOME adresáři, a to pod názvem username-WebLogicConfig.properties, kde první část je nahražena uživatelským jménem, tedy třeba weblogic. Příkaz connect() bez parametrů se nejdříve dívá zda neexistují v home adresáři právě takovéto soubory, proto je výhodné generovat je bez parametrů. Tato vlastnost je bohužel až u WebLogicu 10, u devítky jsou jak pro vygenerování, tak pak pro připojení oba parametry nutné. V devítce se tedy připojujete nějak takto: connect(userConfigFile='~/myuserconfigfile.secure', userKeyFile='~/myuserkeyfile.secure')

Příkaz storeUserConfig má ještě třetí parametr pro uložení hesla node manageru, to se může hodit pokud používáte node managery.

oficiální dokumentace…

ANT

Mezi základní parametry wlconfig Ant tasku patří mimo jiné userconfigfile a userkeyfile. Tedy opět nic složitého, prostě místo username a password použijete tyto parametry a je to.

oficiální dokumentace…

Bezpečnost

StoreUserConfig je užitečná věc, ale nezapomínejte na bezpečnost. Právo čtení k těmto souborům by asi nemusel mít každý uživatel systému. ;)

licence produktů BEA po přechodu pod Oracle

No Comments

Oracle před časem oznámil změnu licenční politiky. Dřívě byl každý produkční licenční soubor vygenerován pro danou IP adresu, pro daný počet jednotek, a pro daný počet CPU. Oracle má tuto politiku mnohem volnější. Prostě si stáhnete licenční soubor pro daný produkt, to ale neznamená, že nemusíte mít licenci zaplacenu. ;-) Mnohem zajímavější je pravděpodobná změna počítání počtu CPU, v závislosti na počtu jejich jader.

Více se snad dozvíme na setkání s Oracle v Praze.

Older Entries Newer Entries

powered by EndomondoWP