diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 2000-06-04 14:58:41 +0000 |
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 2000-06-04 14:58:41 +0000 |
| commit | bcbdc6452f8f590f48a594aac9415b5d9b16e0f3 (patch) | |
| tree | 27e846057f9a7b80ea09f2cb0413747889627902 | |
| parent | 5fb2f505a69f04dcbff92cae5ba872ac685fa216 (diff) | |
Notes
28 files changed, 6802 insertions, 0 deletions
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c new file mode 100644 index 000000000000..5e64cf05256b --- /dev/null +++ b/crypto/openssh/auth.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * $FreeBSD$ + */ + +#include "includes.h" +RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $"); + +#include "xmalloc.h" +#include "rsa.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "compat.h" +#include "channels.h" +#include "match.h" + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" +#include "session.h" +#include "dispatch.h" + + +/* import */ +extern ServerOptions options; +extern char *forced_command; + +/* + * Check if the user is allowed to log in via ssh. If user is listed in + * DenyUsers or user's primary group is listed in DenyGroups, false will + * be returned. If AllowUsers isn't empty and user isn't listed there, or + * if AllowGroups isn't empty and user isn't listed there, false will be + * returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. + */ +int +allowed_user(struct passwd * pw) +{ + struct stat st; + struct group *grp; + char *shell; + int i; + + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw) + return 0; + + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; + + /* deny if shell does not exists or is not executable */ + if (stat(shell, &st) != 0) + return 0; + if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) + return 0; + + /* Return false if user is listed in DenyUsers */ + if (options.num_deny_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_deny_users; i++) + if (match_pattern(pw->pw_name, options.deny_users[i])) + return 0; + } + /* Return false if AllowUsers isn't empty and user isn't listed there */ + if (options.num_allow_users > 0) { + if (!pw->pw_name) + return 0; + for (i = 0; i < options.num_allow_users; i++) + if (match_pattern(pw->pw_name, options.allow_users[i])) + break; + /* i < options.num_allow_users iff we break for loop */ + if (i >= options.num_allow_users) + return 0; + } + /* Get the primary group name if we need it. Return false if it fails */ + if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { + grp = getgrgid(pw->pw_gid); + if (!grp) + return 0; + + /* Return false if user's group is listed in DenyGroups */ + if (options.num_deny_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_deny_groups; i++) + if (match_pattern(grp->gr_name, options.deny_groups[i])) + return 0; + } + /* + * Return false if AllowGroups isn't empty and user's group + * isn't listed there + */ + if (options.num_allow_groups > 0) { + if (!grp->gr_name) + return 0; + for (i = 0; i < options.num_allow_groups; i++) + if (match_pattern(grp->gr_name, options.allow_groups[i])) + break; + /* i < options.num_allow_groups iff we break for + loop */ + if (i >= options.num_allow_groups) + return 0; + } + } +#ifndef __FreeBSD__ /* FreeBSD handle it later */ + /* Fail if the account's expiration time has passed. */ + if (pw->pw_expire != 0) { + struct timeval tv; + + (void)gettimeofday(&tv, NULL); + if (tv.tv_sec >= pw->pw_expire) + return 0; + } +#endif /* !__FreeBSD__ */ + /* We found no reason not to let this user try to log on... */ + return 1; +} diff --git a/crypto/openssh/aux.c b/crypto/openssh/aux.c new file mode 100644 index 000000000000..899142da7167 --- /dev/null +++ b/crypto/openssh/aux.c @@ -0,0 +1,36 @@ +#include "includes.h" +RCSID("$OpenBSD: aux.c,v 1.2 2000/05/17 09:47:59 markus Exp $"); + +#include "ssh.h" + +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if(*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +void +set_nonblock(int fd) +{ + int val; + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return; + } + if (val & O_NONBLOCK) + return; + debug("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) + error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno)); +} diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c new file mode 100644 index 000000000000..a6c8174a4251 --- /dev/null +++ b/crypto/openssh/kex.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +#include "includes.h" +RCSID("$Id: kex.c,v 1.7 2000/05/25 20:45:20 markus Exp $"); + +#include "ssh.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "packet.h" +#include "cipher.h" +#include "compat.h" + +#include <openssl/bn.h> +#include <openssl/dh.h> + +#include <openssl/crypto.h> +#include <openssl/bio.h> +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/pem.h> + +#include "kex.h" + +#define KEX_COOKIE_LEN 16 + +Buffer * +kex_init(char *myproposal[PROPOSAL_MAX]) +{ + int first_kex_packet_follows = 0; + unsigned char cookie[KEX_COOKIE_LEN]; + u_int32_t rand = 0; + int i; + Buffer *ki = xmalloc(sizeof(*ki)); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rand = arc4random(); + cookie[i] = rand & 0xff; + rand >>= 8; + } + buffer_init(ki); + buffer_append(ki, (char *)cookie, sizeof cookie); + for (i = 0; i < PROPOSAL_MAX; i++) + buffer_put_cstring(ki, myproposal[i]); + buffer_put_char(ki, first_kex_packet_follows); + buffer_put_int(ki, 0); /* uint32 reserved */ + return ki; +} + +/* send kexinit, parse and save reply */ +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]) +{ + int i; + char *ptr; + int plen; + + debug("send KEXINIT"); + packet_start(SSH2_MSG_KEXINIT); + packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit)); + packet_send(); + packet_write_wait(); + debug("done"); + + /* + * read and save raw KEXINIT payload in buffer. this is used during + * computation of the session_id and the session keys. + */ + debug("wait KEXINIT"); + packet_read_expect(&plen, SSH2_MSG_KEXINIT); + ptr = packet_get_raw(&plen); + buffer_append(peer_kexint, ptr, plen); + + /* parse packet and save algorithm proposal */ + /* skip cookie */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + packet_get_char(); + /* extract kex init proposal strings */ + for (i = 0; i < PROPOSAL_MAX; i++) { + peer_proposal[i] = packet_get_string(NULL); + debug("got kexinit: %s", peer_proposal[i]); + } + /* first kex follow / reserved */ + i = packet_get_char(); + debug("first kex follow: %d ", i); + i = packet_get_int(); + debug("reserved: %d ", i); + packet_done(); + debug("done"); +} + +/* diffie-hellman-group1-sha1 */ + +int +dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +{ + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + + /* we only accept g==2 */ + if (!BN_is_word(dh->g, 2)) { + log("invalid DH base != 2"); + return 0; + } + if (dh_pub->neg) { + log("invalid public DH value: negativ"); + return 0; + } + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; + debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); + + /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ + if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) + return 1; + log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + return 0; +} + +DH * +dh_new_group1() +{ + static char *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + DH *dh; + int ret, tries = 0; + dh = DH_new(); + if(dh == NULL) + fatal("DH_new"); + ret = BN_hex2bn(&dh->p, group1); + if(ret<0) + fatal("BN_hex2bn"); + dh->g = BN_new(); + if(dh->g == NULL) + fatal("DH_new g"); + BN_set_word(dh->g, 2); + do { + if (DH_generate_key(dh) == 0) + fatal("DH_generate_key"); + if (tries++ > 10) + fatal("dh_new_group1: too many bad keys: giving up"); + } while (!dh_pub_is_valid(dh, dh->pub_key)); + return dh; +} + +void +dump_digest(unsigned char *digest, int len) +{ + int i; + for (i = 0; i< len; i++){ + fprintf(stderr, "%02x", digest[i]); + if(i%2!=0) + fprintf(stderr, " "); + } + fprintf(stderr, "\n"); +} + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret) +{ + Buffer b; + static unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_string(&b, client_version_string, strlen(client_version_string)); + buffer_put_string(&b, server_version_string, strlen(server_version_string)); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest(digest, evp_md->md_size); +#endif + return digest; +} + +unsigned char * +derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret) +{ + Buffer b; + EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + char c = id; + int have; + int mdsz = evp_md->md_size; + unsigned char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz); + + buffer_init(&b); + buffer_put_bignum2(&b, shared_secret); + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ + EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ + EVP_DigestUpdate(&md, &c, 1); /* key id */ + EVP_DigestUpdate(&md, hash, mdsz); /* session id */ + EVP_DigestFinal(&md, digest, NULL); + + /* expand */ + for (have = mdsz; need > have; have += mdsz) { + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, digest, have); + EVP_DigestFinal(&md, digest + have, NULL); + } + buffer_free(&b); +#ifdef DEBUG_KEX + fprintf(stderr, "Digest '%c'== ", c); + dump_digest(digest, need); +#endif + return digest; +} + +#define NKEYS 6 + +#define MAX_PROP 20 +#define SEP "," + +char * +get_match(char *client, char *server) +{ + char *sproposals[MAX_PROP]; + char *c, *s, *p, *ret; + int i, j, nproposals; + + c = xstrdup(client); + s = xstrdup(server); + + for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { + if (i < MAX_PROP) + sproposals[i] = p; + else + break; + } + nproposals = i; + + for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { + for (j = 0; j < nproposals; j++) { + if (strcmp(p, sproposals[j]) == 0) { + ret = xstrdup(p); + xfree(c); + xfree(s); + return ret; + } + } + } + xfree(c); + xfree(s); + return NULL; +} +void +choose_enc(Enc *enc, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching cipher found: client %s server %s", client, server); + enc->type = cipher_number(name); + + switch (enc->type) { + case SSH_CIPHER_3DES_CBC: + enc->key_len = 24; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_BLOWFISH_CBC: + case SSH_CIPHER_CAST128_CBC: + enc->key_len = 16; + enc->iv_len = 8; + enc->block_size = 8; + break; + case SSH_CIPHER_ARCFOUR: + enc->key_len = 16; + enc->iv_len = 0; + enc->block_size = 8; + break; + default: + fatal("unsupported cipher %s", name); + } + enc->name = name; + enc->enabled = 0; + enc->iv = NULL; + enc->key = NULL; +} +void +choose_mac(Mac *mac, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching mac found: client %s server %s", client, server); + if (strcmp(name, "hmac-md5") == 0) { + mac->md = EVP_md5(); + } else if (strcmp(name, "hmac-sha1") == 0) { + mac->md = EVP_sha1(); + } else if (strcmp(name, "hmac-ripemd160@openssh.com") == 0) { + mac->md = EVP_ripemd160(); + } else { + fatal("unsupported mac %s", name); + } + mac->name = name; + mac->mac_len = mac->md->md_size; + mac->key_len = (datafellows & SSH_BUG_HMAC) ? 16 : mac->mac_len; + mac->key = NULL; + mac->enabled = 0; +} +void +choose_comp(Comp *comp, char *client, char *server) +{ + char *name = get_match(client, server); + if (name == NULL) + fatal("no matching comp found: client %s server %s", client, server); + if (strcmp(name, "zlib") == 0) { + comp->type = 1; + } else if (strcmp(name, "none") == 0) { + comp->type = 0; + } else { + fatal("unsupported comp %s", name); + } + comp->name = name; +} +void +choose_kex(Kex *k, char *client, char *server) +{ + k->name = get_match(client, server); + if (k->name == NULL) + fatal("no kex alg"); + if (strcmp(k->name, KEX_DH1) != 0) + fatal("bad kex alg %s", k->name); +} +void +choose_hostkeyalg(Kex *k, char *client, char *server) +{ + k->hostkeyalg = get_match(client, server); + if (k->hostkeyalg == NULL) + fatal("no hostkey alg"); + if (strcmp(k->hostkeyalg, KEX_DSS) != 0) + fatal("bad hostkey alg %s", k->hostkeyalg); +} + +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) +{ + int mode; + int ctos; /* direction: if true client-to-server */ + int need; + Kex *k; + + k = xmalloc(sizeof(*k)); + memset(k, 0, sizeof(*k)); + k->server = server; + + for (mode = 0; mode < MODE_MAX; mode++) { + int nenc, nmac, ncomp; + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; + nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; + ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; + choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); + choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); + choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); + debug("kex: %s %s %s %s", + ctos ? "client->server" : "server->client", + k->enc[mode].name, + k->mac[mode].name, + k->comp[mode].name); + } + choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + if (need < k->enc[mode].key_len) + need = k->enc[mode].key_len; + if (need < k->enc[mode].iv_len) + need = k->enc[mode].iv_len; + if (need < k->mac[mode].key_len) + need = k->mac[mode].key_len; + } + /* XXX need runden? */ + k->we_need = need; + return k; +} + +int +kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret) +{ + int i; + int mode; + int ctos; + unsigned char *keys[NKEYS]; + + for (i = 0; i < NKEYS; i++) + keys[i] = derive_key('A'+i, k->we_need, hash, shared_secret); + + for (mode = 0; mode < MODE_MAX; mode++) { + ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); + k->enc[mode].iv = keys[ctos ? 0 : 1]; + k->enc[mode].key = keys[ctos ? 2 : 3]; + k->mac[mode].key = keys[ctos ? 4 : 5]; + } + return 0; +} diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h new file mode 100644 index 000000000000..7e5c67024bff --- /dev/null +++ b/crypto/openssh/kex.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ +#ifndef KEX_H +#define KEX_H + +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DSS "ssh-dss" + +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +enum kex_modes { + MODE_IN, + MODE_OUT, + MODE_MAX +}; + +typedef struct Kex Kex; +typedef struct Mac Mac; +typedef struct Comp Comp; +typedef struct Enc Enc; + +struct Enc { + int type; + int enabled; + int block_size; + unsigned char *key; + unsigned char *iv; + int key_len; + int iv_len; + char *name; +}; +struct Mac { + EVP_MD *md; + int enabled; + int mac_len; + unsigned char *key; + int key_len; + char *name; +}; +struct Comp { + int type; + int enabled; + char *name; +}; +struct Kex { + Enc enc [MODE_MAX]; + Mac mac [MODE_MAX]; + Comp comp[MODE_MAX]; + int we_need; + int server; + char *name; + char *hostkeyalg; +}; + +Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); +void +kex_exchange_kexinit( + Buffer *my_kexinit, Buffer *peer_kexint, + char *peer_proposal[PROPOSAL_MAX]); +Kex * +kex_choose_conf(char *cprop[PROPOSAL_MAX], + char *sprop[PROPOSAL_MAX], int server); +int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); +void packet_set_kex(Kex *k); +int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); +DH *dh_new_group1(); + +unsigned char * +kex_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret); + +#endif diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c new file mode 100644 index 000000000000..b91bd2190edf --- /dev/null +++ b/crypto/openssh/key.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$ + */ +/* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + */ + +#include "includes.h" +#include "ssh.h" +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/evp.h> +#include "xmalloc.h" +#include "key.h" +#include "dsa.h" +#include "uuencode.h" + +#define SSH_DSS "ssh-dss" + +Key * +key_new(int type) +{ + Key *k; + RSA *rsa; + DSA *dsa; + k = xmalloc(sizeof(*k)); + k->type = type; + k->dsa = NULL; + k->rsa = NULL; + switch (k->type) { + case KEY_RSA: + rsa = RSA_new(); + rsa->n = BN_new(); + rsa->e = BN_new(); + k->rsa = rsa; + break; + case KEY_DSA: + dsa = DSA_new(); + dsa->p = BN_new(); + dsa->q = BN_new(); + dsa->g = BN_new(); + dsa->pub_key = BN_new(); + k->dsa = dsa; + break; + case KEY_EMPTY: + break; + default: + fatal("key_new: bad key type %d", k->type); + break; + } + return k; +} +void +key_free(Key *k) +{ + switch (k->type) { + case KEY_RSA: + if (k->rsa != NULL) + RSA_free(k->rsa); + k->rsa = NULL; + break; + case KEY_DSA: + if (k->dsa != NULL) + DSA_free(k->dsa); + k->dsa = NULL; + break; + default: + fatal("key_free: bad key type %d", k->type); + break; + } + xfree(k); +} +int +key_equal(Key *a, Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + switch (a->type) { + case KEY_RSA: + return a->rsa != NULL && b->rsa != NULL && + BN_cmp(a->rsa->e, b->rsa->e) == 0 && + BN_cmp(a->rsa->n, b->rsa->n) == 0; + break; + case KEY_DSA: + return a->dsa != NULL && b->dsa != NULL && + BN_cmp(a->dsa->p, b->dsa->p) == 0 && + BN_cmp(a->dsa->q, b->dsa->q) == 0 && + BN_cmp(a->dsa->g, b->dsa->g) == 0 && + BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; + break; + default: + fatal("key_equal: bad key type %d", a->type); + break; + } + return 0; +} + +#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" + +/* + * Generate key fingerprint in ascii format. + * Based on ideas and code from Bjoern Groenvall <bg@sics.se> + */ +char * +key_fingerprint(Key *k) +{ + static char retval[80]; + unsigned char *blob = NULL; + int len = 0; + int nlen, elen; + + switch (k->type) { + case KEY_RSA: + nlen = BN_num_bytes(k->rsa->n); + elen = BN_num_bytes(k->rsa->e); + len = nlen + elen; + blob = xmalloc(len); + BN_bn2bin(k->rsa->n, blob); + BN_bn2bin(k->rsa->e, blob + nlen); + break; + case KEY_DSA: + dsa_make_key_blob(k, &blob, &len); + break; + default: + fatal("key_fingerprint: bad key type %d", k->type); + break; + } + if (blob != NULL) { + unsigned char d[16]; + EVP_MD_CTX md; + EVP_DigestInit(&md, EVP_md5()); + EVP_DigestUpdate(&md, blob, len); + EVP_DigestFinal(&md, d, NULL); + snprintf(retval, sizeof(retval), FPRINT, + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + memset(blob, 0, len); + xfree(blob); + } + return retval; +} + +/* + * Reads a multiple-precision integer in decimal from the buffer, and advances + * the pointer. The integer must already be initialized. This function is + * permitted to modify the buffer. This leaves *cpp to point just beyond the + * last processed (and maybe modified) character. Note that this may modify + * the buffer containing the number. + */ +int +read_bignum(char **cpp, BIGNUM * value) +{ + char *cp = *cpp; + int old; + + /* Skip any leading whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Check that it begins with a decimal digit. */ + if (*cp < '0' || *cp > '9') + return 0; + + /* Save starting position. */ + *cpp = cp; + + /* Move forward until all decimal digits skipped. */ + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + + /* Save the old terminating character, and replace it by \0. */ + old = *cp; + *cp = 0; + + /* Parse the number. */ + if (BN_dec2bn(&value, *cpp) == 0) + return 0; + + /* Restore old terminating character. */ + *cp = old; + + /* Move beyond the number and return success. */ + *cpp = cp; + return 1; +} +int +write_bignum(FILE *f, BIGNUM *num) +{ + char *buf = BN_bn2dec(num); + if (buf == NULL) { + error("write_bignum: BN_bn2dec() failed"); + return 0; + } + fprintf(f, " %s", buf); + free(buf); + return 1; +} +unsigned int +key_read(Key *ret, char **cpp) +{ + Key *k; + unsigned int bits = 0; + char *cp; + int len, n; + unsigned char *blob; + + cp = *cpp; + + switch(ret->type) { + case KEY_RSA: + /* Get number of bits. */ + if (*cp < '0' || *cp > '9') + return 0; /* Bad bit count... */ + for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) + bits = 10 * bits + *cp - '0'; + if (bits == 0) + return 0; + *cpp = cp; + /* Get public exponent, public modulus. */ + if (!read_bignum(cpp, ret->rsa->e)) + return 0; + if (!read_bignum(cpp, ret->rsa->n)) + return 0; + break; + case KEY_DSA: + if (strncmp(cp, SSH_DSS " ", 7) != 0) + return 0; + cp += 7; + len = 2*strlen(cp); + blob = xmalloc(len); + n = uudecode(cp, blob, len); + if (n < 0) { + error("key_read: uudecode %s failed", cp); + return 0; + } + k = dsa_key_from_blob(blob, n); + if (k == NULL) { + error("key_read: dsa_key_from_blob %s failed", cp); + return 0; + } + xfree(blob); + if (ret->dsa != NULL) + DSA_free(ret->dsa); + ret->dsa = k->dsa; + k->dsa = NULL; + key_free(k); + bits = BN_num_bits(ret->dsa->p); + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cpp = cp; + break; + default: + fatal("key_read: bad key type: %d", ret->type); + break; + } + return bits; +} +int +key_write(Key *key, FILE *f) +{ + int success = 0; + unsigned int bits = 0; + + if (key->type == KEY_RSA && key->rsa != NULL) { + /* size of modulus 'n' */ + bits = BN_num_bits(key->rsa->n); + fprintf(f, "%u", bits); + if (write_bignum(f, key->rsa->e) && + write_bignum(f, key->rsa->n)) { + success = 1; + } else { + error("key_write: failed for RSA key"); + } + } else if (key->type == KEY_DSA && key->dsa != NULL) { + int len, n; + unsigned char *blob, *uu; + dsa_make_key_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", SSH_DSS, uu); + success = 1; + } + xfree(blob); + xfree(uu); + } + return success; +} +char * +key_type(Key *k) +{ + switch (k->type) { + case KEY_RSA: + return "RSA"; + break; + case KEY_DSA: + return "DSA"; + break; + } + return "unknown"; +} diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h new file mode 100644 index 000000000000..9611d89517d8 --- /dev/null +++ b/crypto/openssh/myproposal.h @@ -0,0 +1,20 @@ +#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" +#define KEX_DEFAULT_PK_ALG "ssh-dss" +#define KEX_DEFAULT_ENCRYPT "3des-cbc,blowfish-cbc,arcfour,cast128-cbc" +#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com" +#define KEX_DEFAULT_COMP "zlib,none" +#define KEX_DEFAULT_LANG "" + + +static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, + KEX_DEFAULT_PK_ALG, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_MAC, + KEX_DEFAULT_MAC, + KEX_DEFAULT_COMP, + KEX_DEFAULT_COMP, + KEX_DEFAULT_LANG, + KEX_DEFAULT_LANG +}; diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c new file mode 100644 index 000000000000..f4c615d23725 --- /dev/null +++ b/crypto/openssh/session.c @@ -0,0 +1,1772 @@ +/* + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + */ +/* + * SSH2 support by Markus Friedl. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * $FreeBSD$ + */ + +#include "includes.h" +RCSID("$OpenBSD: session.c,v 1.15 2000/05/30 17:23:37 markus Exp $"); + +#include "xmalloc.h" +#include "ssh.h" +#include "pty.h" +#include "packet.h" +#include "buffer.h" +#include "cipher.h" +#include "mpaux.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "channels.h" +#include "nchan.h" + +#include "bufaux.h" +#include "ssh2.h" +#include "auth.h" + +#ifdef __FreeBSD__ +#define LOGIN_CAP +#define _PATH_CHPASS "/usr/bin/passwd" +#endif /* __FreeBSD__ */ + +#ifdef LOGIN_CAP +#include <login_cap.h> +#endif /* LOGIN_CAP */ + +#ifdef KRB5 +extern krb5_context ssh_context; +#endif + +/* types */ + +#define TTYSZ 64 +typedef struct Session Session; +struct Session { + int used; + int self; + int extended; + struct passwd *pw; + pid_t pid; + /* tty */ + char *term; + int ptyfd, ttyfd, ptymaster; + int row, col, xpixel, ypixel; + char tty[TTYSZ]; + /* X11 */ + char *display; + int screen; + char *auth_proto; + char *auth_data; + int single_connection; + /* proto 2 */ + int chanid; +}; + +/* func */ + +Session *session_new(void); +void session_set_fds(Session *s, int fdin, int fdout, int fderr); +void session_pty_cleanup(Session *s); +void session_proctitle(Session *s); +void do_exec_pty(Session *s, const char *command, struct passwd * pw); +void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); + +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname); + +/* import */ +extern ServerOptions options; +extern char *__progname; +extern int log_stderr; +extern int debug_flag; + +/* Local Xauthority file. */ +static char *xauthfile; + +/* data */ +#define MAX_SESSIONS 10 +Session sessions[MAX_SESSIONS]; + +/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */ +int no_port_forwarding_flag = 0; +int no_agent_forwarding_flag = 0; +int no_x11_forwarding_flag = 0; +int no_pty_flag = 0; + +/* RSA authentication "command=" option. */ +char *forced_command = NULL; + +/* RSA authentication "environment=" options. */ +struct envstring *custom_environment = NULL; + +/* + * Remove local Xauthority file. + */ +void +xauthfile_cleanup_proc(void *ignore) +{ + debug("xauthfile_cleanup_proc called"); + + if (xauthfile != NULL) { + char *p; + unlink(xauthfile); + p = strrchr(xauthfile, '/'); + if (p != NULL) { + *p = '\0'; + rmdir(xauthfile); + } + xfree(xauthfile); + xauthfile = NULL; + } +} + +/* + * Function to perform cleanup if we get aborted abnormally (e.g., due to a + * dropped connection). + */ +void +pty_cleanup_proc(void *session) +{ + Session *s=session; + if (s == NULL) + fatal("pty_cleanup_proc: no session"); + debug("pty_cleanup_proc: %s", s->tty); + + if (s->pid != 0) { + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + } + + /* Release the pseudo-tty. */ + pty_release(s->tty); +} + +/* + * Prepares for an interactive session. This is called after the user has + * been successfully authenticated. During this message exchange, pseudo + * terminals are allocated, X11, TCP/IP, and authentication agent forwardings + * are requested, etc. + */ +void +do_authenticated(struct passwd * pw) +{ + Session *s; + int type; + int compression_level = 0, enable_compression_after_reply = 0; + int have_pty = 0; + char *command; + int n_bytes; + int plen; + unsigned int proto_len, data_len, dlen; + + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + + /* + * Inform the channel mechanism that we are the server side and that + * the client may request to connect to any port at all. (The user + * could do it anyway, and we wouldn\'t know what is permitted except + * by the client telling us, so we can equally well trust the client + * not to request anything bogus.) + */ + if (!no_port_forwarding_flag) + channel_permit_all_opens(); + + s = session_new(); + s->pw = pw; + + /* + * We stay in this loop until the client requests to execute a shell + * or a command. + */ + for (;;) { + int success = 0; + + /* Get a packet from the client. */ + type = packet_read(&plen); + + /* Process the packet. */ + switch (type) { + case SSH_CMSG_REQUEST_COMPRESSION: + packet_integrity_check(plen, 4, type); + compression_level = packet_get_int(); + if (compression_level < 1 || compression_level > 9) { + packet_send_debug("Received illegal compression level %d.", + compression_level); + break; + } + /* Enable compression after we have responded with SUCCESS. */ + enable_compression_after_reply = 1; + success = 1; + break; + + case SSH_CMSG_REQUEST_PTY: + if (no_pty_flag) { + debug("Allocating a pty not permitted for this authentication."); + break; + } + if (have_pty) + packet_disconnect("Protocol error: you already have a pty."); + + debug("Allocating pty."); + + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty))) { + error("Failed to allocate pty."); + break; + } + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(pw, s->tty); + + /* Get TERM from the packet. Note that the value may be of arbitrary length. */ + s->term = packet_get_string(&dlen); + packet_integrity_check(dlen, strlen(s->term), type); + /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ + /* Remaining bytes */ + n_bytes = plen - (4 + dlen + 4 * 4); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Get window size from the packet. */ + s->row = packet_get_int(); + s->col = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + /* Get tty modes from the packet. */ + tty_parse_modes(s->ttyfd, &n_bytes); + packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); + + session_proctitle(s); + + /* Indicate that we now have a pty. */ + success = 1; + have_pty = 1; + break; + + case SSH_CMSG_X11_REQUEST_FORWARDING: + if (!options.x11_forwarding) { + packet_send_debug("X11 forwarding disabled in server configuration file."); + break; + } +#ifdef XAUTH_PATH + if (no_x11_forwarding_flag) { + packet_send_debug("X11 forwarding not permitted for this authentication."); + break; + } + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->auth_proto = packet_get_string(&proto_len); + s->auth_data = packet_get_string(&data_len); + packet_integrity_check(plen, 4 + proto_len + 4 + data_len + 4, type); + + if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER) + s->screen = packet_get_int(); + else + s->screen = 0; + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + + if (s->display == NULL) + break; + + /* Setup to always have a local .Xauthority. */ + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + /* XXXX remove listening channels */ + break; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, NULL); + success = 1; + break; +#else /* XAUTH_PATH */ + packet_send_debug("No xauth program; cannot forward with spoofing."); + break; +#endif /* XAUTH_PATH */ + + case SSH_CMSG_AGENT_REQUEST_FORWARDING: + if (no_agent_forwarding_flag || compat13) { + debug("Authentication agent forwarding not permitted for this authentication."); + break; + } + debug("Received authentication agent forwarding request."); + success = auth_input_request_forwarding(pw); + break; + + case SSH_CMSG_PORT_FORWARD_REQUEST: + if (no_port_forwarding_flag) { + debug("Port forwarding not permitted for this authentication."); + break; + } + debug("Received TCP/IP port forwarding request."); + channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports); + success = 1; + break; + + case SSH_CMSG_MAX_PACKET_SIZE: + if (packet_set_maxsize(packet_get_int()) > 0) + success = 1; + break; + + case SSH_CMSG_EXEC_SHELL: + case SSH_CMSG_EXEC_CMD: + /* Set interactive/non-interactive mode. */ + packet_set_interactive(have_pty || s->display != NULL, + options.keepalives); + + if (type == SSH_CMSG_EXEC_CMD) { + command = packet_get_string(&dlen); + debug("Exec command '%.500s'", command); + packet_integrity_check(plen, 4 + dlen, type); + } else { + command = NULL; + packet_integrity_check(plen, 0, type); + } + if (forced_command != NULL) { + command = forced_command; + debug("Forced command '%.500s'", forced_command); + } + if (have_pty) + do_exec_pty(s, command, pw); + else + do_exec_no_pty(s, command, pw); + + if (command != NULL) + xfree(command); + /* Cleanup user's local Xauthority file. */ + if (xauthfile) + xauthfile_cleanup_proc(NULL); + return; + + default: + /* + * Any unknown messages in this phase are ignored, + * and a failure message is returned. + */ + log("Unknown packet type received after authentication: %d", type); + } + packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + /* Enable compression now that we have replied if appropriate. */ + if (enable_compression_after_reply) { + enable_compression_after_reply = 0; + packet_start_compression(compression_level); + } + } +} + +/* + * This is called to fork and execute a command when we have no tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors and such. + */ +void +do_exec_no_pty(Session *s, const char *command, struct passwd * pw) +{ + int pid; + +#ifdef USE_PIPES + int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ + if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) + packet_disconnect("Could not create pipes: %.100s", + strerror(errno)); +#else /* USE_PIPES */ + int inout[2], err[2]; + /* Uses socket pairs to communicate with the program. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || + socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) + packet_disconnect("Could not create socket pairs: %.100s", + strerror(errno)); +#endif /* USE_PIPES */ + if (s == NULL) + fatal("do_exec_no_pty: no session"); + + session_proctitle(s); + + /* Fork the child. */ + if ((pid = fork()) == 0) { + /* Child. Reinitialize the log since the pid has changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * Create a new session and process group since the 4.4BSD + * setlogin() affects the entire process group. + */ + if (setsid() < 0) + error("setsid failed: %.100s", strerror(errno)); + +#ifdef USE_PIPES + /* + * Redirect stdin. We close the parent side of the socket + * pair, and make the child side the standard input. + */ + close(pin[1]); + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + + /* Redirect stdout. */ + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + close(pout[1]); + + /* Redirect stderr. */ + close(perr[0]); + if (dup2(perr[1], 2) < 0) + perror("dup2 stderr"); + close(perr[1]); +#else /* USE_PIPES */ + /* + * Redirect stdin, stdout, and stderr. Stdin and stdout will + * use the same socket, as some programs (particularly rdist) + * seem to depend on it. + */ + close(inout[1]); + close(err[1]); + if (dup2(inout[0], 0) < 0) /* stdin */ + perror("dup2 stdin"); + if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ + perror("dup2 stdout"); + if (dup2(err[0], 2) < 0) /* stderr */ + perror("dup2 stderr"); +#endif /* USE_PIPES */ + + /* Do processing for the child (exec command etc). */ + do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; +#ifdef USE_PIPES + /* We are the parent. Close the child sides of the pipes. */ + close(pin[0]); + close(pout[1]); + close(perr[1]); + + if (compat20) { + session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); + } else { + /* Enter the interactive session. */ + server_loop(pid, pin[1], pout[0], perr[0]); + /* server_loop has closed pin[1], pout[1], and perr[1]. */ + } +#else /* USE_PIPES */ + /* We are the parent. Close the child sides of the socket pairs. */ + close(inout[0]); + close(err[0]); + + /* + * Enter the interactive session. Note: server_loop must be able to + * handle the case that fdin and fdout are the same. + */ + if (compat20) { + session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1); + } else { + server_loop(pid, inout[1], inout[1], err[1]); + /* server_loop has closed inout[1] and err[1]. */ + } +#endif /* USE_PIPES */ +} + +/* + * This is called to fork and execute a command when we have a tty. This + * will call do_child from the child, and server_loop from the parent after + * setting up file descriptors, controlling tty, updating wtmp, utmp, + * lastlog, and other such operations. + */ +void +do_exec_pty(Session *s, const char *command, struct passwd * pw) +{ + FILE *f; + char buf[100], *time_string; + char line[256]; + const char *hostname; + int fdout, ptyfd, ttyfd, ptymaster; + int quiet_login; + pid_t pid; + socklen_t fromlen; + struct sockaddr_storage from; + struct stat st; + time_t last_login_time; +#ifdef LOGIN_CAP + login_cap_t *lc; + char *fname; +#endif /* LOGIN_CAP */ +#ifdef __FreeBSD__ +#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ + struct timeval tv; + time_t warntime = DEFAULT_WARN; +#endif /* __FreeBSD__ */ + + if (s == NULL) + fatal("do_exec_pty: no session"); + ptyfd = s->ptyfd; + ttyfd = s->ttyfd; + + /* Get remote host name. */ + hostname = get_canonical_hostname(); + + /* + * Get the time when the user last logged in. Buf will be set to + * contain the hostname the last login was from. + */ + if (!options.use_login) { + last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, + buf, sizeof(buf)); + } + + /* Fork the child. */ + if ((pid = fork()) == 0) { + pid = getpid(); + + /* Child. Reinitialize the log because the pid has + changed. */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* Close the master side of the pseudo tty. */ + close(ptyfd); + + /* Make the pseudo tty our controlling tty. */ + pty_make_controlling_tty(&ttyfd, s->tty); + + /* Redirect stdin from the pseudo tty. */ + if (dup2(ttyfd, fileno(stdin)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stdout to the pseudo tty. */ + if (dup2(ttyfd, fileno(stdout)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Redirect stderr to the pseudo tty. */ + if (dup2(ttyfd, fileno(stderr)) < 0) + error("dup2 stdin failed: %.100s", strerror(errno)); + + /* Close the extra descriptor for the pseudo tty. */ + close(ttyfd); + +/* XXXX ? move to do_child() ??*/ + /* + * Get IP address of client. This is needed because we want + * to record where the user logged in from. If the + * connection is not a socket, let the ip address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + /* Record that there was a login on that terminal. */ + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname, + (struct sockaddr *)&from); + + /* Check if .hushlogin exists. */ + snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); + quiet_login = stat(line, &st) >= 0; + +#ifdef LOGIN_CAP + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + quiet_login = login_getcapbool(lc, "hushlogin", quiet_login); +#endif /* LOGIN_CAP */ + +#ifdef __FreeBSD__ + if (pw->pw_change || pw->pw_expire) + (void)gettimeofday(&tv, NULL); +#ifdef LOGIN_CAP + warntime = login_getcaptime(lc, "warnpassword", + DEFAULT_WARN, DEFAULT_WARN); +#endif /* LOGIN_CAP */ + /* + * If the password change time is set and has passed, give the + * user a password expiry notice and chance to change it. + */ + if (pw->pw_change != 0) { + if (tv.tv_sec >= pw->pw_change) { + (void)printf( + "Sorry -- your password has expired.\n"); + log("%s Password expired - forcing change", + pw->pw_name); + command = _PATH_CHPASS; + } else if (pw->pw_change - tv.tv_sec < warntime && + !quiet_login) + (void)printf( + "Warning: your password expires on %s", + ctime(&pw->pw_change)); + } +#ifdef LOGIN_CAP + warntime = login_getcaptime(lc, "warnexpire", + DEFAULT_WARN, DEFAULT_WARN); +#endif /* LOGIN_CAP */ + if (pw->pw_expire) { + if (tv.tv_sec >= pw->pw_expire) { + (void)printf( + "Sorry -- your account has expired.\n"); + log( + "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s", + pw->pw_name, hostname, ttyname); + exit(254); + } else if (pw->pw_expire - tv.tv_sec < warntime && + !quiet_login) + (void)printf( + "Warning: your account expires on %s", + ctime(&pw->pw_expire)); + } +#endif /* __FreeBSD__ */ +#ifdef LOGIN_CAP + if (!auth_ttyok(lc, ttyname)) { + (void)printf("Permission denied.\n"); + log( + "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s", + pw->pw_name, hostname, ttyname); + exit(254); + } +#endif /* LOGIN_CAP */ + + /* + * If the user has logged in before, display the time of last + * login. However, don't display anything extra if a command + * has been specified (so that ssh can be used to execute + * commands on a remote machine without users knowing they + * are going to another machine). Login(1) will do this for + * us as well, so check if login(1) is used + */ + if (command == NULL && last_login_time != 0 && !quiet_login && + !options.use_login) { + /* Convert the date to a string. */ + time_string = ctime(&last_login_time); + /* Remove the trailing newline. */ + if (strchr(time_string, '\n')) + *strchr(time_string, '\n') = 0; + /* Display the last login time. Host if displayed + if known. */ + if (strcmp(buf, "") == 0) + printf("Last login: %s\r\n", time_string); + else + printf("Last login: %s from %s\r\n", time_string, buf); + } + +#ifdef LOGIN_CAP + if (command == NULL && !quiet_login && !options.use_login) { + fname = login_getcapstr(lc, "copyright", NULL, NULL); + if (fname != NULL && (f = fopen(fname, "r")) != NULL) { + while (fgets(line, sizeof(line), f) != NULL) + fputs(line, stdout); + fclose(f); + } else + (void)printf("%s\n\t%s %s\n", + "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", + "The Regents of the University of California. ", + "All rights reserved."); + } +#endif /* LOGIN_CAP */ + + /* + * Print /etc/motd unless a command was specified or printing + * it was disabled in server options or login(1) will be + * used. Note that some machines appear to print it in + * /etc/profile or similar. + */ + if (command == NULL && options.print_motd && !quiet_login && + !options.use_login) { +#ifdef LOGIN_CAP + fname = login_getcapstr(lc, "welcome", NULL, NULL); + if (fname == NULL || (f = fopen(fname, "r")) == NULL) + f = fopen("/etc/motd", "r"); +#else /* !LOGIN_CAP */ + f = fopen("/etc/motd", "r"); +#endif /* LOGIN_CAP */ + /* Print /etc/motd if it exists. */ + if (f) { + while (fgets(line, sizeof(line), f)) + fputs(line, stdout); + fclose(f); + } + } +#ifdef LOGIN_CAP + login_close(lc); +#endif /* LOGIN_CAP */ + + /* Do common processing for the child, such as execing the command. */ + do_child(command, pw, s->term, s->display, s->auth_proto, + s->auth_data, s->tty); + /* NOTREACHED */ + } + if (pid < 0) + packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; + + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + + /* + * Create another descriptor of the pty master side for use as the + * standard input. We could use the original descriptor, but this + * simplifies code in server_loop. The descriptor is bidirectional. + */ + fdout = dup(ptyfd); + if (fdout < 0) + packet_disconnect("dup #1 failed: %.100s", strerror(errno)); + + /* we keep a reference to the pty master */ + ptymaster = dup(ptyfd); + if (ptymaster < 0) + packet_disconnect("dup #2 failed: %.100s", strerror(errno)); + s->ptymaster = ptymaster; + + /* Enter interactive session. */ + if (compat20) { + session_set_fds(s, ptyfd, fdout, -1); + } else { + server_loop(pid, ptyfd, fdout, -1); + /* server_loop _has_ closed ptyfd and fdout. */ + session_pty_cleanup(s); + } +} + +/* + * Sets the value of the given variable in the environment. If the variable + * already exists, its value is overriden. + */ +void +child_set_env(char ***envp, unsigned int *envsizep, const char *name, + const char *value) +{ + unsigned int i, namelen; + char **env; + + /* + * Find the slot where the value should be stored. If the variable + * already exists, we reuse the slot; otherwise we append a new slot + * at the end of the array, expanding if necessary. + */ + env = *envp; + namelen = strlen(name); + for (i = 0; env[i]; i++) + if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') + break; + if (env[i]) { + /* Reuse the slot. */ + xfree(env[i]); + } else { + /* New variable. Expand if necessary. */ + if (i >= (*envsizep) - 1) { + (*envsizep) += 50; + env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); + } + /* Need to set the NULL pointer at end of array beyond the new slot. */ + env[i + 1] = NULL; + } + + /* Allocate space and format the variable in the appropriate slot. */ + env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); + snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); +} + +/* + * Reads environment variables from the given file and adds/overrides them + * into the environment. If the file does not exist, this does nothing. + * Otherwise, it must consist of empty lines, comments (line starts with '#') + * and assignments of the form name=value. No other forms are allowed. + */ +void +read_environment_file(char ***env, unsigned int *envsize, + const char *filename) +{ + FILE *f; + char buf[4096]; + char *cp, *value; + + f = fopen(filename, "r"); + if (!f) + return; + + while (fgets(buf, sizeof(buf), f)) { + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + if (strchr(cp, '\n')) + *strchr(cp, '\n') = '\0'; + value = strchr(cp, '='); + if (value == NULL) { + fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); + continue; + } + /* + * Replace the equals sign by nul, and advance value to + * the value string. + */ + *value = '\0'; + value++; + child_set_env(env, envsize, cp, value); + } + fclose(f); +} + +/* + * Performs common processing for the child, such as setting up the + * environment, closing extra file descriptors, setting the user and group + * ids, and executing the command or shell. + */ +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname) +{ + char *shell; + const char *cp = NULL; + char buf[256]; + FILE *f; + unsigned int envsize, i; + char **env = NULL; + extern char **environ; + struct stat st; + char *argv[10]; + +#ifdef LOGIN_CAP + login_cap_t *lc; + + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + if (pw->pw_uid != 0) + auth_checknologin(lc); +#else /* !LOGIN_CAP */ + f = fopen("/etc/nologin", "r"); + if (f) { + /* /etc/nologin exists. Print its contents and exit. */ + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); + if (pw->pw_uid != 0) + exit(254); + } +#endif /* LOGIN_CAP */ + +#ifdef LOGIN_CAP + if (options.use_login) +#endif /* LOGIN_CAP */ + /* Set login name in the kernel. */ + if (setlogin(pw->pw_name) < 0) + error("setlogin failed: %s", strerror(errno)); + + /* Set uid, gid, and groups. */ + /* Login(1) does this as well, and it needs uid 0 for the "-h" + switch, so we let login(1) to this for us. */ + if (!options.use_login) { +#ifdef LOGIN_CAP + char **tmpenv; + + /* Initialize temp environment */ + envsize = 64; + env = xmalloc(envsize * sizeof(char *)); + env[0] = NULL; + + child_set_env(&env, &envsize, "PATH", + (pw->pw_uid == 0) ? + _PATH_STDPATH : _PATH_DEFPATH); + + snprintf(buf, sizeof buf, "%.200s/%.50s", + _PATH_MAILDIR, pw->pw_name); + child_set_env(&env, &envsize, "MAIL", buf); + + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + + /* Save parent environment */ + tmpenv = environ; + environ = env; + + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0) + fatal("setusercontext failed: %s", strerror(errno)); + + /* Restore parent environment */ + env = environ; + environ = tmpenv; + + for (envsize = 0; env[envsize] != NULL; ++envsize) + ; + envsize = (envsize < 100) ? 100 : envsize + 16; + env = xrealloc(env, envsize * sizeof(char *)); + +#else /* !LOGIN_CAP */ + if (getuid() == 0 || geteuid() == 0) { + if (setgid(pw->pw_gid) < 0) { + perror("setgid"); + exit(1); + } + /* Initialize the group list. */ + if (initgroups(pw->pw_name, pw->pw_gid) < 0) { + perror("initgroups"); + exit(1); + } + endgrent(); + + /* Permanently switch to the desired uid. */ + permanently_set_uid(pw->pw_uid); + } + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) + fatal("Failed to set uids to %d.", (int) pw->pw_uid); +#endif /* LOGIN_CAP */ + } + /* + * Get the shell from the password data. An empty shell field is + * legal, and means /bin/sh. + */ + shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; +#ifdef LOGIN_CAP + shell = login_getcapstr(lc, "shell", shell, shell); +#endif /* LOGIN_CAP */ + +#ifdef AFS + /* Try to get AFS tokens for the local cell. */ + if (k_hasafs()) { + char cell[64]; + + if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) + krb_afslog(cell, 0); + + krb_afslog(0, 0); + } +#endif /* AFS */ + + /* Initialize the environment. */ + if (env == NULL) { + envsize = 100; + env = xmalloc(envsize * sizeof(char *)); + env[0] = NULL; + } + + if (!options.use_login) { + /* Set basic environment. */ + child_set_env(&env, &envsize, "USER", pw->pw_name); + child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); + child_set_env(&env, &envsize, "HOME", pw->pw_dir); +#ifndef LOGIN_CAP + child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); + + snprintf(buf, sizeof buf, "%.200s/%.50s", + _PATH_MAILDIR, pw->pw_name); + child_set_env(&env, &envsize, "MAIL", buf); +#endif /* !LOGIN_CAP */ + + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); + } +#ifdef LOGIN_CAP + if (options.use_login) +#endif /* LOGIN_CAP */ + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + + /* Set custom environment options from RSA authentication. */ + while (custom_environment) { + struct envstring *ce = custom_environment; + char *s = ce->s; + int i; + for (i = 0; s[i] != '=' && s[i]; i++); + if (s[i] == '=') { + s[i] = 0; + child_set_env(&env, &envsize, s, s + i + 1); + } + custom_environment = ce->next; + xfree(ce->s); + xfree(ce); + } + + snprintf(buf, sizeof buf, "%.50s %d %d", + get_remote_ipaddr(), get_remote_port(), get_local_port()); + child_set_env(&env, &envsize, "SSH_CLIENT", buf); + + if (ttyname) + child_set_env(&env, &envsize, "SSH_TTY", ttyname); + if (term) + child_set_env(&env, &envsize, "TERM", term); + if (display) + child_set_env(&env, &envsize, "DISPLAY", display); + +#ifdef KRB4 + { + extern char *ticket; + + if (ticket) + child_set_env(&env, &envsize, "KRBTKFILE", ticket); + } +#endif /* KRB4 */ +#ifdef KRB5 +{ + extern krb5_ccache mem_ccache; + + if (mem_ccache) { + krb5_error_code problem; + krb5_ccache ccache; +#ifdef AFS + if (k_hasafs()) + krb5_afslog(ssh_context, mem_ccache, NULL, NULL); +#endif /* AFS */ + + problem = krb5_cc_default(ssh_context, &ccache); + if (problem) {} + else { + problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache); + if (problem) {} + } + + krb5_cc_close(ssh_context, ccache); + } + + krb5_cleanup_proc(NULL); + } +#endif /* KRB5 */ + + if (xauthfile) + child_set_env(&env, &envsize, "XAUTHORITY", xauthfile); + if (auth_get_socket_name() != NULL) + child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, + auth_get_socket_name()); + + /* read $HOME/.ssh/environment. */ + if (!options.use_login) { + snprintf(buf, sizeof buf, "%.200s/.ssh/environment", + pw->pw_dir); + read_environment_file(&env, &envsize, buf); + } + if (debug_flag) { + /* dump the environment */ + fprintf(stderr, "Environment:\n"); + for (i = 0; env[i]; i++) + fprintf(stderr, " %.200s\n", env[i]); + } + /* + * Close the connection descriptors; note that this is the child, and + * the server will still have the socket open, and it is important + * that we do not shutdown it. Note that the descriptors cannot be + * closed before building the environment, as we call + * get_remote_ipaddr there. + */ + if (packet_get_connection_in() == packet_get_connection_out()) + close(packet_get_connection_in()); + else { + close(packet_get_connection_in()); + close(packet_get_connection_out()); + } + /* + * Close all descriptors related to channels. They will still remain + * open in the parent. + */ + /* XXX better use close-on-exec? -markus */ + channel_close_all(); + + /* + * Close any extra file descriptors. Note that there may still be + * descriptors left by system functions. They will be closed later. + */ + endpwent(); + + /* + * Close any extra open file descriptors so that we don\'t have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ + for (i = 3; i < getdtablesize(); i++) + close(i); + + /* Change current directory to the user\'s home directory. */ + if ( +#ifdef __FreeBSD__ + !*pw->pw_dir || +#endif /* __FreeBSD__ */ + chdir(pw->pw_dir) < 0 + ) { +#ifdef __FreeBSD__ + int quiet_login = 0; +#endif /* __FreeBSD__ */ +#ifdef LOGIN_CAP + if (login_getcapbool(lc, "requirehome", 0)) { + (void)printf("Home directory not available\n"); + log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s", + pw->pw_name, ttyname); + exit(254); + } +#endif /* LOGIN_CAP */ +#ifdef __FreeBSD__ + if (chdir("/") < 0) { + (void)printf("Cannot find root directory\n"); + log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s", + pw->pw_name, ttyname); + exit(254); + } +#ifdef LOGIN_CAP + quiet_login = login_getcapbool(lc, "hushlogin", 0); +#endif /* LOGIN_CAP */ + if (!quiet_login || *pw->pw_dir) + (void)printf( + "No home directory.\nLogging in with home = \"/\".\n"); + +#else /* !__FreeBSD__ */ + + fprintf(stderr, "Could not chdir to home directory %s: %s\n", + pw->pw_dir, strerror(errno)); +#endif /* __FreeBSD__ */ + } +#ifdef LOGIN_CAP + login_close(lc); +#endif /* LOGIN_CAP */ + + /* + * Must take new environment into use so that .ssh/rc, /etc/sshrc and + * xauth are run in the proper environment. + */ + environ = env; + + /* + * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first + * in this order). + */ + if (!options.use_login) { + if (stat(SSH_USER_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC); + + f = popen("/bin/sh " SSH_USER_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_USER_RC); + } else if (stat(SSH_SYSTEM_RC, &st) >= 0) { + if (debug_flag) + fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC); + + f = popen("/bin/sh " SSH_SYSTEM_RC, "w"); + if (f) { + if (auth_proto != NULL && auth_data != NULL) + fprintf(f, "%s %s\n", auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC); + } +#ifdef XAUTH_PATH + else { + /* Add authority data to .Xauthority if appropriate. */ + if (auth_proto != NULL && auth_data != NULL) { + char *screen = strchr(display, ':'); + if (debug_flag) { + fprintf(stderr, + "Running %.100s add %.100s %.100s %.100s\n", + XAUTH_PATH, display, auth_proto, auth_data); + if (screen != NULL) + fprintf(stderr, + "Adding %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + } + f = popen(XAUTH_PATH " -q -", "w"); + if (f) { + fprintf(f, "add %s %s %s\n", display, + auth_proto, auth_data); + if (screen != NULL) + fprintf(f, "add %.*s/unix%s %s %s\n", + screen-display, display, + screen, auth_proto, auth_data); + pclose(f); + } else + fprintf(stderr, "Could not run %s -q -\n", + XAUTH_PATH); + } + } +#endif /* XAUTH_PATH */ + + /* Get the last component of the shell name. */ + cp = strrchr(shell, '/'); + if (cp) + cp++; + else + cp = shell; + } + /* + * If we have no command, execute the shell. In this case, the shell + * name to be passed in argv[0] is preceded by '-' to indicate that + * this is a login shell. + */ + if (!command) { + if (!options.use_login) { + char buf[256]; + + /* + * Check for mail if we have a tty and it was enabled + * in server options. + */ + if (ttyname && options.check_mail) { + char *mailbox; + struct stat mailstat; + mailbox = getenv("MAIL"); + if (mailbox != NULL) { + if (stat(mailbox, &mailstat) != 0 || + mailstat.st_size == 0) +#ifdef __FreeBSD__ + ; +#else /* !__FreeBSD__ */ + printf("No mail.\n"); +#endif /* __FreeBSD__ */ + else if (mailstat.st_mtime < mailstat.st_atime) + printf("You have mail.\n"); + else + printf("You have new mail.\n"); + } + } + /* Start the shell. Set initial character to '-'. */ + buf[0] = '-'; + strncpy(buf + 1, cp, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + + /* Execute the shell. */ + argv[0] = buf; + argv[1] = NULL; + execve(shell, argv, env); + + /* Executing the shell failed. */ + perror(shell); + exit(1); + + } else { + /* Launch login(1). */ + + execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), + "-p", "-f", "--", pw->pw_name, NULL); + + /* Login couldn't be executed, die. */ + + perror("login"); + exit(1); + } + } + /* + * Execute the command using the user's shell. This uses the -c + * option to execute the command. + */ + argv[0] = (char *) cp; + argv[1] = "-c"; + argv[2] = (char *) command; + argv[3] = NULL; + execve(shell, argv, env); + perror(shell); + exit(1); +} + +Session * +session_new(void) +{ + int i; + static int did_init = 0; + if (!did_init) { + debug("session_new: init"); + for(i = 0; i < MAX_SESSIONS; i++) { + sessions[i].used = 0; + sessions[i].self = i; + } + did_init = 1; + } + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (! s->used) { + s->pid = 0; + s->extended = 0; + s->chanid = -1; + s->ptyfd = -1; + s->ttyfd = -1; + s->term = NULL; + s->pw = NULL; + s->display = NULL; + s->screen = 0; + s->auth_data = NULL; + s->auth_proto = NULL; + s->used = 1; + s->pw = NULL; + debug("session_new: session %d", i); + return s; + } + } + return NULL; +} + +void +session_dump(void) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + debug("dump: used %d session %d %p channel %d pid %d", + s->used, + s->self, + s, + s->chanid, + s->pid); + } +} + +int +session_open(int chanid) +{ + Session *s = session_new(); + debug("session_open: channel %d", chanid); + if (s == NULL) { + error("no more sessions"); + return 0; + } + s->pw = auth_get_user(); + if (s->pw == NULL) + fatal("no user for session %i", s->self); + debug("session_open: session %d: link with channel %d", s->self, chanid); + s->chanid = chanid; + return 1; +} + +Session * +session_by_channel(int id) +{ + int i; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->chanid == id) { + debug("session_by_channel: session %d channel %d", i, id); + return s; + } + } + debug("session_by_channel: unknown channel %d", id); + session_dump(); + return NULL; +} + +Session * +session_by_pid(pid_t pid) +{ + int i; + debug("session_by_pid: pid %d", pid); + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->pid == pid) + return s; + } + error("session_by_pid: unknown pid %d", pid); + session_dump(); + return NULL; +} + +int +session_window_change_req(Session *s) +{ + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + packet_done(); + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + return 1; +} + +int +session_pty_req(Session *s) +{ + unsigned int len; + char *term_modes; /* encoded terminal modes */ + + if (s->ttyfd != -1) + return 0; + s->term = packet_get_string(&len); + s->col = packet_get_int(); + s->row = packet_get_int(); + s->xpixel = packet_get_int(); + s->ypixel = packet_get_int(); + term_modes = packet_get_string(&len); + packet_done(); + + if (strcmp(s->term, "") == 0) { + xfree(s->term); + s->term = NULL; + } + /* Allocate a pty and open it. */ + if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + xfree(s->term); + s->term = NULL; + s->ptyfd = -1; + s->ttyfd = -1; + error("session_pty_req: session %d alloc failed", s->self); + xfree(term_modes); + return 0; + } + debug("session_pty_req: session %d alloc %s", s->self, s->tty); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + fatal_add_cleanup(pty_cleanup_proc, (void *)s); + pty_setowner(s->pw, s->tty); + /* Get window size from the packet. */ + pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); + + session_proctitle(s); + + /* XXX parse and set terminal modes */ + xfree(term_modes); + return 1; +} + +int +session_subsystem_req(Session *s) +{ + unsigned int len; + int success = 0; + char *subsys = packet_get_string(&len); + + packet_done(); + log("subsystem request for %s", subsys); + + xfree(subsys); + return success; +} + +int +session_x11_req(Session *s) +{ + if (!options.x11_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } + if (xauthfile != NULL) { + debug("X11 fwd already started."); + return 0; + } + + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->single_connection = packet_get_char(); + s->auth_proto = packet_get_string(NULL); + s->auth_data = packet_get_string(NULL); + s->screen = packet_get_int(); + packet_done(); + + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + if (s->display == NULL) { + xfree(s->auth_proto); + xfree(s->auth_data); + return 0; + } + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(s->pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + xfree(s->auth_proto); + xfree(s->auth_data); + /* XXXX remove listening channels */ + return 0; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, s); + return 1; +} + +void +session_input_channel_req(int id, void *arg) +{ + unsigned int len; + int reply; + int success = 0; + char *rtype; + Session *s; + Channel *c; + + rtype = packet_get_string(&len); + reply = packet_get_char(); + + s = session_by_channel(id); + if (s == NULL) + fatal("session_input_channel_req: channel %d: no session", id); + c = channel_lookup(id); + if (c == NULL) + fatal("session_input_channel_req: channel %d: bad channel", id); + + debug("session_input_channel_req: session %d channel %d request %s reply %d", + s->self, id, rtype, reply); + + /* + * a session is in LARVAL state until a shell + * or programm is executed + */ + if (c->type == SSH_CHANNEL_LARVAL) { + if (strcmp(rtype, "shell") == 0) { + packet_done(); + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, NULL, s->pw); + else + do_exec_pty(s, NULL, s->pw); + success = 1; + } else if (strcmp(rtype, "exec") == 0) { + char *command = packet_get_string(&len); + packet_done(); + s->extended = 1; + if (s->ttyfd == -1) + do_exec_no_pty(s, command, s->pw); + else + do_exec_pty(s, command, s->pw); + xfree(command); + success = 1; + } else if (strcmp(rtype, "pty-req") == 0) { + success = session_pty_req(s); + } else if (strcmp(rtype, "x11-req") == 0) { + success = session_x11_req(s); + } else if (strcmp(rtype, "subsystem") == 0) { + success = session_subsystem_req(s); + } + } + if (strcmp(rtype, "window-change") == 0) { + success = session_window_change_req(s); + } + + if (reply) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} + +void +session_set_fds(Session *s, int fdin, int fdout, int fderr) +{ + if (!compat20) + fatal("session_set_fds: called for proto != 2.0"); + /* + * now that have a child and a pipe to the child, + * we can activate our channel and register the fd's + */ + if (s->chanid == -1) + fatal("no channel for session %d", s->self); + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ); +} + +void +session_pty_cleanup(Session *s) +{ + if (s == NULL || s->ttyfd == -1) + return; + + debug("session_pty_cleanup: session %i release %s", s->self, s->tty); + + /* Cancel the cleanup function. */ + fatal_remove_cleanup(pty_cleanup_proc, (void *)s); + + /* Record that the user has logged out. */ + record_logout(s->pid, s->tty); + + /* Release the pseudo-tty. */ + pty_release(s->tty); + + /* + * Close the server side of the socket pairs. We must do this after + * the pty cleanup, so that another process doesn't get this pty + * while we're still cleaning up. + */ + if (close(s->ptymaster) < 0) + error("close(s->ptymaster): %s", strerror(errno)); +} + +void +session_exit_message(Session *s, int status) +{ + Channel *c; + if (s == NULL) + fatal("session_close: no session"); + c = channel_lookup(s->chanid); + if (c == NULL) + fatal("session_close: session %d: no channel %d", + s->self, s->chanid); + debug("session_exit_message: session %d channel %d pid %d", + s->self, s->chanid, s->pid); + + if (WIFEXITED(status)) { + channel_request_start(s->chanid, + "exit-status", 0); + packet_put_int(WEXITSTATUS(status)); + packet_send(); + } else if (WIFSIGNALED(status)) { + channel_request_start(s->chanid, + "exit-signal", 0); + packet_put_int(WTERMSIG(status)); + packet_put_char(WCOREDUMP(status)); + packet_put_cstring(""); + packet_put_cstring(""); + packet_send(); + } else { + /* Some weird exit cause. Just exit. */ + packet_disconnect("wait returned status %04x.", status); + } + + /* disconnect channel */ + debug("session_exit_message: release channel %d", s->chanid); + channel_cancel_cleanup(s->chanid); + /* + * emulate a write failure with 'chan_write_failed', nobody will be + * interested in data we write. + * Note that we must not call 'chan_read_failed', since there could + * be some more data waiting in the pipe. + */ + if (c->ostate != CHAN_OUTPUT_CLOSED) + chan_write_failed(c); + s->chanid = -1; +} + +void +session_free(Session *s) +{ + debug("session_free: session %d pid %d", s->self, s->pid); + if (s->term) + xfree(s->term); + if (s->display) + xfree(s->display); + if (s->auth_data) + xfree(s->auth_data); + if (s->auth_proto) + xfree(s->auth_proto); + s->used = 0; +} + +void +session_close(Session *s) +{ + session_pty_cleanup(s); + session_free(s); + session_proctitle(s); +} + +void +session_close_by_pid(pid_t pid, int status) +{ + Session *s = session_by_pid(pid); + if (s == NULL) { + debug("session_close_by_pid: no session for pid %d", s->pid); + return; + } + if (s->chanid != -1) + session_exit_message(s, status); + session_close(s); +} + +/* + * this is called when a channel dies before + * the session 'child' itself dies + */ +void +session_close_by_channel(int id, void *arg) +{ + Session *s = session_by_channel(id); + if (s == NULL) { + debug("session_close_by_channel: no session for channel %d", id); + return; + } + /* disconnect channel */ + channel_cancel_cleanup(s->chanid); + s->chanid = -1; + + debug("session_close_by_channel: channel %d kill %d", id, s->pid); + if (s->pid == 0) { + /* close session immediately */ + session_close(s); + } else { + /* notify child, delay session cleanup */ + if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) + error("session_close_by_channel: kill %d: %s", + s->pid, strerror(errno)); + } +} + +char * +session_tty_list(void) +{ + static char buf[1024]; + int i; + buf[0] = '\0'; + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->ttyfd != -1) { + if (buf[0] != '\0') + strlcat(buf, ",", sizeof buf); + strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + } + } + if (buf[0] == '\0') + strlcpy(buf, "notty", sizeof buf); + return buf; +} + +void +session_proctitle(Session *s) +{ + if (s->pw == NULL) + error("no user for session %d", s->self); + else + setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); +} + +void +do_authenticated2(void) +{ + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + server_loop2(); + if (xauthfile) + xauthfile_cleanup_proc(NULL); +} diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h new file mode 100644 index 000000000000..1fa4c0a0ddae --- /dev/null +++ b/crypto/openssh/ssh2.h @@ -0,0 +1,112 @@ +/* + * draft-ietf-secsh-architecture-05.txt + * + * Transport layer protocol: + * + * 1-19 Transport layer generic (e.g. disconnect, ignore, debug, + * etc) + * 20-29 Algorithm negotiation + * 30-49 Key exchange method specific (numbers can be reused for + * different authentication methods) + * + * User authentication protocol: + * + * 50-59 User authentication generic + * 60-79 User authentication method specific (numbers can be reused + * for different authentication methods) + * + * Connection protocol: + * + * 80-89 Connection protocol generic + * 90-127 Channel related messages + * + * Reserved for client protocols: + * + * 128-191 Reserved + * + * Local extensions: + * + * 192-255 Local extensions + */ +/* RCSID("$OpenBSD: ssh2.h,v 1.3 2000/05/15 07:03:12 markus Exp $"); */ + +/* transport layer: generic */ + +#define SSH2_MSG_DISCONNECT 1 +#define SSH2_MSG_IGNORE 2 +#define SSH2_MSG_UNIMPLEMENTED 3 +#define SSH2_MSG_DEBUG 4 +#define SSH2_MSG_SERVICE_REQUEST 5 +#define SSH2_MSG_SERVICE_ACCEPT 6 + +/* transport layer: alg negotiation */ + +#define SSH2_MSG_KEXINIT 20 +#define SSH2_MSG_NEWKEYS 21 + +/* transport layer: kex specific messages, can be reused */ + +#define SSH2_MSG_KEXDH_INIT 30 +#define SSH2_MSG_KEXDH_REPLY 31 + +/* user authentication: generic */ + +#define SSH2_MSG_USERAUTH_REQUEST 50 +#define SSH2_MSG_USERAUTH_FAILURE 51 +#define SSH2_MSG_USERAUTH_SUCCESS 52 +#define SSH2_MSG_USERAUTH_BANNER 53 + +/* user authentication: method specific, can be reused */ + +#define SSH2_MSG_USERAUTH_PK_OK 60 +#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 + +/* connection protocol: generic */ + +#define SSH2_MSG_GLOBAL_REQUEST 80 +#define SSH2_MSG_REQUEST_SUCCESS 81 +#define SSH2_MSG_REQUEST_FAILURE 82 + +/* channel related messages */ + +#define SSH2_MSG_CHANNEL_OPEN 90 +#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH2_MSG_CHANNEL_DATA 94 +#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH2_MSG_CHANNEL_EOF 96 +#define SSH2_MSG_CHANNEL_CLOSE 97 +#define SSH2_MSG_CHANNEL_REQUEST 98 +#define SSH2_MSG_CHANNEL_SUCCESS 99 +#define SSH2_MSG_CHANNEL_FAILURE 100 + +/* disconnect reason code */ + +#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 +#define SSH2_DISCONNECT_RESERVED 4 +#define SSH2_DISCONNECT_MAC_ERROR 5 +#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH2_DISCONNECT_CONNECTION_LOST 10 +#define SSH2_DISCONNECT_BY_APPLICATION 11 +#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* misc */ + +#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH2_OPEN_CONNECT_FAILED 2 +#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 +#define SSH2_OPEN_RESOURCE_SHORTAGE 4 + +#define SSH2_EXTENDED_DATA_STDERR 1 diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c new file mode 100644 index 000000000000..0abcf89a0a07 --- /dev/null +++ b/crypto/openssh/sshconnect2.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2000 Markus Friedl. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Markus Friedl. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +#include "includes.h" +RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); + +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/md5.h> +#include <openssl/dh.h> +#include <openssl/hmac.h> + +#include "ssh.h" +#include "xmalloc.h" +#include "rsa.h" +#include "buffer.h" +#include "packet.h" +#include "cipher.h" +#include "uidswap.h" +#include "compat.h" +#include "readconf.h" +#include "bufaux.h" +#include "ssh2.h" +#include "kex.h" +#include "myproposal.h" +#include "key.h" +#include "dsa.h" +#include "sshconnect.h" +#include "authfile.h" + +/* import */ +extern char *client_version_string; +extern char *server_version_string; +extern Options options; + +/* + * SSH2 key exchange + */ + +unsigned char *session_id2 = NULL; +int session_id2_len = 0; + +void +ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, + Buffer *client_kexinit, Buffer *server_kexinit) +{ + int i; + int plen, dlen; + unsigned int klen, kout; + char *signature = NULL; + unsigned int slen; + char *server_host_key_blob = NULL; + Key *server_host_key; + unsigned int sbloblen; + DH *dh; + BIGNUM *dh_server_pub = 0; + BIGNUM *shared_secret = 0; + unsigned char *kbuf; + unsigned char *hash; + + debug("Sending SSH2_MSG_KEXDH_INIT."); + /* generate and send 'e', client DH public key */ + dh = dh_new_group1(); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + packet_write_wait(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\np= "); + bignum_print(dh->p); + fprintf(stderr, "\ng= "); + bignum_print(dh->g); + fprintf(stderr, "\npub= "); + bignum_print(dh->pub_key); + fprintf(stderr, "\n"); + DHparams_print_fp(stderr, dh); +#endif + + debug("Wait SSH2_MSG_KEXDH_REPLY."); + + packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY); + + debug("Got SSH2_MSG_KEXDH_REPLY."); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + + check_host_key(host, hostaddr, server_host_key, + options.user_hostfile2, options.system_hostfile2); + + /* DH paramter f, server public DH key */ + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub, &dlen); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "\ndh_server_pub= "); + bignum_print(dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_done(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + debug("shared secret: len %d/%d", klen, kout); + fprintf(stderr, "shared secret == "); + for (i = 0; i< kout; i++) + fprintf(stderr, "%02x", (kbuf[i])&0xff); + fprintf(stderr, "\n"); +#endif + shared_secret = BN_new(); + + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + hash = kex_hash( + client_version_string, + server_version_string, + buffer_ptr(client_kexinit), buffer_len(client_kexinit), + buffer_ptr(server_kexinit), buffer_len(server_kexinit), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret + ); + xfree(server_host_key_blob); + DH_free(dh); +#ifdef DEBUG_KEXDH + fprintf(stderr, "hash == "); + for (i = 0; i< 20; i++) + fprintf(stderr, "%02x", (hash[i])&0xff); + fprintf(stderr, "\n"); +#endif + if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) + fatal("dsa_verify failed for server_host_key"); + key_free(server_host_key); + + kex_derive_keys(kex, hash, shared_secret); + packet_set_kex(kex); + + /* save session id */ + session_id2_len = 20; + session_id2 = xmalloc(session_id2_len); + memcpy(session_id2, hash, session_id2_len); +} + +void +ssh_kex2(char *host, struct sockaddr *hostaddr) +{ + int i, plen; + Kex *kex; + Buffer *client_kexinit, *server_kexinit; + char *sprop[PROPOSAL_MAX]; + + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } else if (options.cipher == SSH_CIPHER_3DES) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_3DES_CBC); + } else if (options.cipher == SSH_CIPHER_BLOWFISH) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = + (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC); + } + if (options.compression) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; + } else { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; + } + + /* buffers with raw kexinit messages */ + server_kexinit = xmalloc(sizeof(*server_kexinit)); + buffer_init(server_kexinit); + client_kexinit = kex_init(myproposal); + + /* algorithm negotiation */ + kex_exchange_kexinit(client_kexinit, server_kexinit, sprop); + kex = kex_choose_conf(myproposal, sprop, 0); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(sprop[i]); + + /* server authentication and session key agreement */ + ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit); + + buffer_free(client_kexinit); + buffer_free(server_kexinit); + xfree(client_kexinit); + xfree(server_kexinit); + + debug("Wait SSH2_MSG_NEWKEYS."); + packet_read_expect(&plen, SSH2_MSG_NEWKEYS); + packet_done(); + debug("GOT SSH2_MSG_NEWKEYS."); + + debug("send SSH2_MSG_NEWKEYS."); + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + packet_write_wait(); + debug("done: send SSH2_MSG_NEWKEYS."); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + packet_start(SSH2_MSG_IGNORE); + packet_put_cstring("markus"); + packet_send(); + packet_write_wait(); +#endif + debug("done: KEX2."); +} + +/* + * Authenticate user + */ +int +ssh2_try_passwd(const char *server_user, const char *host, const char *service) +{ + static int attempt = 0; + char prompt[80]; + char *password; + + if (attempt++ > options.number_of_password_prompts) + return 0; + + snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", + server_user, host); + password = read_passphrase(prompt, 0); + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("password"); + packet_put_char(0); + packet_put_cstring(password); + memset(password, 0, strlen(password)); + xfree(password); + packet_send(); + packet_write_wait(); + return 1; +} + +int +ssh2_try_pubkey(char *filename, + const char *server_user, const char *host, const char *service) +{ + Buffer b; + Key *k; + unsigned char *blob, *signature; + int bloblen, slen; + struct stat st; + + if (stat(filename, &st) != 0) { + debug("key does not exist: %s", filename); + return 0; + } + debug("try pubkey: %s", filename); + + k = key_new(KEY_DSA); + if (!load_private_key(filename, "", k, NULL)) { + int success = 0; + char *passphrase; + char prompt[300]; + snprintf(prompt, sizeof prompt, + "Enter passphrase for DSA key '%.100s': ", + filename); + passphrase = read_passphrase(prompt, 0); + success = load_private_key(filename, passphrase, k, NULL); + memset(passphrase, 0, strlen(passphrase)); + xfree(passphrase); + if (!success) + return 0; + } + dsa_make_key_blob(k, &blob, &bloblen); + + /* data to be signed */ + buffer_init(&b); + buffer_append(&b, session_id2, session_id2_len); + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PUBKEYAUTH ? + "ssh-userauth" : + service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + + /* generate signature */ + dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + key_free(k); +#ifdef DEBUG_DSS + buffer_dump(&b); +#endif + if (datafellows & SSH_BUG_PUBKEYAUTH) { + /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */ + buffer_clear(&b); + buffer_append(&b, session_id2, session_id2_len); + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, server_user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, 1); + buffer_put_cstring(&b, KEX_DSS); + buffer_put_string(&b, blob, bloblen); + } + xfree(blob); + /* append signature */ + buffer_put_string(&b, signature, slen); + xfree(signature); + + /* skip session id and packet type */ + if (buffer_len(&b) < session_id2_len + 1) + fatal("ssh2_try_pubkey: internal error"); + buffer_consume(&b, session_id2_len + 1); + + /* put remaining data from buffer into packet */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_raw(buffer_ptr(&b), buffer_len(&b)); + buffer_free(&b); + + /* send */ + packet_send(); + packet_write_wait(); + return 1; +} + +void +ssh_userauth2(const char *server_user, char *host) +{ + int type; + int plen; + int sent; + unsigned int dlen; + int partial; + int i = 0; + char *auths; + char *service = "ssh-connection"; /* service name */ + + debug("send SSH2_MSG_SERVICE_REQUEST"); + packet_start(SSH2_MSG_SERVICE_REQUEST); + packet_put_cstring("ssh-userauth"); + packet_send(); + packet_write_wait(); + + type = packet_read(&plen); + if (type != SSH2_MSG_SERVICE_ACCEPT) { + fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); + } + if (packet_remaining() > 0) { + char *reply = packet_get_string(&plen); + debug("service_accept: %s", reply); + xfree(reply); + } else { + /* payload empty for ssh-2.0.13 ?? */ + debug("buggy server: service_accept w/o service"); + } + packet_done(); + debug("got SSH2_MSG_SERVICE_ACCEPT"); + + /* INITIAL request for auth */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(server_user); + packet_put_cstring(service); + packet_put_cstring("none"); + packet_send(); + packet_write_wait(); + + for (;;) { + sent = 0; + type = packet_read(&plen); + if (type == SSH2_MSG_USERAUTH_SUCCESS) + break; + if (type != SSH2_MSG_USERAUTH_FAILURE) + fatal("access denied: %d", type); + /* SSH2_MSG_USERAUTH_FAILURE means: try again */ + auths = packet_get_string(&dlen); + debug("authentications that can continue: %s", auths); + partial = packet_get_char(); + packet_done(); + if (partial) + debug("partial success"); + if (options.dsa_authentication && + strstr(auths, "publickey") != NULL) { + while (i < options.num_identity_files2) { + sent = ssh2_try_pubkey( + options.identity_files2[i++], + server_user, host, service); + if (sent) + break; + } + } + if (!sent) { + if (options.password_authentication && + !options.batch_mode && + strstr(auths, "password") != NULL) { + sent = ssh2_try_passwd(server_user, host, service); + } + } + if (!sent) + fatal("Permission denied (%s).", auths); + xfree(auths); + } + packet_done(); + debug("ssh-userauth2 successfull"); +} diff --git a/lib/libxpg4/fakelib.c b/lib/libxpg4/fakelib.c new file mode 100644 index 000000000000..efec8b9cf06f --- /dev/null +++ b/lib/libxpg4/fakelib.c @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +static int ___fake_library___; diff --git a/release/picobsd/mfs_tree/etc/login.conf b/release/picobsd/mfs_tree/etc/login.conf new file mode 100644 index 000000000000..60e50f4c03bf --- /dev/null +++ b/release/picobsd/mfs_tree/etc/login.conf @@ -0,0 +1,62 @@ +# $FreeBSD$ + +# Authentication methods + +auth-defaults:\ + :auth=krb_skey_or_passwd,passwd,kerberos,skey: + +auth-root-defaults:\ + :auth-login=krb_skey_or_passwd,passwd,kerberos,skey:\ + :auth-rlogin=krb_or_skey,kerberos,skey: +auth-ftp-defaults:\ + :auth=skey_or_pwd,passwd,skey: +# Example defaults +default:\ + :cputime=infinity:\ + :datasize-cur=22M:\ + :stacksize-cur=8M:\ + :memorylocked-cur=10M:\ + :memoryuse-cur=30M:\ + :filesize=infinity:\ + :coredumpsize=0:\ + :maxproc-cur=64:\ + :openfiles-cur=64:\ + :priority=0:\ + :requirehome@:\ + :umask=022:\ + :tc=auth-defaults: + +# root - fallback for root logins +root:\ + :path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\ + :cputime=infinity:\ + :datasize=infinity:\ + :stacksize=infinity:\ + :memorylocked=infinity:\ + :memoryuse=infinity:\ + :filesize=infinity:\ + :coredumpsize=0:\ + :openfiles=infinity:\ + :maxproc=infinity:\ + :memoryuse-cur=32M:\ + :maxproc-cur=64:\ + :openfiles-cur=1024:\ + :priority=0:\ + :requirehome@:\ + :umask=022:\ + :tc=auth-root-defaults: +# Settings used by /etc/rc +daemon:\ + :coredumpsize@:\ + :coredumpsize-cur=0:\ + :datasize=infinity:\ + :datasize-cur@:\ + :maxproc=512:\ + :maxproc-cur@:\ + :memoryuse-cur=64M:\ + :memorylocked-cur=64M:\ + :openfiles=1024:\ + :openfiles-cur@:\ + :stacksize=16M:\ + :stacksize-cur@:\ + :tc=default: diff --git a/share/doc/papers/jail/Makefile b/share/doc/papers/jail/Makefile new file mode 100644 index 000000000000..174af30c374a --- /dev/null +++ b/share/doc/papers/jail/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ +PRINTERDEVICE=ps +NODOCCOMPRESS=1 +VOLUME= papers +DOC= jail +SRCS= paper.ms +MACROS= -ms -U +OBJS= implementation.ms mgt.ms future.ms + +.include <bsd.doc.mk> diff --git a/share/doc/papers/jail/future.ms b/share/doc/papers/jail/future.ms new file mode 100644 index 000000000000..01c325d4d19c --- /dev/null +++ b/share/doc/papers/jail/future.ms @@ -0,0 +1,104 @@ +.\" +.\" $FreeBSD$ +.\" +.NH +Future Directions +.PP +The jail facility has already been deployed in numerous capacities and +a few opportunities for improvement have manifested themselves. +.NH 2 +Improved Virtualisation +.PP +As it stands, the jail code provides a strict subset of system resources +to the jail environment, based on access to processes, files, network +resources, and privileged services. +Virtualisation, or making the jail environments appear to be fully +functional FreeBSD systems, allows maximum application support and the +ability to offer a wide range of services within a jail environment. +However, there are a number of limitations on the degree of virtualisation +in the current code, and removing these limitations will enhance the +ability to offer services in a jail environment. +Two areas that deserve greater attention are the virtualisation of +network resources, and management of scheduling resources. +.PP +Currently, a single IP address may be allocated to each jail, and all +communication from the jail is limited to that IP address. +In particular, these addresses are IPv4 addresses. +There has been substantial interest in improving interface virtualisation, +allowing one or more addresses to be assigned to an interface, and +removing the requirement that the address be an IPv4 address, allowing +the use of IPv6. +Also, access to raw sockets is currently prohibited, as the current +implementation of raw sockets allows access to raw IP packets associated +with all interfaces. +Limiting the scope of the raw socket would allow its safe use within +a jail, re-enabling support for ping, and other network debugging and +evaluation tools. +.PP +Another area of great interest to the current consumers of the jail code +is the ability to limit the impact of one jail on the CPU resources +available for other jails. +Specifically, this would require that the jail of a process play a rule in +its scheduling parameters. +Prior work in the area of lottery scheduling, currently available as +patches on FreeBSD 2.2.x, might be leveraged to allow some degree of +partitioning between jail environments \s-2[LOTTERY1] [LOTTERY2]\s+2. +However, as the current scheduling mechanism is targeted at time +sharing, and FreeBSD does not currently support real time preemption +of processes in kernel, complete partitioning is not possible within the +current framework. +.NH 2 +Improved Management +.PP +Management of jail environments is currently somewhat ad hoc--creating +and starting jails is a well-documented procedure, but day-to-day +management of jails, as well as special case procedures such as shutdown, +are not well analysed and documented. +The current kernel process management infrastructure does not have the +ability to manage pools of processes in a jail-centric way. +For example, it is possible to, within a jail, deliver a signal to all +processes in a jail, but it is not possibly to atomically target all +processes within a jail from outside of the jail. +If the jail code is to effectively limit the behaviour of a jail, the +ability to shut it down cleanly is paramount. +Similarly, shutting down a jail cleanly from within is also not well +defined, the traditional shutdown utilities having been written with +a host environment in mind. +This suggests a number of improvements, both in the kernel and in the +user-land utility set. +.PP +First, the ability to address kernel-centric management mechanisms at +jails is important. +One way in which this might be done is to assign a unique jail id, not +unlike a process id or process group id, at jail creation time. +A new jailkill() syscall would permit the direction of signals to +specific jailids, allowing for the effective termination of all processes +in the jail. +A unique jailid could also supplant the hostname as the unique +identifier for a jail, allowing the hostname to be changed by the +processes in the jail without interfering with jail management. +.PP +More carefully defining the user-land semantics of a jail during startup +and shutdown is also important. +The traditional FreeBSD environment makes use of an init process to +bring the system up during the boot process, and to assist in shutdown. +A similar technique might be used for jail, in effect a jailinit, +formulated to handle the clean startup and shutdown, including calling +out to jail-local /etc/rc.shutdown, and other useful shutdown functions. +A jailinit would also present a central location for delivering +management requests to within a jail from the host environment, allowing +the host environment to request the shutdown of the jail cleanly, before +resorting to terminating processes, in the same style as the host +environment shutting down before killing all processes and halting the +kernel. +.PP +Improvements in the host environment would also assist in improving +jail management, possibly including automated runtime jail management tools, +tools to more easily construct the per-jail file system area, and +include jail shutdown as part of normal system shutdown. +.PP +These improvements in the jail framework would improve both raw +functionality and usability from a management perspective. +The jail code has raised significant interest in the FreeBSD community, +and it is hoped that this type of improved functionality will be +available in upcoming releases of FreeBSD. diff --git a/share/doc/papers/jail/implementation.ms b/share/doc/papers/jail/implementation.ms new file mode 100644 index 000000000000..eafc8f25c9c7 --- /dev/null +++ b/share/doc/papers/jail/implementation.ms @@ -0,0 +1,126 @@ +.\" +.\" $FreeBSD$ +.\" +.NH +Implementation jail in the FreeBSD kernel. +.NH 2 +The jail(2) system call, allocation, refcounting and deallocation of +\fCstruct prison\fP. +.PP +The jail(2) system call is implemented as a non-optional system call +in FreeBSD. Other system calls are controlled by compile time options +in the kernel configuration file, but due to the minute footprint of +the jail implementation, it was decided to make it a standard +facility in FreeBSD. +.PP +The implementation of the system call is straightforward: a data structure +is allocated and populated with the arguments provided. The data structure +is attached to the current process' \fCstruct proc\fP, its reference count +set to one and a call to the +chroot(2) syscall implementation completes the task. +.PP +Hooks in the code implementing process creation and destruction maintains +the reference count on the data structure and free it when the last reference +is lost. +Any new process created by a process in a jail will inherit a reference +to the jail, which effectively puts the new process in the same jail. +.PP +There is no way to modify the contents of the data structure describing +the jail after its creation, and no way to attach a process to an existing +jail if it was not created from the inside that jail. +.NH 2 +Fortification of the chroot(2) facility for filesystem name scoping. +.PP +A number of ways to escape the confines of a chroot(2)-created subscope +of the filesystem view have been identified over the years. +chroot(2) was never intended to be security mechanism as such, but even +then the ftp daemon largely depended on the security provided by +chroot(2) to provide the ``anonymous ftp'' access method. +.PP +Three classes of escape routes existed: recursive chroot(2) escapes, +``..'' based escapes and fchdir(2) based escapes. +All of these exploited the fact that chroot(2) didn't try sufficiently +hard to enforce the new root directory. +.PP +New code were added to detect and thwart these escapes, amongst +other things by tracking the directory of the first level of chroot(2) +experienced by a process and refusing backwards traversal across +this directory, as well as additional code to refuse chroot(2) if +file-descriptors were open referencing directories. +.NH 2 +Restriction of process visibility and interaction. +.PP +A macro was already in available in the kernel to determine if one process +could affect another process. This macro did the rather complex checking +of uid and gid values. It was felt that the complexity of the macro were +approaching the lower edge of IOCCC entrance criteria, and it was therefore +converted to a proper function named \fCp_trespass(p1, p2)\fP which does +all the previous checks and additionally checks the jail aspect of the access. +The check is implemented such that access fails if the origin process is jailed +but the target process is not in the same jail. +.PP +Process visibility is provided through two mechanisms in FreeBSD, +the \fCprocfs\fP file system and a sub-tree of the \fCsysctl\fP tree. +Both of these were modified to report only the processes in the same +jail to a jailed process. +.NH 2 +Restriction to one IP number. +.PP +Restricting TCP and UDP access to just one IP number was done almost +entirely in the code which manages ``protocol control blocks''. +When a jailed process binds to a socket, the IP number provided by +the process will not be used, instead the pre-configured IP number of +the jail is used. +.PP +BSD based TCP/IP network stacks sport a special interface, the loop-back +interface, which has the ``magic'' IP number 127.0.0.1. +This is often used by processes to contact servers on the local machine, +and consequently special handling for jails were needed. +To handle this case it was necessary to also intercept and modify the +behaviour of connection establishment, and when the 127.0.0.1 address +were seen from a jailed process, substitute the jails configured IP number. +.PP +Finally the APIs through which the network configuration and connection +state may be queried were modified to report only information relevant +to the configured IP number of a jailed process. +.NH 2 +Adding jail awareness to selected device drivers. +.PP +A couple of device drivers needed to be taught about jails, the ``pty'' +driver is one of them. The pty driver provides ``virtual terminals'' to +services like telnet, ssh, rlogin and X11 terminal window programs. +Therefore jails need access to the pty driver, and code had to be added +to enforce that a particular virtual terminal were not accessed from more +than one jail at the same time. +.NH 2 +General restriction of super-users powers for jailed super-users. +.PP +This item proved to be the simplest but most tedious to implement. +Tedious because a manual review of all places where the kernel allowed +the super user special powers were called for, +simple because very few places were required to let a jailed root through. +Of the approximately 260 checks in the FreeBSD 4.0 kernel, only +about 35 will let a jailed root through. +.PP +Since the default is for jailed roots to not receive privilege, new +code or drivers in the FreeBSD kernel are automatically jail-aware: they +will refuse jailed roots privilege. +The other part of this protection comes from the fact that a jailed +root cannot create new device nodes with the mknod(2) systemcall, so +unless the machine administrator creates device nodes for a particular +device inside the jails filesystem tree, the driver in effect does +not exist in the jail. +.PP +As a side-effect of this work the suser(9) API were cleaned up and +extended to cater for not only the jail facility, but also to make room +for future partitioning facilities. +.NH 2 +Implementation statistics +.PP +The change of the suser(9) API modified approx 350 source lines +distributed over approx. 100 source files. The vast majority of +these changes were generated automatically with a script. +.PP +The implementation of the jail facility added approx 200 lines of +code in total, distributed over approx. 50 files. and about 200 lines +in two new kernel files. diff --git a/share/doc/papers/jail/jail01.eps b/share/doc/papers/jail/jail01.eps new file mode 100644 index 000000000000..ffcfa30386f1 --- /dev/null +++ b/share/doc/papers/jail/jail01.eps @@ -0,0 +1,234 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: jail01.eps +%%Creator: fig2dev Version 3.2 Patchlevel 1 +%%CreationDate: Fri Mar 24 20:37:59 2000 +%%For: $FreeBSD$ +%%Orientation: Portrait +%%BoundingBox: 0 0 425 250 +%%Pages: 0 +%%BeginSetup +%%EndSetup +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +-117.0 298.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit +n -1000 5962 m -1000 -1000 l 10022 -1000 l 10022 5962 l cp clip + 0.06000 0.06000 sc +/Courier-BoldOblique ff 180.00 scf sf +7725 3600 m +gs 1 -1 sc (10.0.0.2) dup sw pop neg 0 rm col0 sh gr +% Polyline +15.000 slw +n 9000 3300 m 9000 4275 l gs col0 s gr +% Polyline +2 slc +n 7875 3225 m 7800 3225 l gs col0 s gr +% Polyline +0 slc +n 7875 4125 m 7800 4125 l gs col0 s gr +% Polyline +n 7875 3225 m 7875 4425 l gs col0 s gr +% Polyline +n 7875 3825 m 7800 3825 l gs col0 s gr +% Polyline +n 7875 3525 m 7800 3525 l gs col0 s gr +% Polyline +n 8175 3825 m 7875 3825 l gs col0 s gr +% Polyline +2 slc +n 7875 4425 m 7800 4425 l gs col0 s gr +/Courier-Bold ff 180.00 scf sf +8700 3900 m +gs 1 -1 sc (fxp0) dup sw pop neg 0 rm col0 sh gr +% Polyline +0 slc +7.500 slw +n 2925 1425 m 3075 1425 l gs col0 s gr +% Polyline +15.000 slw +n 2475 1350 m 2472 1347 l 2465 1342 l 2453 1334 l 2438 1323 l 2420 1311 l + 2401 1299 l 2383 1289 l 2366 1281 l 2351 1275 l 2338 1274 l + 2325 1275 l 2314 1279 l 2303 1285 l 2291 1293 l 2278 1303 l + 2264 1314 l 2250 1326 l 2236 1339 l 2222 1353 l 2209 1366 l + 2198 1379 l 2188 1391 l 2181 1403 l 2177 1414 l 2175 1425 l + 2177 1436 l 2181 1447 l 2188 1459 l 2198 1471 l 2209 1484 l + 2222 1497 l 2236 1511 l 2250 1524 l 2264 1536 l 2278 1547 l + 2291 1557 l 2303 1565 l 2314 1571 l 2325 1575 l 2338 1576 l + 2351 1575 l 2366 1569 l 2383 1561 l 2401 1551 l 2420 1539 l + 2438 1527 l 2453 1516 l 2465 1508 l 2472 1503 l 2475 1500 l gs col0 s gr +/Courier-Bold ff 180.00 scf sf +2550 1500 m +gs 1 -1 sc (lo0) col0 sh gr +/Courier-BoldOblique ff 180.00 scf sf +3075 1500 m +gs 1 -1 sc (127.0.0.1) col0 sh gr +% Polyline +7.500 slw +n 2100 3525 m 2250 3525 l gs col0 s gr +% Polyline +n 2550 2100 m 2250 2400 l 2250 4500 l 2550 4800 l gs col0 s gr +/Courier-Bold ff 180.00 scf sf +1950 3600 m +gs 1 -1 sc (/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 3900 m +gs 1 -1 sc (jail_1/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 4200 m +gs 1 -1 sc (jail_2/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 4500 m +gs 1 -1 sc (jail_3/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 2400 m +gs 1 -1 sc (dev/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 2700 m +gs 1 -1 sc (etc/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 3000 m +gs 1 -1 sc (usr/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 3300 m +gs 1 -1 sc (var/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +2550 3600 m +gs 1 -1 sc (home/) col0 sh gr +% Polyline +n 3375 3825 m 3900 3825 l 4950 1800 l 5100 1800 l gs col0 s gr +% Polyline +n 3375 4125 m 3900 4125 l 4950 3900 l 5100 3900 l gs col0 s gr +% Polyline +n 5400 900 m 5100 1200 l 5100 2400 l 5400 2700 l gs col0 s gr +% Polyline +n 5400 3000 m 5100 3300 l 5100 4500 l 5400 4800 l gs col0 s gr +% Polyline +n 4650 825 m 4650 2775 l 6675 2775 l 6675 3375 l 7950 3375 l 7950 825 l + cp gs col0 s gr +% Polyline +n 4650 2775 m 4650 4950 l 6300 4950 l 6300 3675 l 7950 3675 l 7950 3375 l + 6675 3375 l 6675 2775 l cp gs col0 s gr +/Courier-Bold ff 180.00 scf sf +5400 1200 m +gs 1 -1 sc (dev/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 1500 m +gs 1 -1 sc (etc/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 1800 m +gs 1 -1 sc (usr/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 2100 m +gs 1 -1 sc (var/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 2400 m +gs 1 -1 sc (home/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 3300 m +gs 1 -1 sc (dev/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 3600 m +gs 1 -1 sc (etc/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 3900 m +gs 1 -1 sc (usr/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 4200 m +gs 1 -1 sc (var/) col0 sh gr +/Courier-Bold ff 180.00 scf sf +5400 4500 m +gs 1 -1 sc (home/) col0 sh gr +/Courier-BoldOblique ff 180.00 scf sf +7725 3300 m +gs 1 -1 sc (10.0.0.1) dup sw pop neg 0 rm col0 sh gr +/Courier-BoldOblique ff 180.00 scf sf +7725 4500 m +gs 1 -1 sc (10.0.0.5) dup sw pop neg 0 rm col0 sh gr +/Courier-BoldOblique ff 180.00 scf sf +7725 4200 m +gs 1 -1 sc (10.0.0.4) dup sw pop neg 0 rm col0 sh gr +/Courier-BoldOblique ff 180.00 scf sf +7725 3900 m +gs 1 -1 sc (10.0.0.3) dup sw pop neg 0 rm col0 sh gr +% Polyline +15.000 slw +n 9000 3825 m 8775 3825 l gs col0 s gr +$F2psEnd +rs diff --git a/share/doc/papers/jail/jail01.fig b/share/doc/papers/jail/jail01.fig new file mode 100644 index 000000000000..d4ef1655e195 --- /dev/null +++ b/share/doc/papers/jail/jail01.fig @@ -0,0 +1,86 @@ +#FIG 3.2 +# $FreeBSD$ +Landscape +Center +Inches +A4 +100.00 +Single +-2 +1200 2 +6 7725 3150 9075 4500 +6 8700 3225 9075 4350 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 9000 3825 8775 3825 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 9000 3300 9000 4275 +-6 +2 1 0 2 0 7 100 0 -1 0.000 0 2 -1 0 0 2 + 7875 3225 7800 3225 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 7875 4125 7800 4125 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 7875 3225 7875 4425 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 7875 3825 7800 3825 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 7875 3525 7800 3525 +2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 8175 3825 7875 3825 +2 1 0 2 0 7 100 0 -1 0.000 0 2 -1 0 0 2 + 7875 4425 7800 4425 +4 2 0 100 0 14 12 0.0000 4 180 420 8700 3900 fxp0\001 +-6 +6 2100 1200 4050 1650 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 2925 1425 3075 1425 +3 2 0 2 0 7 100 0 -1 0.000 0 0 0 5 + 2475 1350 2325 1275 2175 1425 2325 1575 2475 1500 + 0.000 -1.000 -1.000 -1.000 0.000 +4 0 0 100 0 14 12 0.0000 4 135 315 2550 1500 lo0\001 +4 0 0 100 0 15 12 0.0000 4 135 945 3075 1500 127.0.0.1\001 +-6 +6 1950 2100 3300 4800 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 + 2100 3525 2250 3525 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 + 2550 2100 2250 2400 2250 4500 2550 4800 +4 0 0 100 0 14 12 0.0000 4 150 105 1950 3600 /\001 +4 0 0 100 0 14 12 0.0000 4 180 735 2550 3900 jail_1/\001 +4 0 0 100 0 14 12 0.0000 4 180 735 2550 4200 jail_2/\001 +4 0 0 100 0 14 12 0.0000 4 180 735 2550 4500 jail_3/\001 +4 0 0 100 0 14 12 0.0000 4 165 420 2550 2400 dev/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 2550 2700 etc/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 2550 3000 usr/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 2550 3300 var/\001 +4 0 0 100 0 14 12 0.0000 4 165 525 2550 3600 home/\001 +-6 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 + 3375 3825 3900 3825 4950 1800 5100 1800 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 + 3375 4125 3900 4125 4950 3900 5100 3900 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 + 5400 900 5100 1200 5100 2400 5400 2700 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 + 5400 3000 5100 3300 5100 4500 5400 4800 +2 3 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 7 + 4650 825 4650 2775 6675 2775 6675 3375 7950 3375 7950 825 + 4650 825 +2 3 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 9 + 4650 2775 4650 4950 6300 4950 6300 3675 7950 3675 7950 3375 + 6675 3375 6675 2775 4650 2775 +4 0 0 100 0 14 12 0.0000 4 165 420 5400 1200 dev/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 1500 etc/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 1800 usr/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 2100 var/\001 +4 0 0 100 0 14 12 0.0000 4 165 525 5400 2400 home/\001 +4 0 0 100 0 14 12 0.0000 4 165 420 5400 3300 dev/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 3600 etc/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 3900 usr/\001 +4 0 0 100 0 14 12 0.0000 4 150 420 5400 4200 var/\001 +4 0 0 100 0 14 12 0.0000 4 165 525 5400 4500 home/\001 +4 2 0 100 0 15 12 0.0000 4 135 840 7725 3300 10.0.0.1\001 +4 2 0 100 0 15 12 0.0000 4 135 840 7725 4500 10.0.0.5\001 +4 2 0 100 0 15 12 0.0000 4 135 840 7725 4200 10.0.0.4\001 +4 2 0 100 0 15 12 0.0000 4 135 840 7725 3900 10.0.0.3\001 +4 2 0 100 0 15 12 0.0000 4 135 840 7725 3600 10.0.0.2\001 diff --git a/share/doc/papers/jail/mgt.ms b/share/doc/papers/jail/mgt.ms new file mode 100644 index 000000000000..b9b5b317f82b --- /dev/null +++ b/share/doc/papers/jail/mgt.ms @@ -0,0 +1,218 @@ +.\" +.\" $FreeBSD$ +.\" +.NH +Managing Jails and the Jail File System Environment +.NH 2 +Creating a Jail Environment +.PP +While the jail(2) call could be used in a number of ways, the expected +configuration creates a complete FreeBSD installation for each jail. +This includes copies of all relevant system binaries, data files, and its +own \fC/etc\fP directory. +Such a configuration maximises the independence of various jails, +and reduces the chances of interference between jails being possible, +especially when it is desirable to provide root access within a jail to +a less trusted user. +.PP +On a box making use of the jail facility, we refer to two types of +environment: the host environment, and the jail environment. +The host environment is the real operating system environment, which is +used to configure interfaces, and start up the jails. +There are then one or more jail environments, effectively virtual +FreeBSD machines. +When configuring Jail for use, it is necessary to configure both the +host and jail environments to prevent overlap. +.PP +As jailed virtual machines are generally bound to an IP address configured +using the normal IP alias mechanism, those jail IP addresses are also +accessible to host environment applications to use. +If the accessibility of some host applications in the jail environment is +not desirable, it is necessary to configure those applications to only +listen on appropriate addresses. +.PP +In most of the production environments where jail is currently in use, +one IP address is allocated to the host environment, and then a number +are allocated to jail boxes, with each jail box receiving a unique IP. +In this situation, it is sufficient to configure the networking applications +on the host to listen only on the host IP. +Generally, this consists of specifying the appropriate IP address to be +used by inetd and SSH, and disabling applications that are not capable +of limiting their address scope, such as sendmail, the port mapper, and +syslogd. +Other third party applications that have been installed on the host must also be +configured in this manner, or users connecting to the jailbox will +discover the host environment service, unless the jailbox has +specifically bound a service to that port. +In some situations, this can actually be the desirable behaviour. +.PP +The jail environments must also be custom-configured. +This consists of building and installing a miniature version of the +FreeBSD file system tree off of a subdirectory in the host environment, +usually \fC/usr/jail\fP, or \fC/data/jail\fP, with a subdirectory per jail. +Appropriate instructions for generating this tree are included in the +jail(8) man page, but generally this process may be automated using the +FreeBSD build environment. +.PP +One notable difference from the default FreeBSD install is that only +a limited set of device nodes should be created. +MAKEDEV(8) has been modified to accept a ``jail'' argument that creates +the correct set of nodes. +.PP +To improve storage efficiency, a fair number of the binaries in the system tree +may be deleted, as they are not relevant in a jail environment. +This includes the kernel, boot loader, and related files, as well as +hardware and network configuration tools. +.PP +After the creation of the jail tree, the easiest way to configure it is +to start up the jail in single-user mode. +The sysinstall admin tool may be used to help with the task, although +it is not installed by default as part of the system tree. +These tools should be run in the jail environment, or they will affect +the host environment's configuration. +.DS +.ft C +.ps -2 +# mkdir /data/jail/192.168.11.100/stand +# cp /stand/sysinstall /data/jail/192.168.11.100/stand +# jail /data/jail/192.168.11.100 testhostname 192.168.11.100 \e + /bin/sh +.ps +2 +.R +.DE +.PP +After running the jail command, the shell is now within the jail environment, +and all further commands +will be limited to the scope of the jail until the shell exits. +If the network alias has not yet been configured, then the jail will be +unable to access the network. +.PP +The startup configuration of the jail environment may be configured so +as to quell warnings from services that cannot run in the jail. +Also, any per-system configuration required for a normal FreeBSD system +is also required for each jailbox. +Typically, this includes: +.IP "" 5n +\(bu Create empty /etc/fstab +.IP +\(bu Disable portmapper +.IP +\(bu Run newaliases +.IP +\(bu Disabling interface configuration +.IP +\(bu Configure the resolver +.IP +\(bu Set root password +.IP +\(bu Set timezone +.IP +\(bu Add any local accounts +.IP +\(bu Install any packets +.NH 2 +Starting Jails +.PP +Jails are typically started by executing their /etc/rc script in much +the same manner a shell was started in the previous section. +Before starting the jail, any relevant networking configuration +should also be performed. +Typically, this involves adding an additional IP address to the +appropriate network interface, setting network properties for the +IP address using IP filtering, forwarding, and bandwidth shaping, +and mounting a process file system for the jail, if the ability to +debug processes from within the jail is desired. +.DS +.ft C +.ps -2 +# ifconfig ed0 inet add 192.168.11.100 netmask 255.255.255.255 +# mount -t procfs proc /data/jail/192.168.11.100/proc +# jail /data/jail/192.168.11.100 testhostname 192.168.11.100 \e + /bin/sh /etc/rc +.ps +2 +.ft P +.DE +.PP +A few warnings are generated for sysctl's that are not permitted +to be set within the jail, but the end result is a set of processes +in an isolated process environment, bound to a single IP address. +Normal procedures for accessing a FreeBSD machine apply: telneting in +through the network reveals a telnet prompt, login, and shell. +.DS +.ft C +.ps -2 +% ps ax + PID TT STAT TIME COMMAND + 228 ?? SsJ 0:18.73 syslogd + 247 ?? IsJ 0:00.05 inetd -wW + 249 ?? IsJ 0:28.43 cron + 252 ?? SsJ 0:30.46 sendmail: accepting connections on port 25 + 291 ?? IsJ 0:38.53 /usr/local/sbin/sshd +93694 ?? SJ 0:01.01 sshd: rwatson@ttyp0 (sshd) +93695 p0 SsJ 0:00.06 -csh (csh) +93700 p0 R+J 0:00.00 ps ax +.ps +2 +.ft P +.DE +.PP +It is immediately obvious that the environment is within a jailbox: there +is no init process, no kernel daemons, and a J flag is present beside all +processes indicating the presence of a jail. +.PP +As with any FreeBSD system, accounts may be created and deleted, +mail is delivered, logs are generated, packages may be added, and the +system may be hacked into if configured incorrectly, or running a buggy +version of a piece of software. +However, all of this happens strictly within the scope of the jail. +.NH 2 +Jail Management +.PP +Jail management is an interesting prospect, as there are two perspectives +from which a jail environment may be administered: from within the jail, +and from the host environment. +From within the jail, as described above, the process is remarkably similar +to any regular FreeBSD install, although certain actions are prohibited, +such as mounting file systems, modifying system kernel properties, etc. +The only area that really differs are that of shutting +the system down: the processes within the jail may deliver signals +between them, allowing all processes to be killed, but bringing the +system back up requires intervention from outside of the jailbox. +.PP +From outside of the jail, there are a range of capabilities, as well +as limitations. +The jail environment is, in effect, a subset of the host environment: +the jail file system appears as part of the host file system, and may +be directly modified by processes in the host environment. +Processes within the jail appear in the process listing of the host, +and may likewise be signalled or debugged. +The host process file system makes the hostname of the jail environment +accessible in /proc/procnum/status, allowing utilities in the host +environment to manage processes based on jailname. +However, the default configuration allows privileged processes within +jails to set the hostname of the jail, which makes the status file less +useful from a management perspective if the contents of the jail are +malicious. +To prevent a jail from changing its hostname, the +"jail.set_hostname_allowed" sysctl may be set to 0 prior to starting +any jails. +.PP +One aspect immediately observable in an environment with multiple jails +is that uids and gids are local to each jail environment: the uid associated +with a process in one jail may be for a different user than in another +jail. +This collision of identifiers is only visible in the host environment, +as normally processes from one jail are never visible in an environment +with another scope for user/uid and group/gid mapping. +Managers in the host environment should understand these scoping issues, +or confusion and unintended consequences may result. +.PP +Jailed processes are subject to the normal restrictions present for +any processes, including resource limits, and limits placed by the network +code, including firewall rules. +By specifying firewall rules for the IP address bound to a jail, it is +possible to place connectivity and bandwidth limitations on individual +jails, restricting services that may be consumed or offered. +.PP +Management of jails is an area that will see further improvement in +future versions of FreeBSD. Some of these potential improvements are +discussed later in this paper. diff --git a/share/man/man4/sym.4 b/share/man/man4/sym.4 new file mode 100644 index 000000000000..0c943697f24d --- /dev/null +++ b/share/man/man4/sym.4 @@ -0,0 +1,313 @@ +.\" +.\" Device driver optimized for the Symbios/LSI 53C896/53C895A/53C1010 +.\" PCI SCSI controllers. +.\" +.\" Copyright (C) 1999-2000 Gerard Roudier <groudier@club-internet.fr> +.\" +.\" This driver also supports the following Symbios/LSI PCI SCSI chips: +.\" 53C810A, 53C825A, 53C860, 53C875, 53C876, 53C885, 53C895, +.\" 53C810, 53C815, 53C825 and the 53C1510D is 53C8XX mode. +.\" +.\" +.\" This driver for FreeBSD-CAM is derived from the Linux sym53c8xx driver. +.\" Copyright (C) 1998-1999 Gerard Roudier +.\" +.\" The sym53c8xx driver is derived from the ncr53c8xx driver that had been +.\" a port of the FreeBSD ncr driver to Linux-1.2.13. +.\" +.\" The original ncr driver has been written for 386bsd and FreeBSD by +.\" Wolfgang Stanglmeier <wolf@cologne.de> +.\" Stefan Esser <se@mi.Uni-Koeln.de> +.\" Copyright (C) 1994 Wolfgang Stanglmeier +.\" +.\" The initialization code, and part of the code that addresses +.\" FreeBSD-CAM services is based on the aic7xxx driver for FreeBSD-CAM +.\" written by Justin T. Gibbs. +.\" +.\" Other major contributions: +.\" +.\" NVRAM detection and reading. +.\" Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> +.\" +.\" ---------------------------------------------------------------------------- +.\" +.\" 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. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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$ +.\" +.Dd January 12, 2000 +.Dt SYM 4 i386 +.Os FreeBSD +.Sh NAME +.Nm sym +.Nd NCR/Symbios/LSI Logic 53C8XX PCI SCSI host adapter driver +.Sh SYNOPSIS +For any number of cards: +.Cd device sym +.Pp +To disable PCI parity checking (needed for broken bridges) +.Cd options SYM_SETUP_PCI_PARITY=<boolean> +.Pp +To control driver probing against HVD buses +.Cd options SYM_SETUP_SCSI_DIFF=<bit combination> +.Pp +To control chip attachment balancing between the ncr driver and this driver +.Cd options SYM_SETUP_LP_PROBE_MAP=<bit combination> +.Sh DESCRIPTION +This driver provides support for the Symbios/LSI Logic +.Tn 53C810, +.Tn 53C815, +.Tn 53C825, +.Tn 53C810A, +.Tn 53C825A, +.Tn 53C860, +.Tn 53C875, +.Tn 53C876, +.Tn 53C895, +.Tn 53C895A, +.Tn 53C896, +.Tn 53C897, +.Tn 53C1510D, +and +.Tn 53C1010 +PCI SCSI controllers. +.Pp +Driver features include support for wide SCSI busses and fast10, fast20, +fast40 and fast80-dt synchronous data transfers depending on controller +capabilities. +It also provides generic SCSI features such as tagged command +queuing and auto-request sense. +This driver is configured by default +for a maximum of 446 outstanding commands per bus, 8 LUNs per target +and 64 tagged tasks per LUN. +These numbers are not so much limited by design +as they are considered reasonable values for current SCSI technology. +These values can be increased by changing appropriate +constants in driver header files (not recommended). +.Pp +This driver supports the entire Symbios 53C8XX family of PCI SCSI +controllers. +It also offers the advantage of architectural improvements available +only with newer chips. +.Pp +.Nm +notably handles phase mismatch from SCRIPTS for the 53C896, 53C895A, +and 53C1010 cores. +As a result, it guarantees that no more than 1 interrupt +per IO completion is delivered to the CPU, and that the SCRIPTS processor +is never stalled waiting for CPU attention in normal situations. +.Pp +.Nm +also uses LOAD/STORE SCRIPTS instructions for chips that support it. +Only the early 810, 815 and 825 NCR chips do not support LOAD/STORE. +Use of LOAD/STORE instead of MEMORY MOVE allows SCRIPTS to access IO +registers internal to the chip (no external PCI cycles). +As a result, the driver guarantees that no PCI self-mastering will occur +for chips that support LOAD/STORE. +.Pp +LOAD/STORE instructions are also faster than MEMORY MOVE because +they do not involve the chip DMA FIFO and are coded on 2 DWORDs +instead of 3. +.Pp +For the early NCR 810, 815 and 825 chips, the driver uses a separate +SCRIPTS set that uses MEMORY MOVE instructions for data movements. +This is because LOAD/STORE are not supported by these chips. +.Pp +HVD/LVD capable controllers (895, 895A, 896, and 897) report +the actual bus mode in the STEST4 chip IO registers. +This feature +allows the driver to safely probe against bus mode and to set up the chip +accordingly. +By default the driver only supports HVD for these chips. +For other chips that can support HVD but not LVD, the driver has to probe +implementation dependent registers (GPIO) in order to detect HVD bus mode. +Only HVD implementations that conform with Symbios Logic recommendations can +be detected by the driver. +When the +.Ar SYM_SETUP_SCSI_DIFF +kernel option is assigned +a value of 1, the driver will also probe against HVD for 825a, 875, 876 and +885 chips, assuming Symbios Logic compatible implementation of HVD. +.Pp +When the +.Ar SYM_SETUP_PCI_PARITY +is assigned a value of 0, the +driver will not enable PCI parity checking for 53C8XX devices. +PCI parity +checking should not be an option for PCI SCSI controllers, but some +systems have been reported to fail using 53C8XX chips, due to spurious or +permanent PCI parity errors detected. +This option is supplied for +convenience but it is neither recommended nor supported. +.Pp +The generic +.Xr ncr 4 +driver also supports SYM53C8XX based PCI SCSI controllers, +except for the SYM53C1010, which is only supported by the +.Nm +driver. +.Pp +By default, when both the +.Xr ncr 4 +and +.Nm +drivers are configured, the +.Nm +driver takes precedence over the +.Xr ncr 4 +driver. +The user can indicate a balancing of chip types between the two drivers +by defining the +.Ar SYM_SETUP_LP_PROBE_MAP +kernel configuration option as follows: +.Bl -column "Bit " "53C8XXA, 53C8XX, 53C8XX, 53C8XX, 53C8XX, 53C8XX" +.Em Bit Devices to be attached by ncr instead +0x01 53C810a, 53C860 +0x02 53C825a, 53C875, 53C876, 53C885, 53C895 +0x04 53C895a, 53C896, 53C897, 53C1510d +0x40 53C810, 53C815, 53C825 +.El +.Pp +For example, if +.Ar SYM_SETUP_LP_PROBE_MAP +is supplied with the value 0x41, the +.Xr ncr 4 +driver will attach to 53C810, 53C815, 53C825, 53C810a, and 53C860 based +controllers, +and the +.Nm +driver will attach to all other 53C8XX based controllers. +.Pp +When only the +.Nm +driver is configured, the +.Ar SYM_SETUP_LP_PROBE_MAP +option has no effect. +Thus, in this case, the +.Nm +driver will attach all 53C8XX based controllers present in the system. +.Pp +This driver offers other options +that are not currently exported to the user. +They are defined and documented in the +.Pa sym_conf.h +driver file. +Changing these options is not recommended unless absolutely necessary. +Some of these +options are planned to be exported through +.Xr sysctl 3 +or an equivalent mechanism +in a future driver releases and therefore, +no compatibility is guaranteed. +.Pp +At initialization, the driver tries to detect and read user settings from +controller NVRAM. +The Symbios/Logic NVRAM layout and the Tekram NVRAM +layout are currently supported. +If the reading of the NVRAM succeeds, the +following settings are taken into account and reported to CAM: +.Pp +.Bl -column "SCSI parity checking " "Symbios " "Tekram" +.Em Host settings Symbios Tekram +SCSI parity checking Y N +Host SCSI ident Y Y +Verbose messages Y N +Scan targets hi-lo Y N +Avoid SCSI bus reset Y N +.Pp +.El +.Bl -column "Synchronous period " "Symbios " "Tekram" +.Em Device settings Symbios Tekram +Synchronous period Y Y +SCSI bus width Y Y +Queue tag enable Y Y +Number of tags NA Y +Disconnect enable Y Y +Scan at boot time Y N +Scan LUN Y N +.El +.Pp +Devices that are configured as disabled for 'scan' in the NVRAM are not +reported to CAM at system start-up. +They can be discovered later using +the +.Ql camcontrol rescan +command. +.Pp +The table below summarizes the main features and capabilities of the +NCR/Symbios/LSI Logic 53C8XX family of PCI SCSI controllers. +.Pp +.Bl -column sym53c1510d "Sync " "Width " "SRAM " "PCI64" +.Em Chip Sync Width SRAM PCI64 Supported +sym53c810 10MHz 8Bit N N Y +sym53c810a 10MHz 8Bit N N Y +sym53c815 10MHz 8Bit N N Y +sym53c825 10MHz 16Bit N N Y +sym53c825a 10MHz 16Bit 4KB N Y +sym53c860 20MHz 8Bit N N Y +sym53c875 20MHz 16Bit 4KB N Y +sym53c876 20MHz 16Bit 4KB N Y +sym53c885 20MHz 16Bit 4KB N Y +sym53c895 40MHz 16Bit 4KB N Y +sym53c895A 40MHz 16Bit 8KB N Y +sym53c896 40MHz 16Bit 8KB Y Y +sym53c897 40MHz 16Bit 8KB Y Y +sym53c1510D 40MHz 16Bit 4KB Y Y +sym53c1010 80MHz 16Bit 8KB Y Y +.El +.Pp +.Sh BUGS +No known bugs. +.Sh SEE ALSO +.Xr cd 4 , +.Xr da 4 , +.Xr ncr 4 , +.Xr sa 4 , +.Xr scsi 4 , +.Xr camcontrol 8 +.Sh AUTHORS +The +.Nm +driver was written by +.An Gerard Roudier +and is derived from the +Linux sym53c8xx driver from the same author. +The sym53c8xx driver is derived from the ncr53c8xx driver, +which was ported from the +.Fx +.Xr ncr 4 +driver to Linux-1.2.13. +The original +.Xr ncr 4 +driver was written for 386BSD and +.Fx +by +.An Wolfgang Stanglmeier +and +.An Stefan Esser . +.Sh HISTORY +The +.Nm +driver appeared in +.Fx 4.0 . diff --git a/sys/alpha/pci/t2var.h b/sys/alpha/pci/t2var.h new file mode 100644 index 000000000000..ef47d0b95d33 --- /dev/null +++ b/sys/alpha/pci/t2var.h @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2000 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$ + */ + +extern void t2_init(void); diff --git a/sys/boot/ficl/softwords/string.fr b/sys/boot/ficl/softwords/string.fr new file mode 100644 index 000000000000..a78f4eadb0bd --- /dev/null +++ b/sys/boot/ficl/softwords/string.fr @@ -0,0 +1,148 @@ +\ ** ficl/softwords/string.fr +\ A useful dynamic string class +\ John Sadler 14 Sep 1998 +\ +\ ** C - S T R I N G +\ counted string, buffer sized dynamically +\ Creation example: +\ c-string --> new str +\ s" arf arf!!" str --> set +\ s" woof woof woof " str --> cat +\ str --> type cr +\ +\ $FreeBSD$ + +.( loading ficl string class ) cr +also oop definitions + +object subclass c-string + c-4byte obj: .count + c-4byte obj: .buflen + c-ptr obj: .buf + 64 constant min-buf + + : get-count ( 2this -- count ) c-string => .count c-4byte => get ; + : set-count ( count 2this -- ) c-string => .count c-4byte => set ; + + : ?empty ( 2this -- flag ) --> get-count 0= ; + + : get-buflen ( 2this -- len ) c-string => .buflen c-4byte => get ; + : set-buflen ( len 2this -- ) c-string => .buflen c-4byte => set ; + + : get-buf ( 2this -- ptr ) c-string => .buf c-ptr => get-ptr ; + : set-buf { ptr len 2this -- } + ptr 2this c-string => .buf c-ptr => set-ptr + len 2this c-string => set-buflen + ; + + \ set buffer to null and buflen to zero + : clr-buf ( 2this -- ) + 0 0 2over c-string => set-buf + 0 -rot c-string => set-count + ; + + \ free the buffer if there is one, set buf pointer to null + : free-buf { 2this -- } + 2this c-string => get-buf + ?dup if + free + abort" c-string free failed" + 2this c-string => clr-buf + endif + ; + + \ guarantee buffer is large enough to hold size chars + : size-buf { size 2this -- } + size 0< abort" need positive size for size-buf" + size 0= if + 2this --> free-buf exit + endif + + \ force buflen to be a positive multiple of min-buf chars + c-string => min-buf size over / 1+ * chars to size + + \ if buffer is null, allocate one, else resize it + 2this --> get-buflen 0= + if + size allocate + abort" out of memory" + size 2this --> set-buf + size 2this --> set-buflen + exit + endif + + size 2this --> get-buflen > if + 2this --> get-buf size resize + abort" out of memory" + size 2this --> set-buf + endif + ; + + : set { c-addr u 2this -- } + u 2this --> size-buf + u 2this --> set-count + c-addr 2this --> get-buf u move + ; + + : get { 2this -- c-addr u } + 2this --> get-buf + 2this --> get-count + ; + + \ append string to existing one + : cat { c-addr u 2this -- } + 2this --> get-count u + dup >r + 2this --> size-buf + c-addr 2this --> get-buf 2this --> get-count + u move + r> 2this --> set-count + ; + + : type { 2this -- } + 2this --> ?empty if ." (empty) " exit endif + 2this --> .buf --> get-ptr + 2this --> .count --> get + type + ; + + : compare ( 2string 2this -- n ) + c-string => get + 2swap + c-string => get + 2swap compare + ; + + : hashcode ( 2this -- hashcode ) + c-string => get hash + ; + + \ destructor method (overrides object --> free) + : free ( 2this -- ) 2dup c-string => free-buf object => free ; + +end-class + +c-string subclass c-hashstring + c-2byte obj: .hashcode + + : set-hashcode { 2this -- } + 2this --> super --> hashcode + 2this --> .hashcode --> set + ; + + : get-hashcode ( 2this -- hashcode ) + --> .hashcode --> get + ; + + : set ( c-addr u 2this -- ) + 2swap 2over --> super --> set + --> set-hashcode + ; + + : cat ( c-addr u 2this -- ) + 2swap 2over --> super --> cat + --> set-hashcode + ; + +end-class + +previous definitions + diff --git a/sys/dev/sound/pci/ds1-fw.h b/sys/dev/sound/pci/ds1-fw.h new file mode 100644 index 000000000000..b69e5b4b410e --- /dev/null +++ b/sys/dev/sound/pci/ds1-fw.h @@ -0,0 +1,1578 @@ +/* ============================================================================= + * Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. + * + * Title: + * hwmcode.c + * Desc: + * micro-code for CTRL & DSP + * ============================================================================= + * $FreeBSD$ + */ +#ifndef _HWMCODE_ +#define _HWMCODE_ + +static u_int32_t DspInst[] = { + 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, + 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, + 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, + 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static u_int32_t CntrlInst[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x001A82, 0x032D0D, 0x000810, 0x10043A, + 0x02D38D, 0x000810, 0x18043A, 0x00010D, + 0x020015, 0x0000FD, 0x000020, 0x038860, + 0x039060, 0x038060, 0x038040, 0x038040, + 0x038040, 0x018040, 0x000A7D, 0x038040, + 0x038040, 0x018040, 0x200402, 0x000882, + 0x08001A, 0x000904, 0x015986, 0x000007, + 0x260007, 0x000007, 0x000007, 0x018A06, + 0x000007, 0x030C8D, 0x000810, 0x18043A, + 0x260007, 0x00087D, 0x018042, 0x00160A, + 0x04A206, 0x000007, 0x00218D, 0x000810, + 0x08043A, 0x21C206, 0x000007, 0x0007FD, + 0x018042, 0x08000A, 0x000904, 0x029386, + 0x000195, 0x090D04, 0x000007, 0x000820, + 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD, + 0x032206, 0x018040, 0x000A7D, 0x038042, + 0x13804A, 0x18000A, 0x001820, 0x059060, + 0x058860, 0x018040, 0x0000FD, 0x018042, + 0x70000A, 0x000115, 0x071144, 0x032386, + 0x030000, 0x007020, 0x034A06, 0x018040, + 0x00348D, 0x000810, 0x08043A, 0x21EA06, + 0x000007, 0x02D38D, 0x000810, 0x18043A, + 0x018206, 0x000007, 0x240007, 0x000F8D, + 0x000810, 0x00163A, 0x002402, 0x005C02, + 0x0028FD, 0x000020, 0x018040, 0x08000D, + 0x000815, 0x510984, 0x000007, 0x00004D, + 0x000E5D, 0x000E02, 0x00418D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00008D, + 0x000924, 0x000F02, 0x00458D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x018386, 0x000007, 0x01AA06, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x218086, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x055A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x034986, 0x000007, 0x002104, 0x034986, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x06C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00688D, 0x000810, 0x08043A, 0x288A06, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x060206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x215886, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x212086, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x07DA86, 0x00057D, 0x002820, + 0x03B060, 0x07F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x07FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x008D8D, 0x000810, + 0x08043A, 0x288A06, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x095186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x007FBD, 0x383DC4, + 0x000007, 0x001A7D, 0x001375, 0x018042, + 0x09004A, 0x10000A, 0x0B8D04, 0x139504, + 0x000007, 0x000820, 0x019060, 0x001104, + 0x212086, 0x010040, 0x0017FD, 0x018042, + 0x08000A, 0x000904, 0x212286, 0x000007, + 0x00197D, 0x038042, 0x09804A, 0x10000A, + 0x000924, 0x001664, 0x0011FD, 0x038042, + 0x2B804A, 0x19804A, 0x00008D, 0x218944, + 0x000007, 0x002244, 0x0AE186, 0x000007, + 0x001A64, 0x002A24, 0x00197D, 0x080102, + 0x100122, 0x000820, 0x039060, 0x018040, + 0x003DFD, 0x00008D, 0x000820, 0x018040, + 0x001375, 0x001A7D, 0x010042, 0x09804A, + 0x10000A, 0x00021D, 0x0189E4, 0x2992E4, + 0x309144, 0x000007, 0x00060D, 0x000A15, + 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4, + 0x000464, 0x01B3E4, 0x0232E4, 0x000464, + 0x000464, 0x000464, 0x000464, 0x00040D, + 0x08B1C4, 0x000007, 0x000820, 0x000BF5, + 0x030040, 0x00197D, 0x038042, 0x09804A, + 0x000A24, 0x08000A, 0x080E64, 0x000007, + 0x100122, 0x000820, 0x031060, 0x010040, + 0x0064AC, 0x00027D, 0x000020, 0x018040, + 0x00107D, 0x018042, 0x0011FD, 0x3B804A, + 0x09804A, 0x20000A, 0x000095, 0x1A1144, + 0x00A144, 0x0D2086, 0x00040D, 0x00B984, + 0x0D2186, 0x0018FD, 0x018042, 0x0010FD, + 0x09804A, 0x28000A, 0x000095, 0x010924, + 0x002A64, 0x0D1186, 0x000007, 0x002904, + 0x0D2286, 0x000007, 0x0D2A06, 0x080002, + 0x00008D, 0x00387D, 0x000820, 0x018040, + 0x00127D, 0x018042, 0x10000A, 0x003904, + 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984, + 0x0DA186, 0x000025, 0x0E7A06, 0x00002D, + 0x000015, 0x00082D, 0x02C78D, 0x000820, + 0x0EC206, 0x00000D, 0x7F8035, 0x00B984, + 0x0E7186, 0x400025, 0x00008D, 0x110944, + 0x000007, 0x00018D, 0x109504, 0x000007, + 0x009164, 0x000424, 0x000424, 0x000424, + 0x100102, 0x280002, 0x02C68D, 0x000820, + 0x0EC206, 0x00018D, 0x00042D, 0x00008D, + 0x109504, 0x000007, 0x00020D, 0x109184, + 0x000007, 0x02C70D, 0x000820, 0x00008D, + 0x0038FD, 0x018040, 0x003BFD, 0x001020, + 0x03A860, 0x000815, 0x313184, 0x212184, + 0x000007, 0x03B060, 0x03A060, 0x018040, + 0x0022FD, 0x000095, 0x010924, 0x000424, + 0x000424, 0x001264, 0x100102, 0x000820, + 0x039060, 0x018040, 0x001924, 0x00FB8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x000424, + 0x000424, 0x00117D, 0x018042, 0x08000A, + 0x000A24, 0x280502, 0x280C02, 0x09800D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x0022FD, 0x018042, 0x08000A, 0x000095, + 0x280DC4, 0x011924, 0x00197D, 0x018042, + 0x0011FD, 0x09804A, 0x10000A, 0x0000B5, + 0x113144, 0x0A8D04, 0x000007, 0x080A44, + 0x129504, 0x000007, 0x0023FD, 0x001020, + 0x038040, 0x101244, 0x000007, 0x000820, + 0x039060, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x10FA86, 0x000007, + 0x003BFD, 0x000100, 0x000A10, 0x0B807A, + 0x13804A, 0x090984, 0x000007, 0x000095, + 0x013D04, 0x118086, 0x10000A, 0x100002, + 0x090984, 0x000007, 0x038042, 0x11804A, + 0x090D04, 0x000007, 0x10000A, 0x090D84, + 0x000007, 0x00257D, 0x000820, 0x018040, + 0x00010D, 0x000810, 0x28143A, 0x00127D, + 0x018042, 0x20000A, 0x00197D, 0x018042, + 0x00117D, 0x31804A, 0x10000A, 0x003124, + 0x01280D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x300102, 0x003124, 0x000424, 0x000424, + 0x001224, 0x280502, 0x001A4C, 0x130186, + 0x700002, 0x00002D, 0x030000, 0x00387D, + 0x018042, 0x10000A, 0x132A06, 0x002124, + 0x0000AD, 0x100002, 0x00010D, 0x000924, + 0x006B24, 0x01368D, 0x00397D, 0x000820, + 0x058040, 0x038042, 0x09844A, 0x000606, + 0x08040A, 0x003264, 0x00008D, 0x000A24, + 0x001020, 0x00227D, 0x018040, 0x013C0D, + 0x000810, 0x08043A, 0x29D206, 0x000007, + 0x002820, 0x00207D, 0x018040, 0x00117D, + 0x038042, 0x13804A, 0x33800A, 0x00387D, + 0x018042, 0x08000A, 0x000904, 0x163A86, + 0x000007, 0x00008D, 0x030964, 0x01478D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x380102, + 0x000424, 0x000424, 0x001224, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x14A286, + 0x000007, 0x280502, 0x001A4C, 0x163986, + 0x000007, 0x032164, 0x00632C, 0x003DFD, + 0x018042, 0x08000A, 0x000095, 0x090904, + 0x000007, 0x000820, 0x001A4C, 0x156186, + 0x018040, 0x030000, 0x157A06, 0x002124, + 0x00010D, 0x000924, 0x006B24, 0x015B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x003A64, + 0x000095, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x01628D, 0x000810, 0x08043A, 0x29D206, + 0x000007, 0x14D206, 0x000007, 0x007020, + 0x08010A, 0x10012A, 0x0020FD, 0x038860, + 0x039060, 0x018040, 0x00227D, 0x018042, + 0x003DFD, 0x08000A, 0x31844A, 0x000904, + 0x16D886, 0x18008B, 0x00008D, 0x189904, + 0x00312C, 0x17AA06, 0x000007, 0x00324C, + 0x173386, 0x000007, 0x001904, 0x173086, + 0x000007, 0x000095, 0x199144, 0x00222C, + 0x003124, 0x00636C, 0x000E3D, 0x001375, + 0x000BFD, 0x010042, 0x09804A, 0x10000A, + 0x038AEC, 0x0393EC, 0x00224C, 0x17A986, + 0x000007, 0x00008D, 0x189904, 0x00226C, + 0x00322C, 0x30050A, 0x301DAB, 0x002083, + 0x0018FD, 0x018042, 0x08000A, 0x018924, + 0x300502, 0x001083, 0x001875, 0x010042, + 0x10000A, 0x00008D, 0x010924, 0x001375, + 0x330542, 0x330CCB, 0x332CCB, 0x3334CB, + 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB, + 0x305C8B, 0x006083, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x187A86, 0x000007, + 0x001E2D, 0x0005FD, 0x018042, 0x08000A, + 0x028924, 0x280502, 0x00060D, 0x000810, + 0x280C3A, 0x00008D, 0x000810, 0x28143A, + 0x0A808D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001275, 0x030042, 0x21004A, + 0x00008D, 0x1A0944, 0x000007, 0x01980D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0001F5, 0x030042, 0x0D004A, 0x10000A, + 0x089144, 0x000007, 0x000820, 0x010040, + 0x0025F5, 0x0A3144, 0x000007, 0x000820, + 0x032860, 0x030040, 0x00217D, 0x038042, + 0x0B804A, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00008D, 0x000124, 0x00012C, + 0x000E64, 0x001A64, 0x00636C, 0x08010A, + 0x10012A, 0x000820, 0x031060, 0x030040, + 0x0020FD, 0x018042, 0x08000A, 0x00227D, + 0x018042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00197D, 0x018042, 0x08000A, + 0x0022FD, 0x038042, 0x10000A, 0x000820, + 0x031060, 0x030040, 0x090D04, 0x000007, + 0x000820, 0x030040, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x038042, 0x13804A, 0x19804A, 0x110D04, + 0x198D04, 0x000007, 0x08000A, 0x001020, + 0x031860, 0x030860, 0x030040, 0x00008D, + 0x0B0944, 0x000007, 0x000820, 0x010040, + 0x0005F5, 0x030042, 0x08000A, 0x000820, + 0x010040, 0x0000F5, 0x010042, 0x08000A, + 0x000904, 0x1C6086, 0x001E75, 0x030042, + 0x01044A, 0x000C0A, 0x1C7206, 0x000007, + 0x000402, 0x000C02, 0x00177D, 0x001AF5, + 0x018042, 0x03144A, 0x031C4A, 0x03244A, + 0x032C4A, 0x03344A, 0x033C4A, 0x03444A, + 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD, + 0x030042, 0x0B004A, 0x1B804A, 0x13804A, + 0x20000A, 0x089144, 0x19A144, 0x0389E4, + 0x0399EC, 0x005502, 0x005D0A, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x006502, 0x006D0A, 0x030042, 0x0B004A, + 0x19004A, 0x2B804A, 0x13804A, 0x21804A, + 0x30000A, 0x089144, 0x19A144, 0x2AB144, + 0x0389E4, 0x0399EC, 0x007502, 0x007D0A, + 0x03A9E4, 0x000702, 0x00107D, 0x000415, + 0x018042, 0x08000A, 0x0109E4, 0x000F02, + 0x002AF5, 0x0019FD, 0x010042, 0x09804A, + 0x10000A, 0x000934, 0x001674, 0x0029F5, + 0x010042, 0x10000A, 0x00917C, 0x002075, + 0x010042, 0x08000A, 0x000904, 0x1ED286, + 0x0026F5, 0x0027F5, 0x030042, 0x09004A, + 0x10000A, 0x000A3C, 0x00167C, 0x001A75, + 0x000BFD, 0x010042, 0x51804A, 0x48000A, + 0x160007, 0x001075, 0x010042, 0x282C0A, + 0x281D12, 0x282512, 0x001F32, 0x1E0007, + 0x0E0007, 0x001975, 0x010042, 0x002DF5, + 0x0D004A, 0x10000A, 0x009144, 0x1FB286, + 0x010042, 0x28340A, 0x000E5D, 0x00008D, + 0x000375, 0x000820, 0x010040, 0x05D2F4, + 0x54D104, 0x00735C, 0x205386, 0x000007, + 0x0C0007, 0x080007, 0x0A0007, 0x02040D, + 0x000810, 0x08043A, 0x332206, 0x000007, + 0x205A06, 0x000007, 0x080007, 0x002275, + 0x010042, 0x20000A, 0x002104, 0x212086, + 0x001E2D, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x209286, 0x000007, 0x002010, + 0x30043A, 0x00057D, 0x0180C3, 0x08000A, + 0x028924, 0x280502, 0x280C02, 0x0A810D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x0004FD, 0x018042, 0x70000A, 0x030000, + 0x007020, 0x06FA06, 0x018040, 0x02180D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x218A86, 0x000007, 0x01F206, 0x000007, + 0x000875, 0x0009FD, 0x00010D, 0x220A06, + 0x000295, 0x000B75, 0x00097D, 0x00000D, + 0x000515, 0x010042, 0x18000A, 0x001904, + 0x287886, 0x0006F5, 0x001020, 0x010040, + 0x0004F5, 0x000820, 0x010040, 0x000775, + 0x010042, 0x09804A, 0x10000A, 0x001124, + 0x000904, 0x22BA86, 0x000815, 0x080102, + 0x101204, 0x22DA06, 0x000575, 0x081204, + 0x000007, 0x100102, 0x000575, 0x000425, + 0x021124, 0x100102, 0x000820, 0x031060, + 0x010040, 0x001924, 0x287886, 0x00008D, + 0x000464, 0x009D04, 0x278886, 0x180102, + 0x000575, 0x010042, 0x28040A, 0x00018D, + 0x000924, 0x280D02, 0x00000D, 0x000924, + 0x281502, 0x10000D, 0x000820, 0x0002F5, + 0x010040, 0x200007, 0x001175, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x23C286, + 0x000007, 0x000100, 0x080B20, 0x130B60, + 0x1B0B60, 0x030A60, 0x010040, 0x050042, + 0x3D004A, 0x35004A, 0x2D004A, 0x20000A, + 0x0006F5, 0x010042, 0x28140A, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x24CA86, 0x004015, 0x000095, 0x010D04, + 0x24B886, 0x100022, 0x10002A, 0x24E206, + 0x000007, 0x333104, 0x2AA904, 0x000007, + 0x032124, 0x280502, 0x001124, 0x000424, + 0x000424, 0x003224, 0x00292C, 0x00636C, + 0x25F386, 0x000007, 0x02B164, 0x000464, + 0x000464, 0x00008D, 0x000A64, 0x280D02, + 0x10008D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x00008D, 0x38B904, 0x000007, + 0x03296C, 0x30010A, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x25BA86, 0x000007, + 0x02312C, 0x28050A, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x267A86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x26C086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x26CA86, 0x000007, 0x003124, 0x300502, + 0x003924, 0x300583, 0x000883, 0x0005F5, + 0x010042, 0x28040A, 0x00008D, 0x008124, + 0x280D02, 0x00008D, 0x008124, 0x281502, + 0x10018D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001025, 0x000575, 0x030042, + 0x09004A, 0x10000A, 0x0A0904, 0x121104, + 0x000007, 0x001020, 0x050860, 0x050040, + 0x0006FD, 0x018042, 0x09004A, 0x10000A, + 0x0000A5, 0x0A0904, 0x121104, 0x000007, + 0x000820, 0x019060, 0x010040, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x284286, + 0x000007, 0x230A06, 0x000007, 0x000606, + 0x000007, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x289286, 0x000007, 0x000100, + 0x080B20, 0x138B60, 0x1B8B60, 0x238B60, + 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60, + 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60, + 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60, + 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60, + 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60, + 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60, + 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60, + 0x000606, 0x018040, 0x00008D, 0x000A64, + 0x280D02, 0x000A24, 0x00027D, 0x018042, + 0x10000A, 0x001224, 0x0003FD, 0x018042, + 0x08000A, 0x000904, 0x2A8286, 0x000007, + 0x00018D, 0x000A24, 0x000464, 0x000464, + 0x080102, 0x000924, 0x000424, 0x000424, + 0x100102, 0x02000D, 0x009144, 0x2AD986, + 0x000007, 0x0001FD, 0x018042, 0x08000A, + 0x000A44, 0x2ABB86, 0x018042, 0x0A000D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x00027D, 0x001020, 0x000606, 0x018040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x2B2A86, 0x000007, 0x00037D, 0x018042, + 0x08000A, 0x000904, 0x2B5A86, 0x000007, + 0x000075, 0x002E7D, 0x010042, 0x0B804A, + 0x000020, 0x000904, 0x000686, 0x010040, + 0x31844A, 0x30048B, 0x000883, 0x00008D, + 0x000810, 0x28143A, 0x00008D, 0x000810, + 0x280C3A, 0x000675, 0x010042, 0x08000A, + 0x003815, 0x010924, 0x280502, 0x0B000D, + 0x000820, 0x0002F5, 0x010040, 0x000606, + 0x220007, 0x000464, 0x000464, 0x000606, + 0x000007, 0x000134, 0x007F8D, 0x00093C, + 0x281D12, 0x282512, 0x001F32, 0x0E0007, + 0x00010D, 0x00037D, 0x000820, 0x018040, + 0x05D2F4, 0x000007, 0x080007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2D0286, + 0x000007, 0x000606, 0x000007, 0x000007, + 0x000012, 0x100007, 0x320007, 0x600007, + 0x100080, 0x48001A, 0x004904, 0x2D6186, + 0x000007, 0x001210, 0x58003A, 0x000145, + 0x5C5D04, 0x000007, 0x000080, 0x48001A, + 0x004904, 0x2DB186, 0x000007, 0x001210, + 0x50003A, 0x005904, 0x2E0886, 0x000045, + 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524, + 0x004224, 0x500102, 0x200502, 0x000082, + 0x40001A, 0x004104, 0x2E3986, 0x000007, + 0x003865, 0x40001A, 0x004020, 0x00104D, + 0x04C184, 0x301B86, 0x000040, 0x040007, + 0x000165, 0x000145, 0x004020, 0x000040, + 0x000765, 0x080080, 0x40001A, 0x004104, + 0x2EC986, 0x000007, 0x001210, 0x40003A, + 0x004104, 0x2F2286, 0x00004D, 0x0000CD, + 0x004810, 0x20043A, 0x000882, 0x40001A, + 0x004104, 0x2F3186, 0x000007, 0x004820, + 0x005904, 0x300886, 0x000040, 0x0007E5, + 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0, + 0x4216E0, 0x021260, 0x000040, 0x000032, + 0x400075, 0x00007D, 0x07D574, 0x200512, + 0x000082, 0x40001A, 0x004104, 0x2FE186, + 0x000007, 0x037206, 0x640007, 0x060007, + 0x0000E5, 0x000020, 0x000040, 0x000A65, + 0x000020, 0x020040, 0x020040, 0x000040, + 0x000165, 0x000042, 0x70000A, 0x007104, + 0x30A286, 0x000007, 0x018206, 0x640007, + 0x050000, 0x007020, 0x000040, 0x037206, + 0x640007, 0x000007, 0x00306D, 0x028860, + 0x029060, 0x08000A, 0x028860, 0x008040, + 0x100012, 0x00100D, 0x009184, 0x314186, + 0x000E0D, 0x009184, 0x325186, 0x000007, + 0x300007, 0x001020, 0x003B6D, 0x008040, + 0x000080, 0x08001A, 0x000904, 0x316186, + 0x000007, 0x001220, 0x000DED, 0x008040, + 0x008042, 0x10000A, 0x40000D, 0x109544, + 0x000007, 0x001020, 0x000DED, 0x008040, + 0x008042, 0x20040A, 0x000082, 0x08001A, + 0x000904, 0x31F186, 0x000007, 0x003B6D, + 0x008042, 0x08000A, 0x000E15, 0x010984, + 0x329B86, 0x600007, 0x08001A, 0x000C15, + 0x010984, 0x328386, 0x000020, 0x1A0007, + 0x0002ED, 0x008040, 0x620007, 0x00306D, + 0x028042, 0x0A804A, 0x000820, 0x0A804A, + 0x000606, 0x10804A, 0x000007, 0x282512, + 0x001F32, 0x05D2F4, 0x54D104, 0x00735C, + 0x000786, 0x000007, 0x0C0007, 0x0A0007, + 0x1C0007, 0x003465, 0x020040, 0x004820, + 0x025060, 0x40000A, 0x024060, 0x000040, + 0x454944, 0x000007, 0x004020, 0x003AE5, + 0x000040, 0x0028E5, 0x000042, 0x48000A, + 0x004904, 0x386886, 0x002C65, 0x000042, + 0x40000A, 0x0000D5, 0x454104, 0x000007, + 0x000655, 0x054504, 0x34F286, 0x0001D5, + 0x054504, 0x34F086, 0x002B65, 0x000042, + 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4, + 0x000007, 0x454504, 0x000007, 0x0000CD, + 0x444944, 0x000007, 0x454504, 0x000007, + 0x00014D, 0x554944, 0x000007, 0x045144, + 0x34E986, 0x002C65, 0x000042, 0x48000A, + 0x4CD104, 0x000007, 0x04C144, 0x34F386, + 0x000007, 0x160007, 0x002CE5, 0x040042, + 0x40000A, 0x004020, 0x000040, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x356086, + 0x000007, 0x002402, 0x36A206, 0x005C02, + 0x0025E5, 0x000042, 0x40000A, 0x004274, + 0x002AE5, 0x000042, 0x40000A, 0x004274, + 0x500112, 0x0029E5, 0x000042, 0x40000A, + 0x004234, 0x454104, 0x000007, 0x004020, + 0x000040, 0x003EE5, 0x000020, 0x000040, + 0x002DE5, 0x400152, 0x50000A, 0x045144, + 0x364A86, 0x0000C5, 0x003EE5, 0x004020, + 0x000040, 0x002BE5, 0x000042, 0x40000A, + 0x404254, 0x000007, 0x002AE5, 0x004020, + 0x000040, 0x500132, 0x040134, 0x005674, + 0x0029E5, 0x020042, 0x42000A, 0x000042, + 0x50000A, 0x05417C, 0x0028E5, 0x000042, + 0x48000A, 0x0000C5, 0x4CC144, 0x371086, + 0x0026E5, 0x0027E5, 0x020042, 0x40004A, + 0x50000A, 0x00423C, 0x00567C, 0x0028E5, + 0x004820, 0x000040, 0x281D12, 0x282512, + 0x001F72, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x37AA86, 0x0E0007, 0x160007, + 0x1E0007, 0x003EE5, 0x000042, 0x40000A, + 0x004104, 0x37E886, 0x002D65, 0x000042, + 0x28340A, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x50004A, 0x05D2F4, + 0x54D104, 0x00735C, 0x385186, 0x000007, + 0x000606, 0x080007, 0x0C0007, 0x080007, + 0x0A0007, 0x0001E5, 0x020045, 0x004020, + 0x000060, 0x000365, 0x000040, 0x002E65, + 0x001A20, 0x0A1A60, 0x000040, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x000606, 0x50004A, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +/* -------------------------------------------- + DS-1E Controller InstructionRAM Code + 1999/06/21 + Buf441 slot is Enabled. + -------------------------------------------- + 04/09@creat + 04/12 stop nise fix + 06/21@WorkingOff timming +*/ + +static u_int32_t CntrlInst1E[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x00800D, 0x000810, 0x20043A, 0x001A82, + 0x03460D, 0x000810, 0x10043A, 0x02EC0D, + 0x000810, 0x18043A, 0x00010D, 0x020015, + 0x0000FD, 0x000020, 0x038860, 0x039060, + 0x038060, 0x038040, 0x038040, 0x038040, + 0x018040, 0x000A7D, 0x038040, 0x038040, + 0x018040, 0x200402, 0x000882, 0x08001A, + 0x000904, 0x017186, 0x000007, 0x260007, + 0x400007, 0x000007, 0x03258D, 0x000810, + 0x18043A, 0x260007, 0x284402, 0x00087D, + 0x018042, 0x00160A, 0x05A206, 0x000007, + 0x440007, 0x00230D, 0x000810, 0x08043A, + 0x22FA06, 0x000007, 0x0007FD, 0x018042, + 0x08000A, 0x000904, 0x02AB86, 0x000195, + 0x090D04, 0x000007, 0x000820, 0x0000F5, + 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, + 0x018040, 0x000A7D, 0x038042, 0x13804A, + 0x18000A, 0x001820, 0x059060, 0x058860, + 0x018040, 0x0000FD, 0x018042, 0x70000A, + 0x000115, 0x071144, 0x033B86, 0x030000, + 0x007020, 0x036206, 0x018040, 0x00360D, + 0x000810, 0x08043A, 0x232206, 0x000007, + 0x02EC0D, 0x000810, 0x18043A, 0x019A06, + 0x000007, 0x240007, 0x000F8D, 0x000810, + 0x00163A, 0x002402, 0x005C02, 0x0028FD, + 0x000020, 0x018040, 0x08000D, 0x000815, + 0x510984, 0x000007, 0x00004D, 0x000E5D, + 0x000E02, 0x00430D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x00008D, 0x000924, + 0x000F02, 0x00470D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x480480, 0x001210, + 0x28043A, 0x00778D, 0x000810, 0x280C3A, + 0x00068D, 0x000810, 0x28143A, 0x284402, + 0x03258D, 0x000810, 0x18043A, 0x07FF8D, + 0x000820, 0x0002FD, 0x018040, 0x260007, + 0x200007, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x051286, 0x000007, 0x240007, + 0x02EC0D, 0x000810, 0x18043A, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x019B86, 0x000007, 0x01B206, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x22B886, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x065A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x036186, 0x000007, 0x002104, 0x036186, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x07C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00788D, 0x000810, 0x08043A, 0x2A1206, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x070206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x229086, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x225886, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x08DA86, 0x00057D, 0x002820, + 0x03B060, 0x08F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x08FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x009D8D, 0x000810, + 0x08043A, 0x2A1206, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x0A5186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x00107D, 0x018042, + 0x08000A, 0x000215, 0x010984, 0x3A8186, + 0x000007, 0x007FBD, 0x383DC4, 0x000007, + 0x001A7D, 0x001375, 0x018042, 0x09004A, + 0x10000A, 0x0B8D04, 0x139504, 0x000007, + 0x000820, 0x019060, 0x001104, 0x225886, + 0x010040, 0x0017FD, 0x018042, 0x08000A, + 0x000904, 0x225A86, 0x000007, 0x00197D, + 0x038042, 0x09804A, 0x10000A, 0x000924, + 0x001664, 0x0011FD, 0x038042, 0x2B804A, + 0x19804A, 0x00008D, 0x218944, 0x000007, + 0x002244, 0x0C1986, 0x000007, 0x001A64, + 0x002A24, 0x00197D, 0x080102, 0x100122, + 0x000820, 0x039060, 0x018040, 0x003DFD, + 0x00008D, 0x000820, 0x018040, 0x001375, + 0x001A7D, 0x010042, 0x09804A, 0x10000A, + 0x00021D, 0x0189E4, 0x2992E4, 0x309144, + 0x000007, 0x00060D, 0x000A15, 0x000C1D, + 0x001025, 0x00A9E4, 0x012BE4, 0x000464, + 0x01B3E4, 0x0232E4, 0x000464, 0x000464, + 0x000464, 0x000464, 0x00040D, 0x08B1C4, + 0x000007, 0x000820, 0x000BF5, 0x030040, + 0x00197D, 0x038042, 0x09804A, 0x000A24, + 0x08000A, 0x080E64, 0x000007, 0x100122, + 0x000820, 0x031060, 0x010040, 0x0064AC, + 0x00027D, 0x000020, 0x018040, 0x00107D, + 0x018042, 0x0011FD, 0x3B804A, 0x09804A, + 0x20000A, 0x000095, 0x1A1144, 0x00A144, + 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, + 0x0018FD, 0x018042, 0x0010FD, 0x09804A, + 0x28000A, 0x000095, 0x010924, 0x002A64, + 0x0E4986, 0x000007, 0x002904, 0x0E5A86, + 0x000007, 0x0E6206, 0x080002, 0x00008D, + 0x00387D, 0x000820, 0x018040, 0x00127D, + 0x018042, 0x10000A, 0x003904, 0x0F0986, + 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, + 0x000025, 0x0FB206, 0x00002D, 0x000015, + 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, + 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, + 0x400025, 0x00008D, 0x110944, 0x000007, + 0x00018D, 0x109504, 0x000007, 0x009164, + 0x000424, 0x000424, 0x000424, 0x100102, + 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, + 0x00018D, 0x00042D, 0x00008D, 0x109504, + 0x000007, 0x00020D, 0x109184, 0x000007, + 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, + 0x018040, 0x003BFD, 0x001020, 0x03A860, + 0x000815, 0x313184, 0x212184, 0x000007, + 0x03B060, 0x03A060, 0x018040, 0x0022FD, + 0x000095, 0x010924, 0x000424, 0x000424, + 0x001264, 0x100102, 0x000820, 0x039060, + 0x018040, 0x001924, 0x010F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x000424, 0x000424, + 0x00117D, 0x018042, 0x08000A, 0x000A24, + 0x280502, 0x280C02, 0x09800D, 0x000820, + 0x0002FD, 0x018040, 0x200007, 0x0022FD, + 0x018042, 0x08000A, 0x000095, 0x280DC4, + 0x011924, 0x00197D, 0x018042, 0x0011FD, + 0x09804A, 0x10000A, 0x0000B5, 0x113144, + 0x0A8D04, 0x000007, 0x080A44, 0x129504, + 0x000007, 0x0023FD, 0x001020, 0x038040, + 0x101244, 0x000007, 0x000820, 0x039060, + 0x018040, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x123286, 0x000007, 0x003BFD, + 0x000100, 0x000A10, 0x0B807A, 0x13804A, + 0x090984, 0x000007, 0x000095, 0x013D04, + 0x12B886, 0x10000A, 0x100002, 0x090984, + 0x000007, 0x038042, 0x11804A, 0x090D04, + 0x000007, 0x10000A, 0x090D84, 0x000007, + 0x00257D, 0x000820, 0x018040, 0x00010D, + 0x000810, 0x28143A, 0x00127D, 0x018042, + 0x20000A, 0x00197D, 0x018042, 0x00117D, + 0x31804A, 0x10000A, 0x003124, 0x013B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x300102, + 0x003124, 0x000424, 0x000424, 0x001224, + 0x280502, 0x001A4C, 0x143986, 0x700002, + 0x00002D, 0x030000, 0x00387D, 0x018042, + 0x10000A, 0x146206, 0x002124, 0x0000AD, + 0x100002, 0x00010D, 0x000924, 0x006B24, + 0x014A0D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x003264, 0x00008D, 0x000A24, 0x001020, + 0x00227D, 0x018040, 0x014F8D, 0x000810, + 0x08043A, 0x2B5A06, 0x000007, 0x002820, + 0x00207D, 0x018040, 0x00117D, 0x038042, + 0x13804A, 0x33800A, 0x00387D, 0x018042, + 0x08000A, 0x000904, 0x177286, 0x000007, + 0x00008D, 0x030964, 0x015B0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x380102, 0x000424, + 0x000424, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x280502, 0x001A4C, 0x177186, 0x000007, + 0x032164, 0x00632C, 0x003DFD, 0x018042, + 0x08000A, 0x000095, 0x090904, 0x000007, + 0x000820, 0x001A4C, 0x169986, 0x018040, + 0x030000, 0x16B206, 0x002124, 0x00010D, + 0x000924, 0x006B24, 0x016F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x003A64, 0x000095, + 0x001224, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x171286, 0x000007, 0x01760D, + 0x000810, 0x08043A, 0x2B5A06, 0x000007, + 0x160A06, 0x000007, 0x007020, 0x08010A, + 0x10012A, 0x0020FD, 0x038860, 0x039060, + 0x018040, 0x00227D, 0x018042, 0x003DFD, + 0x08000A, 0x31844A, 0x000904, 0x181086, + 0x18008B, 0x00008D, 0x189904, 0x00312C, + 0x18E206, 0x000007, 0x00324C, 0x186B86, + 0x000007, 0x001904, 0x186886, 0x000007, + 0x000095, 0x199144, 0x00222C, 0x003124, + 0x00636C, 0x000E3D, 0x001375, 0x000BFD, + 0x010042, 0x09804A, 0x10000A, 0x038AEC, + 0x0393EC, 0x00224C, 0x18E186, 0x000007, + 0x00008D, 0x189904, 0x00226C, 0x00322C, + 0x30050A, 0x301DAB, 0x002083, 0x0018FD, + 0x018042, 0x08000A, 0x018924, 0x300502, + 0x001083, 0x001875, 0x010042, 0x10000A, + 0x00008D, 0x010924, 0x001375, 0x330542, + 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, + 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, + 0x006083, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x19B286, 0x000007, 0x001E2D, + 0x0005FD, 0x018042, 0x08000A, 0x028924, + 0x280502, 0x00060D, 0x000810, 0x280C3A, + 0x00008D, 0x000810, 0x28143A, 0x0A808D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x001275, 0x030042, 0x21004A, 0x00008D, + 0x1A0944, 0x000007, 0x01AB8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, + 0x030042, 0x0D004A, 0x10000A, 0x089144, + 0x000007, 0x000820, 0x010040, 0x0025F5, + 0x0A3144, 0x000007, 0x000820, 0x032860, + 0x030040, 0x00217D, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00008D, 0x000124, 0x00012C, 0x000E64, + 0x001A64, 0x00636C, 0x08010A, 0x10012A, + 0x000820, 0x031060, 0x030040, 0x0020FD, + 0x018042, 0x08000A, 0x00227D, 0x018042, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00197D, 0x018042, 0x08000A, 0x0022FD, + 0x038042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x090D04, 0x000007, 0x000820, + 0x030040, 0x038042, 0x0B804A, 0x10000A, + 0x000820, 0x031060, 0x030040, 0x038042, + 0x13804A, 0x19804A, 0x110D04, 0x198D04, + 0x000007, 0x08000A, 0x001020, 0x031860, + 0x030860, 0x030040, 0x00008D, 0x0B0944, + 0x000007, 0x000820, 0x010040, 0x0005F5, + 0x030042, 0x08000A, 0x000820, 0x010040, + 0x0000F5, 0x010042, 0x08000A, 0x000904, + 0x1D9886, 0x001E75, 0x030042, 0x01044A, + 0x000C0A, 0x1DAA06, 0x000007, 0x000402, + 0x000C02, 0x00177D, 0x001AF5, 0x018042, + 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, + 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, + 0x00043D, 0x0013F5, 0x001AFD, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x005502, 0x005D0A, 0x030042, 0x0B004A, + 0x1B804A, 0x13804A, 0x20000A, 0x089144, + 0x19A144, 0x0389E4, 0x0399EC, 0x006502, + 0x006D0A, 0x030042, 0x0B004A, 0x19004A, + 0x2B804A, 0x13804A, 0x21804A, 0x30000A, + 0x089144, 0x19A144, 0x2AB144, 0x0389E4, + 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, + 0x000702, 0x00107D, 0x000415, 0x018042, + 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, + 0x0019FD, 0x010042, 0x09804A, 0x10000A, + 0x000934, 0x001674, 0x0029F5, 0x010042, + 0x10000A, 0x00917C, 0x002075, 0x010042, + 0x08000A, 0x000904, 0x200A86, 0x0026F5, + 0x0027F5, 0x030042, 0x09004A, 0x10000A, + 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, + 0x010042, 0x51804A, 0x48000A, 0x160007, + 0x001075, 0x010042, 0x282C0A, 0x281D12, + 0x282512, 0x001F32, 0x1E0007, 0x0E0007, + 0x001975, 0x010042, 0x002DF5, 0x0D004A, + 0x10000A, 0x009144, 0x20EA86, 0x010042, + 0x28340A, 0x000E5D, 0x00008D, 0x000375, + 0x000820, 0x010040, 0x05D2F4, 0x54D104, + 0x00735C, 0x218B86, 0x000007, 0x0C0007, + 0x080007, 0x0A0007, 0x02178D, 0x000810, + 0x08043A, 0x34B206, 0x000007, 0x219206, + 0x000007, 0x080007, 0x002275, 0x010042, + 0x20000A, 0x002104, 0x225886, 0x001E2D, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x21CA86, 0x000007, 0x002010, 0x30043A, + 0x00057D, 0x0180C3, 0x08000A, 0x028924, + 0x280502, 0x280C02, 0x0A810D, 0x000820, + 0x0002F5, 0x010040, 0x220007, 0x0004FD, + 0x018042, 0x70000A, 0x030000, 0x007020, + 0x07FA06, 0x018040, 0x022B8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x22C286, + 0x000007, 0x020206, 0x000007, 0x000875, + 0x0009FD, 0x00010D, 0x234206, 0x000295, + 0x000B75, 0x00097D, 0x00000D, 0x000515, + 0x010042, 0x18000A, 0x001904, 0x2A0086, + 0x0006F5, 0x001020, 0x010040, 0x0004F5, + 0x000820, 0x010040, 0x000775, 0x010042, + 0x09804A, 0x10000A, 0x001124, 0x000904, + 0x23F286, 0x000815, 0x080102, 0x101204, + 0x241206, 0x000575, 0x081204, 0x000007, + 0x100102, 0x000575, 0x000425, 0x021124, + 0x100102, 0x000820, 0x031060, 0x010040, + 0x001924, 0x2A0086, 0x00008D, 0x000464, + 0x009D04, 0x291086, 0x180102, 0x000575, + 0x010042, 0x28040A, 0x00018D, 0x000924, + 0x280D02, 0x00000D, 0x000924, 0x281502, + 0x10000D, 0x000820, 0x0002F5, 0x010040, + 0x200007, 0x001175, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x24FA86, 0x000007, + 0x000100, 0x080B20, 0x130B60, 0x1B0B60, + 0x030A60, 0x010040, 0x050042, 0x3D004A, + 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, + 0x010042, 0x28140A, 0x0004F5, 0x010042, + 0x08000A, 0x000315, 0x010D04, 0x260286, + 0x004015, 0x000095, 0x010D04, 0x25F086, + 0x100022, 0x10002A, 0x261A06, 0x000007, + 0x333104, 0x2AA904, 0x000007, 0x032124, + 0x280502, 0x284402, 0x001124, 0x400102, + 0x000424, 0x000424, 0x003224, 0x00292C, + 0x00636C, 0x277386, 0x000007, 0x02B164, + 0x000464, 0x000464, 0x00008D, 0x000A64, + 0x280D02, 0x10008D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x00008D, 0x38B904, + 0x000007, 0x03296C, 0x30010A, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x270286, + 0x000007, 0x00212C, 0x28050A, 0x00316C, + 0x00046C, 0x00046C, 0x28450A, 0x001124, + 0x006B64, 0x100102, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x004124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x27FA86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x284086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x284A86, 0x000007, 0x284402, 0x003124, + 0x300502, 0x003924, 0x300583, 0x000883, + 0x0005F5, 0x010042, 0x28040A, 0x00008D, + 0x008124, 0x280D02, 0x00008D, 0x008124, + 0x281502, 0x10018D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001025, 0x000575, + 0x030042, 0x09004A, 0x10000A, 0x0A0904, + 0x121104, 0x000007, 0x001020, 0x050860, + 0x050040, 0x0006FD, 0x018042, 0x09004A, + 0x10000A, 0x0000A5, 0x0A0904, 0x121104, + 0x000007, 0x000820, 0x019060, 0x010040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x29CA86, 0x000007, 0x244206, 0x000007, + 0x000606, 0x000007, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x2A1A86, 0x000007, + 0x000100, 0x080B20, 0x138B60, 0x1B8B60, + 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, + 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, + 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, + 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, + 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, + 0x038A60, 0x000606, 0x018040, 0x00008D, + 0x000A64, 0x280D02, 0x000A24, 0x00027D, + 0x018042, 0x10000A, 0x001224, 0x0003FD, + 0x018042, 0x08000A, 0x000904, 0x2C0A86, + 0x000007, 0x00018D, 0x000A24, 0x000464, + 0x000464, 0x080102, 0x000924, 0x000424, + 0x000424, 0x100102, 0x02000D, 0x009144, + 0x2C6186, 0x000007, 0x0001FD, 0x018042, + 0x08000A, 0x000A44, 0x2C4386, 0x018042, + 0x0A000D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00027D, 0x001020, 0x000606, + 0x018040, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x2CB286, 0x000007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2CE286, + 0x000007, 0x000075, 0x002E7D, 0x010042, + 0x0B804A, 0x000020, 0x000904, 0x000686, + 0x010040, 0x31844A, 0x30048B, 0x000883, + 0x00008D, 0x000810, 0x28143A, 0x00008D, + 0x000810, 0x280C3A, 0x000675, 0x010042, + 0x08000A, 0x003815, 0x010924, 0x280502, + 0x0B000D, 0x000820, 0x0002F5, 0x010040, + 0x000606, 0x220007, 0x000464, 0x000464, + 0x000606, 0x000007, 0x000134, 0x007F8D, + 0x00093C, 0x281D12, 0x282512, 0x001F32, + 0x0E0007, 0x00010D, 0x00037D, 0x000820, + 0x018040, 0x05D2F4, 0x000007, 0x080007, + 0x00037D, 0x018042, 0x08000A, 0x000904, + 0x2E8A86, 0x000007, 0x000606, 0x000007, + 0x000007, 0x000012, 0x100007, 0x320007, + 0x600007, 0x460007, 0x100080, 0x48001A, + 0x004904, 0x2EF186, 0x000007, 0x001210, + 0x58003A, 0x000145, 0x5C5D04, 0x000007, + 0x000080, 0x48001A, 0x004904, 0x2F4186, + 0x000007, 0x001210, 0x50003A, 0x005904, + 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, + 0x7FFF7D, 0x07D524, 0x004224, 0x500102, + 0x200502, 0x000082, 0x40001A, 0x004104, + 0x2FC986, 0x000007, 0x003865, 0x40001A, + 0x004020, 0x00104D, 0x04C184, 0x31AB86, + 0x000040, 0x040007, 0x000165, 0x000145, + 0x004020, 0x000040, 0x000765, 0x080080, + 0x40001A, 0x004104, 0x305986, 0x000007, + 0x001210, 0x40003A, 0x004104, 0x30B286, + 0x00004D, 0x0000CD, 0x004810, 0x20043A, + 0x000882, 0x40001A, 0x004104, 0x30C186, + 0x000007, 0x004820, 0x005904, 0x319886, + 0x000040, 0x0007E5, 0x200480, 0x2816A0, + 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, + 0x000040, 0x000032, 0x400075, 0x00007D, + 0x07D574, 0x200512, 0x000082, 0x40001A, + 0x004104, 0x317186, 0x000007, 0x038A06, + 0x640007, 0x0000E5, 0x000020, 0x000040, + 0x000A65, 0x000020, 0x020040, 0x020040, + 0x000040, 0x000165, 0x000042, 0x70000A, + 0x007104, 0x323286, 0x000007, 0x060007, + 0x019A06, 0x640007, 0x050000, 0x007020, + 0x000040, 0x038A06, 0x640007, 0x000007, + 0x00306D, 0x028860, 0x029060, 0x08000A, + 0x028860, 0x008040, 0x100012, 0x00100D, + 0x009184, 0x32D186, 0x000E0D, 0x009184, + 0x33E186, 0x000007, 0x300007, 0x001020, + 0x003B6D, 0x008040, 0x000080, 0x08001A, + 0x000904, 0x32F186, 0x000007, 0x001220, + 0x000DED, 0x008040, 0x008042, 0x10000A, + 0x40000D, 0x109544, 0x000007, 0x001020, + 0x000DED, 0x008040, 0x008042, 0x20040A, + 0x000082, 0x08001A, 0x000904, 0x338186, + 0x000007, 0x003B6D, 0x008042, 0x08000A, + 0x000E15, 0x010984, 0x342B86, 0x600007, + 0x08001A, 0x000C15, 0x010984, 0x341386, + 0x000020, 0x1A0007, 0x0002ED, 0x008040, + 0x620007, 0x00306D, 0x028042, 0x0A804A, + 0x000820, 0x0A804A, 0x000606, 0x10804A, + 0x000007, 0x282512, 0x001F32, 0x05D2F4, + 0x54D104, 0x00735C, 0x000786, 0x000007, + 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, + 0x020040, 0x004820, 0x025060, 0x40000A, + 0x024060, 0x000040, 0x454944, 0x000007, + 0x004020, 0x003AE5, 0x000040, 0x0028E5, + 0x000042, 0x48000A, 0x004904, 0x39F886, + 0x002C65, 0x000042, 0x40000A, 0x0000D5, + 0x454104, 0x000007, 0x000655, 0x054504, + 0x368286, 0x0001D5, 0x054504, 0x368086, + 0x002B65, 0x000042, 0x003AE5, 0x50004A, + 0x40000A, 0x45C3D4, 0x000007, 0x454504, + 0x000007, 0x0000CD, 0x444944, 0x000007, + 0x454504, 0x000007, 0x00014D, 0x554944, + 0x000007, 0x045144, 0x367986, 0x002C65, + 0x000042, 0x48000A, 0x4CD104, 0x000007, + 0x04C144, 0x368386, 0x000007, 0x160007, + 0x002CE5, 0x040042, 0x40000A, 0x004020, + 0x000040, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x36F086, 0x000007, 0x002402, + 0x383206, 0x005C02, 0x0025E5, 0x000042, + 0x40000A, 0x004274, 0x002AE5, 0x000042, + 0x40000A, 0x004274, 0x500112, 0x0029E5, + 0x000042, 0x40000A, 0x004234, 0x454104, + 0x000007, 0x004020, 0x000040, 0x003EE5, + 0x000020, 0x000040, 0x002DE5, 0x400152, + 0x50000A, 0x045144, 0x37DA86, 0x0000C5, + 0x003EE5, 0x004020, 0x000040, 0x002BE5, + 0x000042, 0x40000A, 0x404254, 0x000007, + 0x002AE5, 0x004020, 0x000040, 0x500132, + 0x040134, 0x005674, 0x0029E5, 0x020042, + 0x42000A, 0x000042, 0x50000A, 0x05417C, + 0x0028E5, 0x000042, 0x48000A, 0x0000C5, + 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, + 0x020042, 0x40004A, 0x50000A, 0x00423C, + 0x00567C, 0x0028E5, 0x004820, 0x000040, + 0x281D12, 0x282512, 0x001F72, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x393A86, + 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, + 0x000042, 0x40000A, 0x004104, 0x397886, + 0x002D65, 0x000042, 0x28340A, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, + 0x39E186, 0x000007, 0x000606, 0x080007, + 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, + 0x020045, 0x004020, 0x000060, 0x000365, + 0x000040, 0x002E65, 0x001A20, 0x0A1A60, + 0x000040, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x000606, 0x50004A, + 0x0017FD, 0x018042, 0x08000A, 0x000904, + 0x225A86, 0x000007, 0x00107D, 0x018042, + 0x0011FD, 0x33804A, 0x19804A, 0x20000A, + 0x000095, 0x2A1144, 0x01A144, 0x3B9086, + 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, + 0x018042, 0x0010FD, 0x09804A, 0x38000A, + 0x000095, 0x010924, 0x003A64, 0x3B8186, + 0x000007, 0x003904, 0x3B9286, 0x000007, + 0x3B9A06, 0x00000D, 0x00008D, 0x000820, + 0x00387D, 0x018040, 0x700002, 0x00117D, + 0x018042, 0x00197D, 0x29804A, 0x30000A, + 0x380002, 0x003124, 0x000424, 0x000424, + 0x002A24, 0x280502, 0x00068D, 0x000810, + 0x28143A, 0x00750D, 0x00B124, 0x002264, + 0x3D0386, 0x284402, 0x000810, 0x280C3A, + 0x0B800D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00758D, 0x00B124, 0x100102, + 0x012144, 0x3E4986, 0x001810, 0x10003A, + 0x00387D, 0x018042, 0x08000A, 0x000904, + 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, + 0x00008D, 0x023164, 0x000A64, 0x280D02, + 0x0B808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00387D, 0x018042, 0x08000A, + 0x000904, 0x3E3286, 0x030000, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x3D8286, + 0x000007, 0x002810, 0x28043A, 0x00750D, + 0x030924, 0x002264, 0x280D02, 0x02316C, + 0x28450A, 0x0B810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x00008D, 0x000A24, + 0x3E4A06, 0x100102, 0x001810, 0x10003A, + 0x0000BD, 0x003810, 0x30043A, 0x00187D, + 0x018042, 0x0018FD, 0x09804A, 0x20000A, + 0x0000AD, 0x028924, 0x07212C, 0x001010, + 0x300583, 0x300D8B, 0x3014BB, 0x301C83, + 0x002083, 0x00137D, 0x038042, 0x33844A, + 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, + 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, + 0x001E0D, 0x0005FD, 0x018042, 0x20000A, + 0x020924, 0x00068D, 0x00A96C, 0x00009D, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x3F6A86, 0x000007, 0x280502, 0x280D0A, + 0x284402, 0x001810, 0x28143A, 0x0C008D, + 0x000820, 0x0002FD, 0x018040, 0x220007, + 0x003904, 0x225886, 0x001E0D, 0x00057D, + 0x018042, 0x20000A, 0x020924, 0x0000A5, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x402A86, 0x000007, 0x280502, 0x280C02, + 0x002010, 0x28143A, 0x0C010D, 0x000820, + 0x0002FD, 0x018040, 0x225A06, 0x220007, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +#endif + diff --git a/sys/dev/sound/pci/ds1.h b/sys/dev/sound/pci/ds1.h new file mode 100644 index 000000000000..ad4e829cbfee --- /dev/null +++ b/sys/dev/sound/pci/ds1.h @@ -0,0 +1,156 @@ +/* + * ======================================================================= + * title : define + * company : YAMAHA + * author : Taichi Sugiyama + * create Data : 28/Sep/99 + * ======================================================================= + * $FreeBSD$ + */ + + +/* ----- YAMAHA DS-XG Devices -------------------------------------------- */ +#define YAMAHA 0x1073 +#define YMF724 0x0004 +#define YMF724F 0x000d +#define YMF734 0x0005 +#define YMF737 0x0008 +#define YMF738 0x0020 +#define YMF740 0x000a +#define YMF740C 0x000c +#define YMF744 0x0010 +#define YMF754 0x0012 +#define YMF738_TEG 0x0006 +#define DEVICE4CH(x) ((x == YMF738) || (x == YMF744) || (x == YMF754)) + + +#define PCIR_DSXGCTRL 0x48 +/* ----- interrupt flag -------------------------------------------------- */ +#define YDSXG_DEFINT 0x01 +#define YDSXG_TIMERINT 0x02 + + +/* ----- AC97 ------------------------------------------------------------ */ +#define YDSXG_AC97TIMEOUT 1000 +#define YDSXG_AC97READCMD 0x8000 +#define YDSXG_AC97WRITECMD 0x0000 +#define YDSXG_AC97READFALSE 0xFFFF + + +/* ----- AC97 register map _---------------------------------------------- */ +#define AC97R_GPIOSTATUS 0x54 + + +/* ----- work buffer ----------------------------------------------------- */ +#define DEF_WORKBUFFLENGTH 0x0400 + + +/* ----- register size --------------------------------------------------- */ +#define YDSXG_MAPLENGTH 0x8000 +#define YDSXG_DSPLENGTH 0x0080 +#define YDSXG_CTRLLENGTH 0x3000 + + +/* ----- register map ---------------------------------------------------- */ +#define YDSXGR_INTFLAG 0x0004 +#define YDSXGR_ACTIVITY 0x0006 +#define YDSXGR_GLOBALCTRL 0x0008 +#define YDSXGR_ZVCTRL 0x000A +#define YDSXGR_TIMERCTRL 0x0010 +#define YDSXGR_TIMERCOUNT 0x0012 +#define YDSXGR_SPDIFOUTCTRL 0x0018 +#define YDSXGR_SPDIFOUTSTATUS 0x001C +#define YDSXGR_EEPROMCTRL 0x0020 +#define YDSXGR_SPDIFINCTRL 0x0034 +#define YDSXGR_SPDIFINSTATUS 0x0038 +#define YDSXGR_DSPPROGRAMDL 0x0048 +#define YDSXGR_DLCNTRL 0x004C +#define YDSXGR_GPIOININTFLAG 0x0050 +#define YDSXGR_GPIOININTENABLE 0x0052 +#define YDSXGR_GPIOINSTATUS 0x0054 +#define YDSXGR_GPIOOUTCTRL 0x0056 +#define YDSXGR_GPIOFUNCENABLE 0x0058 +#define YDSXGR_GPIOTYPECONFIG 0x005A +#define YDSXGR_AC97CMDDATA 0x0060 +#define YDSXGR_AC97CMDADR 0x0062 +#define YDSXGR_PRISTATUSDATA 0x0064 +#define YDSXGR_PRISTATUSADR 0x0066 +#define YDSXGR_SECSTATUSDATA 0x0068 +#define YDSXGR_SECSTATUSADR 0x006A +#define YDSXGR_SECCONFIG 0x0070 +#define YDSXGR_LEGACYOUTVOL 0x0080 +#define YDSXGR_LEGACYOUTVOLL 0x0080 +#define YDSXGR_LEGACYOUTVOLR 0x0082 +#define YDSXGR_NATIVEDACOUTVOL 0x0084 +#define YDSXGR_NATIVEDACOUTVOLL 0x0084 +#define YDSXGR_NATIVEDACOUTVOLR 0x0086 +#define YDSXGR_SPDIFOUTVOL 0x0088 +#define YDSXGR_SPDIFOUTVOLL 0x0088 +#define YDSXGR_SPDIFOUTVOLR 0x008A +#define YDSXGR_AC3OUTVOL 0x008C +#define YDSXGR_AC3OUTVOLL 0x008C +#define YDSXGR_AC3OUTVOLR 0x008E +#define YDSXGR_PRIADCOUTVOL 0x0090 +#define YDSXGR_PRIADCOUTVOLL 0x0090 +#define YDSXGR_PRIADCOUTVOLR 0x0092 +#define YDSXGR_LEGACYLOOPVOL 0x0094 +#define YDSXGR_LEGACYLOOPVOLL 0x0094 +#define YDSXGR_LEGACYLOOPVOLR 0x0096 +#define YDSXGR_NATIVEDACLOOPVOL 0x0098 +#define YDSXGR_NATIVEDACLOOPVOLL 0x0098 +#define YDSXGR_NATIVEDACLOOPVOLR 0x009A +#define YDSXGR_SPDIFLOOPVOL 0x009C +#define YDSXGR_SPDIFLOOPVOLL 0x009E +#define YDSXGR_SPDIFLOOPVOLR 0x009E +#define YDSXGR_AC3LOOPVOL 0x00A0 +#define YDSXGR_AC3LOOPVOLL 0x00A0 +#define YDSXGR_AC3LOOPVOLR 0x00A2 +#define YDSXGR_PRIADCLOOPVOL 0x00A4 +#define YDSXGR_PRIADCLOOPVOLL 0x00A4 +#define YDSXGR_PRIADCLOOPVOLR 0x00A6 +#define YDSXGR_NATIVEADCINVOL 0x00A8 +#define YDSXGR_NATIVEADCINVOLL 0x00A8 +#define YDSXGR_NATIVEADCINVOLR 0x00AA +#define YDSXGR_NATIVEDACINVOL 0x00AC +#define YDSXGR_NATIVEDACINVOLL 0x00AC +#define YDSXGR_NATIVEDACINVOLR 0x00AE +#define YDSXGR_BUF441OUTVOL 0x00B0 +#define YDSXGR_BUF441OUTVOLL 0x00B0 +#define YDSXGR_BUF441OUTVOLR 0x00B2 +#define YDSXGR_BUF441LOOPVOL 0x00B4 +#define YDSXGR_BUF441LOOPVOLL 0x00B4 +#define YDSXGR_BUF441LOOPVOLR 0x00B6 +#define YDSXGR_SPDIFOUTVOL2 0x00B8 +#define YDSXGR_SPDIFOUTVOL2L 0x00B8 +#define YDSXGR_SPDIFOUTVOL2R 0x00BA +#define YDSXGR_SPDIFLOOPVOL2 0x00BC +#define YDSXGR_SPDIFLOOPVOL2L 0x00BC +#define YDSXGR_SPDIFLOOPVOL2R 0x00BE +#define YDSXGR_ADCSLOTSR 0x00C0 +#define YDSXGR_RECSLOTSR 0x00C4 +#define YDSXGR_ADCFORMAT 0x00C8 +#define YDSXGR_RECFORMAT 0x00CC +#define YDSXGR_P44SLOTSR 0x00D0 +#define YDSXGR_STATUS 0x0100 +#define YDSXGR_CTRLSELECT 0x0104 +#define YDSXGR_MODE 0x0108 +#define YDSXGR_SAMPLECOUNT 0x010C +#define YDSXGR_NUMOFSAMPLES 0x0110 +#define YDSXGR_CONFIG 0x0114 +#define YDSXGR_PLAYCTRLSIZE 0x0140 +#define YDSXGR_RECCTRLSIZE 0x0144 +#define YDSXGR_EFFCTRLSIZE 0x0148 +#define YDSXGR_WORKSIZE 0x014C +#define YDSXGR_MAPOFREC 0x0150 +#define YDSXGR_MAPOFEFFECT 0x0154 +#define YDSXGR_PLAYCTRLBASE 0x0158 +#define YDSXGR_RECCTRLBASE 0x015C +#define YDSXGR_EFFCTRLBASE 0x0160 +#define YDSXGR_WORKBASE 0x0164 +#define YDSXGR_DSPINSTRAM 0x1000 +#define YDSXGR_CTRLINSTRAM 0x4000 + + +/* ----- time out -------------------------------------------------------- */ +#define YDSXG_WORKBITTIMEOUT 250000 + diff --git a/sys/kern/genassym.sh b/sys/kern/genassym.sh new file mode 100644 index 000000000000..071ddb04cb03 --- /dev/null +++ b/sys/kern/genassym.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# $FreeBSD$ + +# Grrr, this should use stdin and stdout, but is encrufted for compatibility. + +usage() { + echo "usage: genassym [-o outfile] objfile" + exit 1 +} + +outfile=/dev/stdout +while getopts "o:" option +do + case "$option" in + o) outfile="$OPTARG";; + *) usage;; + esac +done +shift $(($OPTIND - 1)) +case $# in +1) ;; +*) usage;; +esac + +nm "$1" | awk ' +/ C .*sign$/ { + sign = substr($1, length($1) - 3, 4) + sub("^0*", "", sign) + if (sign != "") + sign = "-" +} +/ C .*w0$/ { + w0 = substr($1, length($1) - 3, 4) +} +/ C .*w1$/ { + w1 = substr($1, length($1) - 3, 4) +} +/ C .*w2$/ { + w2 = substr($1, length($1) - 3, 4) +} +/ C .*w3$/ { + w3 = substr($1, length($1) - 3, 4) + w = w3 w2 w1 w0 + sub("^0*", "", w) + if (w == "") + w = "0" + sub("w3$", "", $3) + # This still has minor problems representing INT_MIN, etc. E.g., + # with 32-bit 2''s complement ints, this prints -0x80000000, which + # has the wrong type (unsigned int). + printf("#define\t%s\t%s0x%s\n", $3, sign, w) +} +' 3>"$outfile" >&3 3>&- diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c new file mode 100644 index 000000000000..ab47b4ff2ff7 --- /dev/null +++ b/sys/kern/subr_taskqueue.c @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 2000 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$ + */ + +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/taskqueue.h> +#include <sys/interrupt.h> +#include <sys/malloc.h> +#include <machine/ipl.h> + +MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); + +static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; + +struct taskqueue { + STAILQ_ENTRY(taskqueue) tq_link; + STAILQ_HEAD(, task) tq_queue; + const char *tq_name; + taskqueue_enqueue_fn tq_enqueue; + void *tq_context; + int tq_draining; +}; + +struct taskqueue * +taskqueue_create(const char *name, int mflags, + taskqueue_enqueue_fn enqueue, void *context) +{ + struct taskqueue *queue; + static int once = 1; + int s; + + queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags); + if (!queue) + return 0; + STAILQ_INIT(&queue->tq_queue); + queue->tq_name = name; + queue->tq_enqueue = enqueue; + queue->tq_context = context; + queue->tq_draining = 0; + + s = splhigh(); + if (once) { + STAILQ_INIT(&taskqueue_queues); + once = 0; + } + STAILQ_INSERT_TAIL(&taskqueue_queues, queue, tq_link); + splx(s); + + return queue; +} + +void +taskqueue_free(struct taskqueue *queue) +{ + int s = splhigh(); + queue->tq_draining = 1; + splx(s); + + taskqueue_run(queue); + + s = splhigh(); + STAILQ_REMOVE(&taskqueue_queues, queue, taskqueue, tq_link); + splx(s); + + free(queue, M_TASKQUEUE); +} + +struct taskqueue * +taskqueue_find(const char *name) +{ + struct taskqueue *queue; + int s; + + s = splhigh(); + STAILQ_FOREACH(queue, &taskqueue_queues, tq_link) + if (!strcmp(queue->tq_name, name)) { + splx(s); + return queue; + } + splx(s); + return 0; +} + +int +taskqueue_enqueue(struct taskqueue *queue, struct task *task) +{ + struct task *ins; + struct task *prev; + + int s = splhigh(); + + /* + * Don't allow new tasks on a queue which is being freed. + */ + if (queue->tq_draining) { + splx(s); + return EPIPE; + } + + /* + * Count multiple enqueues. + */ + if (task->ta_pending) { + task->ta_pending++; + splx(s); + return 0; + } + + /* + * Optimise the case when all tasks have the same priority. + */ + prev = STAILQ_LAST(&queue->tq_queue); + if (!prev || prev->ta_priority >= task->ta_priority) { + STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link); + } else { + prev = 0; + for (ins = STAILQ_FIRST(&queue->tq_queue); ins; + prev = ins, ins = STAILQ_NEXT(ins, ta_link)) + if (ins->ta_priority < task->ta_priority) + break; + + if (prev) + STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); + else + STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); + } + + task->ta_pending = 1; + if (queue->tq_enqueue) + queue->tq_enqueue(queue->tq_context); + + splx(s); + + return 0; +} + +void +taskqueue_run(struct taskqueue *queue) +{ + int s; + struct task *task; + int pending; + + s = splhigh(); + while (STAILQ_FIRST(&queue->tq_queue)) { + /* + * Carefully remove the first task from the queue and + * zero its pending count. + */ + task = STAILQ_FIRST(&queue->tq_queue); + STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); + pending = task->ta_pending; + task->ta_pending = 0; + splx(s); + + task->ta_func(task->ta_context, pending); + + s = splhigh(); + } + splx(s); +} + +static void +taskqueue_swi_enqueue(void *context) +{ + setsofttq(); +} + +static void +taskqueue_swi_run(void) +{ + taskqueue_run(taskqueue_swi); +} + +TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0, + register_swi(SWI_TQ, taskqueue_swi_run)); diff --git a/usr.bin/less/Makefile b/usr.bin/less/Makefile new file mode 100644 index 000000000000..e0e25c24d81b --- /dev/null +++ b/usr.bin/less/Makefile @@ -0,0 +1,15 @@ +# $FreeBSD$ + +PROG= less +SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c decode.c \ + edit.c filename.c forwback.c help.c ifile.c input.c jump.c line.c \ + linenum.c lsystem.c mark.c optfunc.c option.c opttbl.c os.c output.c \ + position.c prompt.c search.c signal.c tags.c ttyin.c version.c +DPADD= ${LIBNCURSES} +LDADD= -lncurses +LINKS= ${BINDIR}/less /usr/bin/more +MLINKS= less.1 more.1 +CLEANFILES= ${MAN1} + +.include "Makefile.common" +.include <bsd.prog.mk> diff --git a/usr.bin/less/Makefile.common b/usr.bin/less/Makefile.common new file mode 100644 index 000000000000..6b3b62b97dab --- /dev/null +++ b/usr.bin/less/Makefile.common @@ -0,0 +1,11 @@ +# $FreeBSD$ + +LSDIR= ${.CURDIR}/../../contrib/less +.PATH: ${LSDIR} + +CFLAGS+=-I${.CURDIR}/../less -I${LSDIR} + +.SUFFIXES: .nro .1 + +.nro.1: + ln -s ${.IMPSRC} ${.TARGET} diff --git a/usr.bin/lessecho/Makefile b/usr.bin/lessecho/Makefile new file mode 100644 index 000000000000..bfe81d61f9c3 --- /dev/null +++ b/usr.bin/lessecho/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= lessecho +SRCS= lessecho.c version.c +NOMAN= + +.include "${.CURDIR}/../less/Makefile.common" +.include <bsd.prog.mk> diff --git a/usr.bin/lesskey/Makefile b/usr.bin/lesskey/Makefile new file mode 100644 index 000000000000..5c80cc607116 --- /dev/null +++ b/usr.bin/lesskey/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= lesskey +SRCS= lesskey.c version.c +CLEANFILES= ${MAN1} + +.include "${.CURDIR}/../less/Makefile.common" +.include <bsd.prog.mk> |
