TOC 
M. Rose
 Dover Beach Consulting, Inc.
 D. New
 June 2002

beepcore-tcl v1.6.1


 TOC 

Table of Contents




 TOC 

1. Introduction

This document describes an implementation of the BEEP core[1] in Tcl. It maps[2] BEEP over TCP. This package allows you to write your own BEEP profiles in Tcl by adding a profile-*.tcl module to the "scripts/" directory. Running "etc/beepd-boot.tcl" will create all the necessary control files.

The top-level information flow is:

    +---------+
    +  inetd  +
    +---------+
        |                +---------------+
        +--------------->| beepd.sh/.tcl |
                         +---------------+
          +-------------+    |   |
          | TLS profile |<---+   |
          +-------------+    |   |
             The PROFILE API |   |  The PEER API
        +---------------+    |   |
        | SASL profiles |<---+   |   +----------+
        +---------------+    |   +-->| Peer API |
                             |       +----------+
        +---------------+    |          |
        | your profiles |<---+          +-->--TCP/IP
        +---------------+

This toolkit is designed to be invoked from inetd. However, the routines are event-driven and non-blocking, so with appropriate rewrites of the outer loops, they can be embedded in a more sophisticated socket management subsystem. Implementing a new profile consists of creating a profile module that implements the Profile API. More sophisticated applications can code directly to the Peer API. Both APIs (along with several others) are documented here.



 TOC 

2. Required and Optional Software

You should already have installed:

In addition, if you want TLS support, then also:

In addition, if you want comprehensive SASL support (mechanisms other than ANONYMOUS, EXTERNAL and OTP), then also:

Finally, if you want to support the DNS' SRV RRs, then also:



 TOC 

3. The Server

The software architecture for the server is three-level:

+-----------------------------------------+
|                 server                  |
+-----------------------------------------+
                    /|\
                     |
                profile api
                     | (Section 5.1)
                     V
+-----------+  +-----------+  +------------+  +-----------+
| SASL      |  | SASL      |  | your       |  | transport |
| anonymous |  |    OTP    |  | application|  |  security |
|   profile |  |   profile |  |   profile  |  |   profile |
+-----------+  +-----------+  +------------+  +-----------+
             /|\                
              |                
      authorization api         
              | (Section 5.2)  
              V                
+--------------------------+  
| authorization            |                  miscellaneous apis
|                datastore |                    logging (Section 8.1)
+--------------------------+                    utility (Section 8.2)

3.1 Directory Layout

$prefix/
    beepd/                          the "home" directory

        auth/                       authorization database
            anonymous.sasl          entry used for user "anonymous"
            default                 entry used when not logged-in
            external.tcl            site-specific external ID mapping
            unknown                 entry used when authenticated,
                                        but no authorization entry
            *.sasl                  user's file
            *.lock                  lock-in-progress
            *.tmp                   file being updated

        beepd.sh                    invoked by inetd

        certs/                      certificates for TLS negotiation
            privkey.pem                the server's private key
            server.pem                 the server's public key certificate

        etc/
            add-inetd.conf          example line to add to /etc/inetd.conf
            add-services.conf       example line to add to /etc/services
            authmgmt.tcl            manage authorization database
            beepd-boot.tcl          initializes a server
            beepng.tcl              test server installation/connectivity
            makeCert.sh             a shell script to make a self-signed 
                                       certificate
            otp-init.tcl            creates an OTP user

                                    run-time configuration files
            clickZ                    if present, turns on timing stats
            debugP                    if present, turns on debug level 1
            serverD                   if present, used to set list of domains
                                         for this server-instance

        logs/
            authmgmt.log              authorization management log
            beepd.log                 server operation log
            beepng.log                server testing log
            boot.log                  server initialization log
            otp-init.log                ..

        scripts/
            beepd.tcl               BEEP server

                                    automatically created by etc/beepd-boot.tcl
            beepd-plaintext.tcl       profiles allowing plaintext 
            beepd-encrypted.tcl       profiles requiring encryption 
            pkgIndex.tcl              package index 

                                    server-specific packages
            beep-server.tcl           BEEP server loop       (Section 5.1)
            beep-sasl.tcl             authorization routines (Section 5.2)

                                    server profiles
            profile-anonymous.tcl     SASL/ANONYMOUS profile
            profile-authmgmt.tcl      authorization management 
            profile-cyrus.tcl         Cyrus SASL profiles
            profile-external.tcl      SASL/EXTERNAL profile
            profile-null.tcl          ECHO and SINK profile
            profile-otp.tcl           SASL/OTP profile
            profile-sudys.tcl         SOAP profile
            profile-syslog-raw.tcl    syslog RAW profile (demo only)
            profile-tlsv1.tcl         TLS profile
            profile-tunnel.tcl        TUNNEL profile

                                    client-specific packages
            beep-client.tcl           BEEP client API        (Section 6.1)

                                    generic packages
            beep-peer.tcl             BEEP framing           (Section 7.1)
            beep-logging.tcl          logging                (Section 8.1)
            beep-utilities.tcl        utility                (Section 8.2)

3.2 Package Configuration and Installation

The first thing you should do is run "configure", followed by "make install":

% ./configure --prefix=/usr/pkg
% make install

This will install the directory hierarchy for the server, and create a link from the Tcl library area to the "beepcore" packages. At the tail end of the installation, two scripts, "etc/beepd-boot.tcl" and "etc/makeCert.sh", are run.

The "etc/beepd-boot.tcl" script is used to prepare the automatically-generated files in the beep hierarchy (including "pkgIndex.tcl"), and initialize the authorization database. This script is run automatically, but if you install new profiles in your server, you'll need to re-run it, so here's the invocation:

    % cd $prefix/beepd/
    % ./etc/beepd-boot.tcl . privacyRequired anonymousAllowed 

The arguments are:

privacyRequired:
determines whether encryption must be in use prior to authentication and data exchange, one of "yes" or "no"; and,
anonymousAllowed:
determines whether to create an authorization entry for "anonymous" authentication (trace information only) is permissible, one of "yes" or "no".

Then, the "etc/makeCert.sh" script is run to generate certificates for use by "scripts/profile-tlsv1.tcl". If you already have certificates, you can link them into the "certs/" directory; otherwise, "etc/makeCert.sh" will prompt for the information defining your server.

To "turn on" the beep listener, you'll need to update "/etc/services" and "inetd.conf", and then restart inetd. Take a look in the "etc/" directory and you'll find some examples.

To test the installation, use "etc/beepng.tcl", the debugging client.

3.3 The Debugging Client

The debugging client packaged with this release is etc/beepng.tcl.

The program takes one required argument, one of:

echo
indicating the ECHO profile should be used; or,
sink
indicating the SINK profile should be used; or,
many
indicating the ECHO profile should be used in a one-to-many exchange; or,
syslog/raw
indicating the syslog RAW profile should be used.

The beepng.tcl program also accepts these optional arguments:

-server
indicating the domain name or IP address to connect to;
-count
indicating the number of messages to send; and,
-size
indicating the size (in octets) of each message to send.

In addition, any optional argument to client::init is accepted, providing that it occurs before the one required argument, e.g.,

    etc/beepng.tcl -server example.com \
        -privacy strong echo -count 10 -size 65535


 TOC 

4. Server Administration

4.1 The Authorization Database

The "auth/" directory holds the files pertaining to the authorization database.

Data exchange profiles (the kind of profiles you'll be implementing) typically use only one call from the Authorization API, beepcore::sasl::allowP, which determines whether the profile should perform a given action. The server makes this determination based on the "authorization entry" currently in use.

When the server starts, it looks for a file called "auth/default" that contains the initial authorization entry. If this file is not present, it uses a hard-wired default which "just says no". Later, if and when the remote peer authenticates itself, the server uses the corresponding authentorization entry from the "auth/" directory.

It turns out that the authorization entry may also hold authentication information that is used by the "native" SASL profiles that come with this package. However, if you use Cyrus SASL profiles (and you really should), the authentication information in the entry isn't consulted. The only problem with this is that it's possible for a user to authenticate without having an entry in the authorization database. If this happens, after logging the event, the server looks for a file called "auth/unknown" and uses the authorization entry contained therein.

You can use the etc/authmgmt.tcl program to configure the "default" and "unknown" entries as you see fit.

4.2 Mapping External IDs

If a client-side certificate is used with the TLS profile, then the server looks for a file called "auth/external.tcl" and sources it. This file should define a procedure called id2name that is used to map the "subject" field from a certificate into a username. You can define this procedure however you want, but typically one of two strategies is used.

You can define a mapping array, e.g.,

variable mapping

array set mapping [list "/C=US/.../Email=fred@example.com" fred]

proc id2name {logT id} {
    variable mapping

    if {[info exists mapping($id)]} {
        return $mapping($id)
    }

    beepcore::log::entry $logT info no mapping for $id
    return $id
}

Just be sure to keep it upto date.

Or, you can perform some kind of algorithmic transformation, e.g.,

proc id2name {logT id} {
    if {([set x [string last "/Email=" $id]] < 0)
            || ([set y [string first "@" \
                               [set email [string range $id [expr $x+7] \
                                                  end]]]] <= 0)} {
        beepcore::log::entry $logT info no email in $id
        return $id
    }
    return [string range $email 0 [expr $y-1]]
}

4.3 Authorization Entry

An authorization entry is a serialized array containing these elements:

name:
the username;
authentication:
a serialized array containing:
disabled:
if present, indicates whether the entry is disabled;
mechanism:
the authentication mechanism (e.g., "anonymous" or "otp");
privacy:
the minimum required privacy service necessary for authentication to be attempted (i.e., "none", "weak", or "strong");
algorithm (for otp):
the digest algorithm (e.g., "md5" or "sha1");
seed (for otp):
the seed;
sequence (for otp):
the sequence number; and,
key (for otp):
the last successful response.

authorization:
a serialized array containing information for an exchange profile. The elements are:
acl:
a serialized array of scope/privilege pairs. Each pair contains:
scope:
a naming scope, which beepcore::sasl::allowP uses as a parameter to "string compare" and then "string match" (e.g., "mytable:xyz", "mytable:abc.*", and so on); and,
privs:
a list of allowed actions, containing any or all of the possible values for the "action" parameter of beepcore::sasl::allowP.

proxy:
a list of authenticated usernames that may proxy for this user (cf., beepcore::sasl::proxyP).

Although internally represented as a serialized array, the on-disk representation is typically encoded as XML, e.g.,

<array>
    <elem key="name">fred</elem>

    <elem key="authentication">
        <elem key="key">45298184B655D648</elem>
        <elem key="seed">cmtviewcaus80390</elem>
        <elem key="sequence">9960</elem>
        <elem key="mechanism">otp</elem>
        <elem key="privacy">none</elem>
        <elem key="algorithm">md5</elem>
    </elem>

    <elem key="authorization">
        <elem key="acl">
            <elem key="soap:urn:soapinterop">
                <elem key="scope">soap:urn:soapinterop</elem>
                <elem key="privs">invoke</elem>
            </elem>
        </elem>

        <elem key="proxy">wilma</elem>
    </elem>
</array>

which says that "fred" authenticates via the SASL/OTP profile, has exactly one "acl" entry dealing with something in the "soap:" profile, and, if "wilma" can authenticate as herself, she's allowed to login with fred's privileges.

4.4 Authorization Management

The "etc/authmgmt.tcl" program is used to remotely manage the authorization database.

Once you've bootstrapped this program, you can create new entries, and modify, list, or delete existing entries. In addition, you can modify the "default" and "unknown" authorization entries.

The "etc/otp-init.tcl" script is used to create an OTP-authenticated user with full-service privs:

    % cd $prefix/beepd/
    % ./etc/otp-init.tcl . logs/otp-init.log blockhead
    Enter passphrase for blockead: secret
    Again passphrase for blockead: secret

(Historically, the BEEP "super-user" is known as the "blockhead".)

Once you've boostrapped the blockhead, you can run "etc/authmgmt.tcl" to manage the server:

    % cd $prefix/beepd/
    % ./etc/authmgmt.tcl -passphrase secret
    tuned for privacy using 128-bit session key

    commands are:
       create user ?-algorithm md5|sha1? ?-clone user? ?-template file?
       delete user
      disable user
         help
         list      ?-user      name?
       modify user ?-rekey     yes|no?
         quit
         test user scope action

The commands are:

list:
Lists all known users, or a particular user.
create:
Creates a new user.
modify:
Modifies a user. (If you want to change the user's password, use "-rekey true"; otherwise, you'll only be able to edit the authorization parameters.)
test:
Tests whether the user is allowed to perform a given action, cf., beepcore::sasl::allowP.
disable:
Disables the user's ability to authenticate. (To re-enable the user, use "modify -rekey true' and set a new password.)
delete:
Deletes the user.

The "create" and modify" commands invoke a text editor to let you do the actual editing. They'll fill-in most of the hard stuff (e.g., OTP parameters automatically).

The editor defaults to "vi", unless the "$EDITOR" environment variable is set. A word of warning — at present, typing CTRL-C will abort the editing processing...

Finally, to modify the default entry or the unknown entries, use ".default" and ".unknown", respectively, e.g.,

authmgmt> modify .default


 TOC 

5. Server-Side APIs

5.1 The Profile API

5.1.1 Introduction

The Profile API is used by profiles to communicate with the server. When channels are opened or closed, and when messages arrive over data exchange channels, the API is invoked for the appropriate profile.

The file "scripts/profile-null.tcl" can serve as an example skeleton on which to base more substantial profile implementations. Copying this to a new "profile-*.tcl" file in the "scripts/" directory and editing it can implement a new profile. The server only "explores" profiles once, when "etc/beepd-boot.tcl" is run, so adding a new profile or changing what is returned from "info" or "boot" requires running "etc/beepd-boot.tcl" anew.

Profiles will usually invoke routines in the Utility API. They may also invoke beepcore::sasl::allowP to determine whether a given operation is permitted for the current user. Profiles may also also examine the "::beepcore::server::tuning" variable to determine the tuning properties in effect.

5.1.2 Conventions

    package provide profile 1.0

    namespace eval profile {
        ...

        namespace export info boot init fin exch exch2
    }

5.1.3 Info

    proc profile::info {logT} {}

Returns a list containing information about the profile. There are three elements:

element 0:
an indicator as to whether this profile provides transport security ("0" or "1");
element 1:
a list of supported profile identities (URIs); and,
element 2:
a serialized array containing vectors for the other public methods of this profile.

The parameter is:

logT:
a token returned by a successful call to beepcore::log::init.

5.1.4 Boot

    proc profile::boot {logT} {}

    proc profile::boot2 {logT uri} {}

Verifies that the profile is runtime bootable, an error is returned otherwise.

The parameter is:

logT:
a token returned by a successful call to beepcore::log::init.

The "boot2" interface has an additional parameter, "uri" that indicates the URI of interest. If the "boot2" procedure is defined, it is used instead of the "boot" procedure.

5.1.5 Initialize

    proc profile::init {logT serverD clientA upcallV uri}
                       { return $token }

Initializes an instance of the API, returning a token used in subsequent calls.

The parameters are:

logT:
a token returned by a successful call to beepcore::log::init;
serverD:
the domain name of the server;
clientA:
a serialized array of information about the client;
upcallV:
a procedure to invoke an upcall in the server; and,
uri:
the negotiated URI value.

The serialized array, clientA, contains these elements (any of which may be empty):

address:
the client-side IP address;
domain:
the client-side domain name; and,
port:
the client-side TCP port number.

5.1.6 Finalize

    proc profile::fin {token status} {}

Finalizes an instance of the API, dissolving the token. The "status" parameter indicates whether the finalization is graceful ("+") or extremely prejudicial ("-").

5.1.7 Synchronous Exchange

    proc profile::exch {token data} { return $data }

    proc profile::exch2 {peerT token mimeT} { return $mimeT }

Given a request from the client, return a response using either:

code 0:
a positive response; or,
code 7:
an negative response.

The differences between the two interfaces are:

If the "exch2" procedure is defined, it is used instead of the "exch" procedure.

5.1.8 Upcall the Server

    in profile:

        eval $upcallV [list $data  $rspV]
    or
        eval $upcallV [list $mimeT $rspV]

    in server:

        eval $rspV [list $status $data]
    or
        eval $rspV [list $status $mimeT]

Although interactions between the server and the profile are synchronous, it's possible that the profile may need to originate traffic. An upcall is provided for this purpose.

The parameters are:

data/mimeT:
the data to send; and,
rspV:
a procedure to invoke when a response is received.

When a response is received, "rspV" is invoked with two parameters:

status:
an indication as to what kind of response was received; and,
data/mimeT:
the data received.

The "mimeT" variant is used if an "exch2" interface is defined. The profile is responsible for invoking mime::finalize, as appropriate.

The value of the "status" parameter depends on whether the "mimeT" variant is used:

5.1.9 One-to-Many Exchanges

    in profile:

        eval $upcallV [list $data  unused -mode answer -ansNo $ansNo]
    or
        eval $upcallV [list $mimeT unused -mode answer -ansNo $ansNo]

    ...

    from exch/exch2:

        return -code 9 ""

To perform the server-side of a one-to-many exchange, the profile makes zero or more upcalls. Then, when it's done generating all the answers, the "exch" or "exch2" procedure returns using "code 9".

Note that all of this is done synchronously (which sort of defeats the whole purpose of a one-to-many exchange).

5.1.10 Inter-Channel Communication

    in calling profile:

        set beepT [lindex $upcallV 1]
        ...

        eval [beepcore::server::getmethod $beepT $channelNumber] method args...

    in called profile:

        proc profile::method {token method args} {
            return $result
        }

One channel can "talk" to another if the latter provides a "method" routine in it's info vector.

The parameters to "beepcore::server::getmethod" are:

beepT:
a token, surreptitiously derived when the profile is initialized;
channelNumber:
the channel-number to talk to;
method:
the method to invoke; and,
args:
any arguments to the method.

The parameters passed to the channel are self-explanatory.

5.2 The Authorization API

5.2.1 Introduction

The Authorization API interacts with the SASL profiles to provide information about what authentication and what authorization is permitted for each user. Other profiles can invoke the beepcore::sasl::allowP method to determine whether the action under consideration is authorized for whatever user (if any) has been authenticated.

To use the beepcore::sasl::allowP routine, you need to have two bits of infrastructure set up. First, when a called procedure returns with -code 7, this must be propagated as a -code 7. In other words, catching such a return and throwing it as an error will not allow you to distinguish between returns intended to generate an ERR message and actual coding errors in your profile. Secondly, you must define one or more naming scopes and actions that can be performed in those scopes. For example, a database access profile might have a naming scope of "mytable:xyz" to represent the table "xyz" in your profile, with the actions being "read", "append", "overwrite", and so on. When an action to append to the table called "pdq" is attempted, before permitting the change to be made, invoke beepcore::sasl::allowP, e.g.,

    proc append_to_table {logT tableName recordToAppend} {
# on failure, this does "return -code 7"
        beepcore::sasl::allowP $logT append mytable:$tableName

        .... append to table ....
    }

Of course, any errors thrown while appending to the table (such as deadlocks, alphabetics found in numeric columns, etc.) should also be returned as an ERR message. This is accomplished by returning something like

    return -code 7 [list code 501 diagnostic "letters in integer field"]

The highest level of the profile's "exch" method should catch lower level errors that are thrown with -code 7, call beepcore::util::xml_error2 to convert the serialized array into an <error> element, and then propagate the result with -code 7.

The beepcore::sasl::allowP routine does not need any "token", making it easy to call from anywhere. It also works with default privileges if no SASL profile has been negotiated, making it appropriate to call at any time. So, unless you're writing a SASL profile, beepcore::sasl::allowP is probably the only routine in the Authorization API that you'll use.

5.2.2 Conventions

    package require beepcore::sasl 1.0

All procedures return either:

code 0 (normal return):
return values are specified below;
code 7 (exceptional return):
return value is a serialized array; or,
otherwise (uncaught error):
return value is from the interpreter.

If a serialized array is returned, two elements are present:

code:
a three-digit reply code (cf., [1]'s Section 8); and,
diagnostic:
a textual explanation.

5.2.3 Initialize

    proc beepcore::sasl::init {logT clientA mechanism} { return $token }

Initializes an instance of the API, returning a token used in subsequent calls.

The parameters are:

logT:
a token returned by a successful call to beepcore::log::init;
clientA:
the serialized array passed to the calling profile's initialization routine; and,
mechanism:
the mechanism associated with the calling SASL profile (e.g., "anonymous", "otp", and so on).

5.2.4 Finalize

    proc beepcore::sasl::fin {token} {}

Finalizes an instance of the API, dissolving the token.

5.2.5 Map Name to Authorization Entry

    proc beepcore::sasl::fetch {token name} { return $info }

Given a username (e.g., "fred") returns the corresponding authorization entry (cf., Authorization Entry).

Possible exceptions:

    451 authorization database corrupt

    550 username unknown
    534 username disabled
    535 authentication mechanism mismatch
    538 authentication mechanism requires encryption
    554 invalid username

5.2.6 Store Authorization Entry

    proc beepcore::sasl::store {token name info createP} {}

Given a username store its authorization entry.

The parameters are:

token:
a token returned by a successful call to beepcore::sasl::init;
name:
the username;
info:
its new authorization entry; and,
createP:
if non-zero, then the username must not already exist in the authorization database.

Possible exceptions:

    450 username not locked

    554 invalid username
    554 authorization entry already exists

5.2.7 Lock a Username

    proc beepcore::sasl::lock {token name} {}

Creates a lock for a username, even if the username doesn't exist in the authorization database.

Possible exceptions:

    450 account being updated

    554 invalid username

5.2.8 Release a Username

    proc beepcore::sasl::release {token name} {}

Releases a lock for a username.

Possible exceptions:

    553 username locked
    554 invalid username

5.2.9 Parse a <blob> Element

    proc beepcore::sasl:parse {token data} { return $info }

Parses a <blob> element returning a serialized array, either:

code 0:
on success, "blob" and "status"; or,
code 7:
on failure, "code" and "diagnostic".

Note that this procedure does not parse <error> elements.

5.2.10 Verify Not Tuned Yet

    proc beepcore::sasl::errorP {{errorP 0} {privP 0}} {}

Verify that the session hasn't been tuned for authentication.

The parameters are:

errorP:
if non-zero, instead of returning a serialized array, return a string containing an <error> element; and,
privP:
if non-zero, check for privacy instead of authentication.

Possible exceptions:

    520 already tuned for authentication
    520 already tuned for privacy

5.2.11 Map External ID to Name

    proc beepcore::sasl::id2name {logT id} { return $name }

If the SASL/EXTERNAL profile is used (e.g., if TLS with a client-side certificate is used to tune for privacy), then there needs to be a way of mapping from the certificate's subject to a local name.

The file "auth/external.tcl", if present, is sourced, and is expected to re-define this procedure with whatever logic you want.

5.2.12 Get Default Permissions

    proc beepcore::sasl::unknownA {name} { return $info }

Returns the authorization entry for a user who, although authenticated, isn't in the authorization database.

5.2.13 Check for Proxy

    proc beepcore::sasl::proxyP {token authname username} {}

Check to see if an authenticated user may assert authorization for a given username.

The parameters are:

token:
a token returned by a successful call to beepcore::sasl::init;
authname:
the authenticated username; and,
info:
desired authorization username.

Possible exceptions:

    451 authorization database corrupt

    550 username unknown
    539 proxy not authorized
    554 invalid username

5.2.14 Accept a Login

    proc beepcore::sasl::login {token name options} {}

Tells the server that the indicated username has successfully authenticated. The "options" parameter is an arbitrary serialized array used for auditing purposes.

5.2.15 Refuse a Login

    proc beepcore::sasl::failure {token name options} {}

Notes that an attempt to authentication has failed. The "options" parameter is an arbitrary serialized array used for auditing purposes.

5.2.16 Logout

    proc beepcore::sasl::logout {} {}

Resets the authorization entry used by the server.

5.2.17 Check for Authorization

    proc beepcore::sasl::allowP {logT action scope} {}

Checks to see if an action is allowed.

The parameters are:

logT:
a token returned by a successful call to beepcore::log::init;
action:
the requested action, (i.e., the permissions being sought, such as "read" or "write"); and,
scope:
a naming scope (e.g., a directory name).

Note that there is no "token" parameter for this procedure. Also note that the "action" and "scope" are determined by the "info" parameter of an earlier beepcore::sasl::store call.

Possible exceptions:

    537 action not authorized


 TOC 

6. Client-Side APIs

6.1 The Client API

In releases of beepcore-tcl previous to version 1.5, the client-side API was called the "Mixer" API. Use of the term "mixer" is now historic. Now, the term "Client API" is used to refer to a convenient set of routines for calling the Peer API to create channels, to send and receive messages over those channels, and to conveniently invoke privacy and authentication.

6.1.1 Conventions

    package require beepcore::client 1.1

All procedures return either:

code 0 (normal return):
return values are specified below;
code 7 (exceptional return):
return value is a serialized array; or,
otherwise (uncaught error):
return value is from the interpreter.

If a serialized array is returned, two elements are present:

code:
a three-digit reply code (cf., [1]'s Section 8); and,
diagnostic:
a textual explanation.

6.1.2 Initialize

    proc beepcore::client::init {logT serverD args} { return $token }

Initializes an instance of the API, returning a token used in subsequent calls.

The parameters are:

logT:
a token returned by a successful call to beepcore::log::init.
serverD:
the domain name (or ip address) of the host running the BEEP service.
args:
a serialized array of keyword/value pairs. The keyword/value pairs are:
-port number
indicating the TCP port to connect to;
-service name
indicating the SRV service name to use (cf., Tcl SRVRR);
-debug boolean:
indicating whether debugging should be enabled;
-servername string:
indicating the string to use when starting the service;
-mechanism "none":
indicating that SASL authentication should not occur (the default);
-privacy string:
indicating the minimum required privacy level (i.e., "none", "optional" (the default), "weak", or "strong");
-certfile file:
indicating the file containing the public key certificate to use to authenticate with the server; and,
-keyfile file:
indicating the file containing the corresponding secret key (consulted only if "-certfile" is also present).

If you don't have the Tcl SASL package installed, then these additional options are available:

-mechanism "anonymous":
indicating that the SASL/ANONYMOUS profile should be used for "authentication";
-trace string:
indicating the trace information to use during the SASL/ANONYMOUS exchange (for forwards-compatibility, if this switch is not present, then "-authname" and "-username" are consulted);
-mechanism "otp":
indicating that the SASL/OTP profile should be used for authentication;
-username string:
indicating the authorization name to use during the SASL/OTP exchange;
-authname string
indicating the corresponding authentication name (if not present, then "-username" is consulted);
-passphrase string:
indicating the corresponding passphrase;
-passback upcallV:
indicating an upcall used to respond to an OTP challenge (consulted only if "-passphrase" is absent); and,
-mechanism "external":
indicating that the SASL/EXTERNAL profile should be used for authentication (this requires that "-certfile" be used with "-privacy").

Otherwise, if you do have the Tcl SASL package installed, then the additional options are:

-mechanism string
indicating the SASL mechanism to use, or "any" (to let the library pick the most appropriate one);
-username string
indicating the authorization name to use (regardless of the mechanism used);
-authname string
indicating the corresponding authentication name (if not present, then "-username" is consulted);
-passphrase string:
indicating the corresponding passphrase;
-callbacks list
indicating the client-only callback list given to Tcl SASL; and,
-signed boolean
indicating if message integrity should be used (if privacy is not requested).

For backwards-compatibility, if "-username" is not present, then "-trace" is examined. However, note that "-passback" is not used by the Tcl SASL package.

Finally, if the "-tunnel" option is present, this indicates that the tunnel profile should be used. In that case, any option starting with "-tunnel." is used when connecting to the tunnel (e.g., "-tunnel.mechanism").

Let's look at some examples:

-mechanism anonymous -trace ...
anonymous login and no privacy
-mechanism otp -username ...
use a one-time password to authenticate, but no privacy
-privacy strong
use TLS for privacy, but don't authenticate
-mechanism ... -privacy strong
use TLS for privacy, and then authenticate using the indicated mechanism
-signed true -username ...
authenticate using any SASL mechanism supporting messaging integrity, but no privacy
-privacy optional -username ...
authenticate using any SASL mechanism, and negotiate privacy if available
-mechanism any -username ...
use any SASL mechanism to authenticate, negotiating the strongest privacy possible (which may be none)
-mechanism external -privacy strong -certfile ...
use TLS for privacy, and authenticate using a client-side certificate (if you haven't installed the patch for the Tcl TLS package, and are using the Tcl SASL package, then you may need to supply "-username" as well).
-mechanism plain -username ... -privacy strong
use TLS for privacy, and then authenticate using a user/pass exchange

And finally, here's one with tunnelling:

beepcore::client::init $logT tunnel.example.com \
    -tunnel "<tunnel fqdn='rubble.com' port='10288'><tunnel /></tunnel>" \
    -tunnel.mechanism srp -tunnel.username fred -tunnel.passphrase ... \
    -mechanism plain -username wilma -passphrase ... -privacy strong

which establishes a session with "tunnel.example.com", authenticates the user "fred" using "srp", starts the tunnel profile to establish a tunnel to "rubble.com", then uses TLS for privacy, and finally authenticates to rubble.com as "wilma" using a user/pass exchange.

If "client::init" is successful, use client::tuningA to find out what tuning properties were negotiated.

6.1.3 Finalize

    proc beepcore::client::fin {token} {}

Finalizes an instance of the API, dissolving the token.

6.1.4 Available Profiles

    proc beepcore::client::profiles {token} { return $uriL }

Returns a list of profiles (each identified by a URI) from the server's greeting.

6.1.5 Tuning Properties

    proc beepcore::client::tuningA {token} { return $list }

Returns a serialized array of tuning properties.

6.1.6 Create a Channel

    proc beepcore::client::create {token uri {data ""}} { return $channelT }

Attempts to create a channel for the profile, returning a token used in subsequent calls.

The parameters are:

token:
a token returned by a successful call to beepcore::client::init;
uri:
a URI identifying the profile to bind to the channel; and,
data:
initialization data for the channel.

If the "uri" parameter is a list with more than one element, then the "data" parameter must be present, and must be a list with the same number of elements.

6.1.7 Close a Channel

    proc beepcore::client::destroy {token channelT} {}

Closes a channel previously started with beepcore::client::create.

The parameters are:

token:
a token returned by a successful call to beepcore::client::init; and,
channelT:
a token returned by a successful call to beepcore::client::create.

6.1.8 Exchange

    proc beepcore::client::exch {token channel mimeT} { return $mimeT }

Sends a request, returns a response.

The parameters are:

token:
a token returned by a successful call to beepcore::client::init;
channel:
a channel-number returned by a successful call to beepcore::client::create; and,
mimeT:
a MIME part to be sent as the request.

Note that a MIME part is returned for both positive (return code 0) and negative (return code 7) responses.

6.1.9 Parse an <error> Element

    proc beepcore::client::errscan {token mimeT} {
        return [list code ... diagnostic ...]
    }

Parses an <error> element, returning a serialized array.

You've probably guessed, but this is just a front-end to peer::errscan.

6.1.10 Get the Peer token

    proc beepcore::client::peerT {token} { return $peerT }

Sometimes you need to use the Peer API directly.



 TOC 

7. Peer-to-Peer APIs

7.1 The Peer API

7.1.1 Conventions

    package require beepcore::peer 2.0

The Peer API provides low-level access to a BEEP session, allowing sessions and channels to be started and stopped, and allowing both messages and segments to be sent and received asynchronously over any Tcl-channel.

7.1.1.1 Data Structures

stringL:
A list of strings
peerT:
A peer token, representing a BEEP session.
channelT:
A channel token, representing a BEEP channel.
reply array:
A serialized array with three elements:
code:
three digits
diagnostic:
a string
language:
a string

7.1.1.2 Callbacks

A callback is a script that is eval'd when an event occurs. An odd number of arguments are appended to the script prior to evaluation. The first argument is a peer token, a channel token, or a channelNumber. The arguments that follow are keywords and values, forming a serialized array.

7.1.1.2.1 Start a Channel

"startV" is eval'd when the remote peer asks to start a channel, and should eventually cause either beepcore::peer::accept or beepcore::peer::decline to be invoked. The first parameter is the "channelNumber" for the proposed channel. The remaining parameters are:

profiles:
a list of URIs.
data:
if present, a list of strings, each containing initialization data for the corresponding URI.
serverName:
if present, the "serverName" attribute supplied by the remote peer.

"crtV" is eval'd when the remote peer responds on whether it will allow the creation of a channel. The first parameter is a peer token. The remaining parameters are:

status:
either "positive" or "negative", indicating the remote peer's response.
channelT:
the new channel token (if positive).
profile:
the URI selected (if positive).
datum:
the associated initialization data (if positive).
code:
the 3-digit error code (if negative).
diagnostic:
the accompanying textual string (if negative).
language:
the associated localization language (if negative).

7.1.1.2.2 Process a Terminal Event

"eventV" is eval'd when an event occurs that indicates that a terminal release should eventually be invoked (e.g., due to a non-recoverable error or a graceful termination). The first parameter is a peer token. The remaining parameters are:

source:
either "internal" or "external".
code:
the 3-digit error code.
diagnostic:
the accompanying textual string.
language:
the associated localization language.

7.1.1.2.3 Release a Channel

"rlsV" is eval'd when either peer asks to close the channel, or possibly the session. The first parameter is a channel token. The remaining parameters are:

source:
either "internal" or "external"; and,
mode:
one of:
query:
If "rlsV" returns code 0, then session release may occur, a subsequent call to "rlsV" will be made with a mode of either "commit" or "rollback". Otherwise, if "rslV" returns code 7 with a reply array, the session won't be released.
commit:
The session is being released.
rollback:
The session is not being released.
abort:
The session is being unilaterally released.

Note that the return value of this callback is consulted only if the "mode" parameter is "query" and if it returns with code 7.

"finalV" is eval'd when the remote peer responds on whether it will allow the channel (or session) to be released. The first parameter is a peer token. The remaining parameters are:

status:
either "positive" or "negative", indicating the remote peer's response.
code:
the 3-digit error code (if negative)
diagnostic:
the accompanying textual string (if negative)
language:
the associated localization language (if negative)

If the "status" parameter is positive, then a terminal release should eventually be invoked.

7.1.1.2.4 Receive a Message

"msgV" is eval'd when the remote peer sends a message, and should eventually cause beepcore::peer::reply to be invoked. The first parameter is a channel token. The remaining parameters are:

msgNo:
an integer selected by the remote peer.
mimeT:
the MIME object sent by the remote peer.

Note that "msgV" is ultimately responsible for finalizing "mimeT".

"rpyV" is eval'd when the remote peer responds to an earlier message. The first parameter is a channel token. The remaining parameters are:

msgNo:
an integer used with the earlier message
ansNo:
if present, an integer selected by the remote peer
status:
one of "positive", "negative", "answer", or "nul")
mimeT:
the MIME object sent by the remote peer.

Note that if the "status" parameter is "nul", then "mimeT", if present, should be ignored; otherwise, "rpyV" is ultimately responsible for finalizing "mimeT".

7.1.1.2.5 Receive a Segment

"segV" is eval'd when the remote peer sends a segment. The first parameter is a channel token. The remaining parameters are:

msgNo:
an integer selected by the remote peer
ansNo:
if present, an integer selected by the remote peer
payload:
a string
continuation:
either "complete" or "intermediate".

7.1.2 Peer Bindings

7.1.2.1 Start a Session

    proc beepcore::peer::join {logT socketT args} { return $token }

Creates a peer binding to any bi-directional Tcl-channel.

The parameters are:

logT:
a token returned by a successful call to beepcore::log::init.
socketT:
a bi-directional Tcl-channel.
args:
Keywords and values:
-localize:
a list of localization languages to advertise in the greeting.
-profiles:
a list of URIs to advertise in the greeting.
-serverName:
the "serverName" attribute to use when starting a channel.
-initiator:
either "true" or "false".
-startCallback:
if present, specifies the "startV" callback for this session; if not present, remote requests to start a channel are automatically rejected.
-eventCallback:
if present, specifies the "eventV" callback for this session.

7.1.2.2 Release a Session

    proc beepcore::peer::done {peerT args} {
        return $msgNo          # non-blocking

        return                 # on success  
        return -code 7 $replyA # on failure
    }

Destroys a peer binding (but does not close the associated Tcl-channel).

The parameters are:

peerT:
a token returned by a successful call to beepcore::peer::join.
args:
Keywords and values:
-release:
one of
orderly:
to ask each local channel (via the "rlsV" callback) and then the remote peer for permission; or,
abortive:
to unilaterally tell all local channels and the remote peer that the session is being released, without waiting for a response; or,
terminal:
to unilaterally tell all local channels that the session is being released.

-code:
a 3-digit reply code, typically "200".
-diagnostic:
if present, the accompanying textual string.
-language:
if present, the associated localization language.
-finalCallback:
if present, specifies a "finalV" callback, and this call is non-blocking.

If the "-finalCallback" option is given, then it immediately returns an integer "msgNo", and sometime later the associated "finalV" callback is eval'd; otherwise, the call blocks and ultimately makes a normal return (the session is released and the peer token is dissolved); or a code 7 return of a reply array.

You may want to invoke beepcore::peer::wait before attempting to release the session.

7.1.3 Channel Bindings

7.1.3.1 Start a Channel

    proc beepcore::peer::start {peerT profiles args} {
        return $msgNo          # non-blocking

        return $token          # on success  
        return -code 7 $replyA # on failure
    }

Asks to start a channel.

The parameters are:

peerT:
a token returned by a successful call to beepcore::peer::join.
profiles:
a list of URIs.
args:
Keywords and values:
-data:
if present, a list of strings, each containing initialization data for the corresponding URI. (This must have the same number of elements as the "profiles" parameter.)
-serverName:
the "serverName" attribute to use when starting this channel.
-createCallback:
if present, specifies a "crtV" callback, and this call is non-blocking.
-messageCallback:
if present, specifies the "msgV" callback for this channel.
-segmentCallback:
if present, specifies the "segV" callback for this channel.
-releaseCallback:
if present, specifies the "rlsV" callback for this channel.

If the "-createCallback" option is given, then it immediately returns an integer "msgNo", and sometime later the associated "crtV" callback is eval'd; otherwise, the call blocks and either makes a normal return of a channel token or a code 7 return of a reply array. If a channel is started, then beepcore::peer::getprop may be used to determine the profile and datum returned by the remote peer.

At most one of the "-messageCallback" and "-segmentCallback" options may be present. If neither is present and the channel is successfully started, then incoming messages for the channel are automatically rejected, and beepcore::peer::sendseg is unavailable.

7.1.3.2 Agree to Start a Channel

    proc beepcore::peer::accept {peerT channelNumber profile args} {
        return $token
    }

Allows a channel to be started.

The parameters are:

peerT:
a token returned by a successful call to beepcore::peer::join.
channelNumber:
the "channelNumber" parameter given earlier to the session's "startV" callback.
profile:
a URI from the list contained in the "profiles" parameter given earlier to "startV" callback.
args:
Keywords and values:
-datum:
if present, specifies the initialization data for the channel.
-messageCallback:
if present, specifies the "msgV" callback for this channel.
-segmentCallback:
if present, specifies the "segV" callback for this channel.
-releaseCallback:
if present, specifies the "rlsV" callback for this channel.

At most one of the "-messageCallback" and "-segmentCallback" options may be present. If neither is present and the channel is successfully started, then incoming messages for the channel are automatically rejected, and beepcore::peer::sendseg is unavailable.

7.1.3.3 Disagree to Start a Channel

    proc beepcore::peer::decline {peerT channelNumber code 
                                  {diagnostic ""} {language ""}} {
    }

Refuse to start a channel.

The parameters are:

peerT:
a token returned by a successful call to beepcore::peer::join.
channelNumber:
the "channelNumber" parameter given earlier to the "startV" callback.
code:
a 3-digit reply code
diagnostic:
if present, the accompanying textual string.
language:
if present, the associated localization language.

7.1.3.4 Close a Channel

    proc beepcore::peer::stop {channelT args} {
        return $msgNo          # non-blocking

        return $token          # on success  
        return -code 7 $replyA # on failure
    }

Closes a channel.

The parameters are:

channelT:
a token returned by a successful call to beepcore::peer::start or beepcore::peer::accept, or passed as a parameter to the "crtV" callback.
args:
Keywords and values:
-code:
a 3-digit reply code, typically "200".
-diagnostic:
if present, the accompanying textual string.
-language:
if present, the associated localization language.
-finalCallback:
if present, specifies a "finalV" callback, and this call is non-blocking.

If the "-finalCallback" option is given, then it immediately returns an integer "msgNo", and sometime later the associated "finalV" callback is eval'd; otherwise, the call blocks and ultimately makes a normal return (the channel is closed and the channel token is dissolved); or a code 7 return of a reply array.

You may want to invoke beepcore::peer::wait before attempting to stop the channel.

7.1.4 Property Management

The peer-specific properties are:

-names:
list of all properties
channels:
list of channelT's associated with the peerT
NNN:
the channelT corresponding to this channelNumber
features:
list of channel management features supported by remote peer
localize:
list of desirable localization languages for remote peer
profiles:
list of URIs advertised by remote peer
rcv.stamp:
the "clock seconds" value of the last receive activity
event:
a reply array
startCallback:
eval'd when a start message is received on channel zero (may be set)
eventCallback:
eval'd when a fatal error is detected (may be set)

The channel-specific properties are:

-names:
list of all properties
peer:
the channelT's peerT
profile:
URI of associated profile
datum:
string (not MIME) returned during channel initialization
messages:
list of outstanding message numbers
snd.wnd:
BEEP's current send window
rcv.wnd:
BEEP's current receive window
rcv.buf:
the relative space to allocate for receiving (may be set)
rcv.stamp:
the "clock seconds" value of the last receive activity
messageCallback:
eval'd when a message is received on this channel (may be set)
segmentCallback:
eval'd when a segment is received on this channel (may be set)
releaseCallback:
eval'd when either peer wants to release the session (may be set)

7.1.4.1 Get a Property

    proc beepcore::peer::getprop {token} { return $vArray }

    proc beepcore::peer::getprop {token property} { return $value }

Gets a property (or all properties) for a peerT or a channelT.

The parameters are:

token:
either a peer token or a channel token.
property:
if present, the property to retrieve.

Note that some properties, i.e., features, localize, and profiles, do not become available until a handshake occurs with the remote peer. beepcore::peer::wait may be invoked accordingly, e.g.,

   
    set peerT [beepcore::peer::join ...]
    while {[lsearch -exact [beepcore::peer::getprop $peerT -names] \
                localize] < 0} {
        beepcore::peer::wait $peerT -timeout ...
    }

7.1.4.2 Set a Property

    proc beepcore::peer::setprop {token property value} { return $oldvalue }

Sets a property for a peerT or channelT, returning the old value.

The parameters are:

token:
either a peer token or a channel token.
property:
the property to set.
value:
the new value.

7.1.5 The Message-Oriented Interface

7.1.5.1 Send a Message

    proc beepcore::peer::message {channelT mimeT args} {
        return $msgNo          # non-blocking

        return $mimeT          # on success  
        return -code 7 $mimeT  # on failure
    }

Sends a message to the remote peer.

The parameters are:

channelT:
a channel token.
mimeT:
the MIME object to send.
args:
Keywords and values:
-replyCallback:
if present, specifies the "rpyV" callback for this message.

If the "-replyCallback" option is given, then it immediately returns an integer "msgNo", and sometime later the associated "rpyV" callback is eval'd; otherwise, the callbacks and returns a MIME object, with either a normal return (for a positive status) or a code 7 return (for a negative status). If the "-replyCallback" option is not given, and the remote peer attempts a one-to-many reply, an error is thrown.

7.1.5.2 Reply to a Message

    proc beepcore::peer::reply {channelT msgNo mimeT args} {
    }

Replies to a message (invoked after a "msgV" callback is eval'd)

The parameters are:

channelT:
a channel token.
msgNo:
the "msgNo" parameter given earlier to the "msgV" callback.
mimeT:
the MIME object to send.
args:
Keywords and values:
-status:
one of "positive", "negative", "answer", or "nul".
-ansNo:
If the "-status" option is "answer", then this integer is the associated answer number.

7.1.6 The Segment-Oriented Interface

7.1.6.1 Send a Segment

    proc beepcore::peer::sendseg {channelT msgNo payload args} {
    }

Sends a segment to the remote peer.

The parameters are:

channelT:
a channel token.
msgNo:
If the "-status" option is "message", then you choose the integer; otherwise, the "msgNo" parameter given earlier to the "segV" callback.
payload:
the string to send.
args:
Keywords and values:
-type:
one of "message", "positive", "negative", "answer", or "nul".
-continuation:
either "complete" or "intermediate".
-ansNo:
If the "-status" option is "answer", then this integer is the associated answer number.

7.1.6.2 Waiting

7.1.6.2.1 Wait for Something to Happen

    proc beepcore::peer::wait {token args} {
        return $msgsWaiting    # on success 
        return -code 7 $replyA # on failure
    }

Waits until all (specified) messages are responded to.

The parameters are:

token:
either a peer token or a channel token.
args:
Keywords and values:
-msgNos:
either a list of "msgNo" values to wait for; or, to wait for new messages, the keyword "new".
-timeout:
either "-1" to wait forever, "0" to wait for the event queue to drain, or specify the desired number of milliseconds to wait.

7.1.6.3 Message Formatting

7.1.6.3.1 XML string to MIME token

beepcore::peer::str2xml string
    -> mimeT

Takes a string and returns a "application/beep+xml" MIME token.

7.1.6.3.2 Create an <error> Element

    proc beepcore::peer::errfmt {peerT code {diagnostic ""} {language ""}} {
        return $mimeT
    }

    proc beepcore::peer::errfmt2 {peerT code {diagnostic ""} {language ""}} {
        return $string
    }

    proc beepcore::peer::errfmt3 {peerT replyA} { return $mimeT }

    proc beepcore::peer::errfmt4 {peerT replyA} { return $string }

All four return a filled-in <error> element.

The default for language is the first element from the "-localize" option given to beepcore::peer::join.

7.1.6.3.3 Parse an <error> element

    proc beepcore::peer::errscan {peerT mimeT args} {
        return [list code ... diagnostic ...]
    }

    proc {beepcore::peer::errscan2 {peerT string} {
        return [list code ... diagnostic ...]
    }

Both look at something containing an <error> element and return a reply array.

The first procedure takes a "-finalize" option, having value "true" (the default) or "false", indicating whether the "mimeT" parameter should be finalized upon completion.

7.2 Tuning Properties

The tuning properties for a session are presented in a serialized array:

privacy:
The privacy in effect, one of: "none", "weak", or "strong".
sbits:
The number of bits used for the session key. (If "0", the number may be unknown — consult the "privacy" element to find out.)
authname:
The external authentication name (as mapped by beepcore::sasl::id2name).
realname:
The actual (unmapped) external authentication name.
tls:
A serialized array of properties from the TLS negotiation:
remote:
Fields from the remote peer's certificate: subject, issuer, notBefore, notAfter, and serial.
local:
Fields from the locally-used certificate (may not be present).
cipher:
The cipher in use.

sasl:
A serialized array of properties from the SASL negotation:
mechanism:
The mechanism in use.



 TOC 

8. Miscellaneous APIs

8.1 Logging API

8.1.1 Conventions

    package require beepcore::log 1.0

Return values for each procedure are specified below.

8.1.2 Initialize

    proc beepcore::log::init {file ident {recipient ""} {originator ""}} {
        return $token
    }

Initializes an instance of the API, returning a token used in subsequent calls.

The parameters are:

file:
the name of the log file;
ident:
the caller's logging identity (e.g., "space");
recipient:
if present, the address to send critical messages to; and,
originator:
if present, the address to send critical messages from.

8.1.3 Finalize

    proc beepcore::log::fin {token} {}

Finalizes an instance of the API, dissolving the token.

8.1.4 Append a Log Entry

    proc beepcore::log::entry {token level args} {}

Appends an entry to the log file.

The parameters are:

token:
a token returned by a successful call to beepcore::log::init.
level:
a textual string that defines the form of the "args" parameter; one of:
debugN
$function args... (where N > 0, and defaults to 1)
error
$function $result
notify
$function $result
fatal
$errorInfo $result
info
begin/end args...
stats
name value...
system
$result
user
$result

args:
the textual portion of the log entry.

8.1.5 Annotate

    proc beepcore::log::init {token data} {}

Annotate the next log entry with additional text.

The parameters are:

token:
a token returned by a successful call to beepcore::log::init.
data:
the textual annotation for the next log entry.

When a log entry with level "notify" is made, email is sent to the administrator. This email provides context by including some of the previously made log entries. In addition, the contents of an annotation buffer (set by this call) is included.

8.2 Utility API

8.2.1 Conventions

    package require beepcore::util 1.0

8.2.2 Create an XML attribute value

    proc beepcore::util::xml_av {text {allP 1}} { return $text }

Takes a string and quotes it according to XML's rules for attribute values. If "allP" is zero, then "&" and "<" aren't quoted.

8.2.3 Create an XML string value

    proc beepcore::util::xml_cdata {text} { return $text }

Takes a string and quotes it according to XML's rules for string values.

8.2.4 Expand CDATA Blocks

    proc beepcore::util::xml_norm {text} { return $text }

Takes XML input and expands any CDATA blocks contained therein.

8.2.5 Transform an XML string

    proc beepcore::util::xml_pcdata {text {flattenP 1}} { return $text }

The inverse of beepcore::util::xml_cdata. If "flattenP" is non-zero, then leading and trailing whitespace is compressed.

8.2.6 Generate a Parser Trace

    proc beepcore::util::xml_trace {logT prefix info data stack} { return $text }

Logs an XML parsing error and returns a multiline text string containing the corresponding stack trace. The parameters are:

logT:
a token returned by a successful call to beepcore::log::init;
prefix:
a short string identifying the profile encountering the error;
info:
an informative string to be logged;
data:
the XML being parsed; and,
stack:
a list containing the parse tree.

8.2.7 Create an <error> Element

    proc beepcore::util::xml_error {code {diagnostic ""} {language ""}} {
        return $string
    }

    proc beepcore::peer::xml_error2 {replyA} { return $string }

Just like beepcore::peer::errfmt2 and beepcore::peer::errfmt4, but these don't require a peer token.

8.2.8 Create a <blob> Element

    proc beepcore::util::xml_blob {text {status continue}} { return $string }

Creates a <blob> element (doing the base64 encoding).



 TOC 

References

[1] Rose, M., "The Blocks Extensible Exchange Protocol Core", RFC 3080, March 2001 (TXT, HTML, XML).
[2] Rose, M., "Mapping the BEEP Core onto TCP", RFC 3081, March 2001 (TXT, HTML, XML).
[3] Gulbrandsen, A., Vixie, P. and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000.


 TOC 

Authors' Addresses

  Marshall T. Rose
  Dover Beach Consulting, Inc.
  POB 255268
  Sacramento, CA 95865-5268
  US
Phone:  +1 916 483 8878
EMail:  mrose@dbc.mtview.ca.us
  
  Darren New
  5390 Caminito Exquisito
  San Diego, CA 92130
  US
Phone:  +1 858 350 9733
EMail:  dnew@san.rr.com


 TOC 

Appendix A. Tcl SASL

Tcl SASL provides a Tcl interface to the Cyrus SASLv2 library.

At present, this package includes Tcl SASL — look in the "OTHERPKGS/" directory for a file called tclsasl-1.0.tgz. Get a copy of Cyrus SASL v2.1.0, and configure, compile, and install it. If there are any errors or problems, you should fix those before proceeding. Then configure, compile and install Tcl SASL.

Finally, after you've installed Tcl SASL, re-run "etc/beepd-boot.tcl" to update the server's configuration files.

A.1 Tcl TLS and Tcl SASL

If you are running Tcl TLS version 1.4.1 or earlier, you can make Tcl SASL's job a little easier by applying the "tls-1.4.1.patch" file in the "OTHERPKGS/" directory.

What this patch does is modify the "tls::status" command to report both local certificate information along with the number of bits used in the session key. This is useful information because the Cyrus SASL package can be configured to behave differently based on this information.



 TOC 

Appendix B. Tcl SRVRR

Tcl SRVRR provides a Tcl interface to the DNS' SRV RRs[3].

At present, this package includes Tcl SRVRR — look in the "OTHERPKGS/" directory for a file called tclsrvrr-1.0.tgz. If you install it, then beepcore::client::init will allow a "-service string" option to specify the name of the service to look for (e.g., "soap-beep"). If it's not installed, then this option will be silently ignored.

Note that beepcore::client::init always requires that "-port number" be present (because the SRV algorithm requires a fallback if no SRV RRs are found).



 TOC 

Appendix C. Copyright and License

Blocks Public License
Copyright (c) 2000, Invisible Worlds, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 INVISIBLE WORLDS 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.



 TOC 

Index

B 
 beepcore::client::
   create
   destroy
   errscan
   exch
   fin
   init
   peerT
   profiles
   tuningA
 beepcore::log::
   annotate
   entry
   fin
   init
 beepcore::peer::
   accept
   decline
   done
   errfmt
   errfmt2
   errfmt3
   errfmt4
   errscan
   errscan2
   getprop
   join
   message
   reply
   sendseg
   setprop
   start
   stop
   str2xml
   wait
 beepcore::sasl::
   allowP
   failure
   fetch
   fin
   id2name 1, 2
   init
   lock
   login
   logout
   parse
   proxyP
   release
   store
   tuneP
   unknownA
 beepcore::server::
   getmethod
   tuning
 beepcore::util::
   xml_av
   xml_blob
   xml_cdata
   xml_error
   xml_norm
   xml_pcdata
   xml_trace
C 
 callbacks
   channel started
   process a terminal event
   receive a message
   receive a reply
   receive a segment
   release a session/channel
   session/channel released
   start a channel
P 
 profile::
   boot
   boot2
   exch
   exch2
   fin
   info
   init
   method