Initial commit
This commit is contained in:
commit
829a2d67b2
57
Dockerfile
Normal file
57
Dockerfile
Normal file
@ -0,0 +1,57 @@
|
||||
# NAME leenooks/mbse
|
||||
# VERSION 1.0.7.12
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
curl python-pip supervisor xinetd telnetd openssh-server webfs procps less \
|
||||
zip tar arj unrar-free lhasa arc zoo lrzsz unzip logrotate joe \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
RUN mkdir -p /run/sshd
|
||||
|
||||
# Add in Leenooks' apt repository
|
||||
RUN curl -s http://apt.leenooks.net/setup.sh | sh
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --allow-unauthenticated -yqq mbse makenl goldedplus \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
ENV MBSE_ROOT /opt/mbse
|
||||
WORKDIR ${MBSE_ROOT}
|
||||
|
||||
RUN mkdir ${MBSE_ROOT}/template; \
|
||||
for dir in share home etc var log tmp ftp html; do \
|
||||
mv ${MBSE_ROOT}/${dir} ${MBSE_ROOT}/template; \
|
||||
ln -s data/${dir} ${MBSE_ROOT}/${dir}; \
|
||||
done
|
||||
|
||||
EXPOSE 23 80 24554 60177 60179
|
||||
|
||||
VOLUME [ "${MBSE_ROOT}/data" ]
|
||||
|
||||
COPY python-mbse /root/python-mbse
|
||||
RUN cd /root/python-mbse; pip install .
|
||||
|
||||
COPY xinetd.d /etc/xinetd.d
|
||||
COPY supervisord.d /etc/supervisor/conf.d/
|
||||
COPY logrotate.d /etc/logrotate.d/
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf", "-n"]
|
||||
COPY mbse.cron /etc/cron.d/mbse
|
||||
|
||||
COPY golded.sh /usr/bin
|
||||
COPY init /sbin/init
|
||||
ENTRYPOINT [ "/sbin/init" ]
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime
|
||||
|
||||
# Add ZeroTier
|
||||
RUN echo "deb http://download.zerotier.com/debian/stretch stretch main" > /etc/apt/sources.list.d/zerotier.list
|
||||
COPY zt-gpg-key /tmp/
|
||||
RUN apt-key add /tmp/zt-gpg-key
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yq zerotier-one \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
VOLUME [ "/var/lib/zerotier-one" ]
|
38
init
Executable file
38
init
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
: ${MBSE_ROOT=/opt/mbse}
|
||||
|
||||
PATH=${MBSE_ROOT}/bin:$PATH
|
||||
export PATH
|
||||
|
||||
if [ ! -d "${MBSE_ROOT}/etc" ]; then
|
||||
echo "* Installing MBSE data files into ${MBSE_ROOT}/data"
|
||||
cp -a ${MBSE_ROOT}/template/* ${MBSE_ROOT}/data
|
||||
fi
|
||||
|
||||
if [ -f "${MBSE_ROOT}/data/etc/users.data" ]; then
|
||||
echo "* Restoring passwords"
|
||||
mbse-pwfix
|
||||
fi
|
||||
|
||||
for keytype in rsa ecdsa ed25519; do
|
||||
if [ ! -f /etc/ssh/ssh_host_${keytype}_key ]; then
|
||||
echo "* Generating ${keytype} ssh key"
|
||||
/usr/libexec/openssh/sshd-keygen ${keytype}
|
||||
fi
|
||||
done
|
||||
|
||||
# clear out state and lockfiles from previous instance
|
||||
rm -f ${MBSE_ROOT}/data/var/sema/*
|
||||
rm -f ${MBSE_ROOT}/data/var/run/*
|
||||
rm -f ${MBSE_ROOT}/data/tmp/*
|
||||
|
||||
chown -R mbse:bbs ${MBSE_ROOT}/data
|
||||
|
||||
if [ -x /usr/sbin/zerotier-one -a -n "${ENABLE_ZT}" ]; then
|
||||
echo "* Starting ZeroTier"
|
||||
mkdir /dev/net && mknod /dev/net/tun -m 666 c 10 200
|
||||
/usr/sbin/zerotier-one -d
|
||||
fi
|
||||
|
||||
exec "$@"
|
7
logrotate.d/mbse
Normal file
7
logrotate.d/mbse
Normal file
@ -0,0 +1,7 @@
|
||||
/opt/mbse/data/log/*.log {
|
||||
daily
|
||||
compress
|
||||
rotate 31
|
||||
olddir /opt/mbse/data/log/old
|
||||
su mbse bbs
|
||||
}
|
0
python-mbse/mbse/__init__.py
Normal file
0
python-mbse/mbse/__init__.py
Normal file
0
python-mbse/mbse/cmd/__init__.py
Normal file
0
python-mbse/mbse/cmd/__init__.py
Normal file
79
python-mbse/mbse/cmd/pwfix.py
Normal file
79
python-mbse/mbse/cmd/pwfix.py
Normal file
@ -0,0 +1,79 @@
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import subprocess
|
||||
|
||||
from mbse.parser import parse_struct
|
||||
import mbse.fmt.users_data as users_data
|
||||
|
||||
def parse_args():
|
||||
p = argparse.ArgumentParser()
|
||||
|
||||
p.add_argument('--mbse-root', '-r', default='/opt/mbse')
|
||||
p.add_argument('--users', '-u')
|
||||
p.add_argument('--shell', '-S')
|
||||
p.add_argument('--home', '-H')
|
||||
|
||||
return p.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
logging.basicConfig(level='INFO')
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
if args.users is None:
|
||||
args.users = os.path.join(args.mbse_root, 'etc', 'users.data')
|
||||
|
||||
if args.shell is None:
|
||||
args.shell = os.path.join(args.mbse_root, 'bin', 'mbsebbs')
|
||||
|
||||
if args.home is None:
|
||||
args.home = os.path.join(args.mbse_root, 'home')
|
||||
|
||||
with open(args.users, 'r') as fd:
|
||||
hdr = parse_struct(users_data.fmt_userhdr, fd)
|
||||
|
||||
while True:
|
||||
try:
|
||||
user = parse_struct(users_data.fmt_userrec, fd)
|
||||
|
||||
# skip deleted users
|
||||
if user['flags1'] & users_data.FLAG_DELETED:
|
||||
continue
|
||||
|
||||
user['Name'] = user['Name'].rstrip('\0')
|
||||
user['sUserName'] = user['sUserName'].rstrip('\0')
|
||||
user['Password'] = user['Password'].rstrip('\0')
|
||||
|
||||
# check if users exists
|
||||
try:
|
||||
pwd.getpwnam(user['Name'])
|
||||
log.info('user %s already exists', user['Name'])
|
||||
except KeyError:
|
||||
log.info('creating user %s', user['Name'])
|
||||
subprocess.check_call([
|
||||
'useradd',
|
||||
'-c', user['sUserName'],
|
||||
'-d', os.path.join(args.home, user['Name']),
|
||||
'-s', args.shell,
|
||||
'-g', 'bbs',
|
||||
'-M', '-N',
|
||||
user['Name']
|
||||
])
|
||||
|
||||
log.info('fixing permissions on home directory')
|
||||
subprocess.check_call([
|
||||
'chown', '-R', user['Name'],
|
||||
os.path.join(args.home, user['Name'])])
|
||||
|
||||
log.info('setting password for user %s', user['Name'])
|
||||
p = subprocess.Popen(['chpasswd'], stdin=subprocess.PIPE)
|
||||
|
||||
p.communicate(input=user['Name']+':'+user['Password'])
|
||||
except EOFError:
|
||||
break
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
0
python-mbse/mbse/fmt/__init__.py
Normal file
0
python-mbse/mbse/fmt/__init__.py
Normal file
96
python-mbse/mbse/fmt/users_data.py
Normal file
96
python-mbse/mbse/fmt/users_data.py
Normal file
@ -0,0 +1,96 @@
|
||||
fmt_userhdr = (
|
||||
('hdrsize', 'I'),
|
||||
('recsize', 'I'),
|
||||
)
|
||||
|
||||
fmt_securityrec = (
|
||||
('level', 'I'),
|
||||
('flags', 'I'),
|
||||
('notflags', 'I'),
|
||||
)
|
||||
|
||||
fmt_userrec = (
|
||||
('sUserName', '36s'),
|
||||
('Name', '9s'),
|
||||
('xPassword', 'I'),
|
||||
('sVoicePhone', '20s'),
|
||||
('sDataPhone', '20s'),
|
||||
('sLocation', '28s'),
|
||||
('sAddress', ('41s',)*3),
|
||||
('sDataOfBirth', '12s'),
|
||||
('tFirstLoginDate', 'I'),
|
||||
('tLastLoginDate', 'I'),
|
||||
('Security', None, fmt_securityrec),
|
||||
('sComment', '81s'),
|
||||
('sExpiryDate', '12s'),
|
||||
('ExpirySec', None, fmt_securityrec),
|
||||
('sSex', '8s'),
|
||||
|
||||
('flags1', 'B'),
|
||||
('flags2', 'B'),
|
||||
|
||||
('iTotalCalls', 'I'),
|
||||
('iTimeLeft', 'I'),
|
||||
('iConnectTime', 'I'),
|
||||
('iTimeUsed', 'I'),
|
||||
('xScreenLen', 'I'),
|
||||
('tLastPwdChange', 'I'),
|
||||
('xHangUps', 'I'),
|
||||
('Credit', 'I'),
|
||||
('Paged', 'I'),
|
||||
('MsgEditor', 'I'),
|
||||
('LastPktNum', 'I'),
|
||||
('Archiver', '6s'),
|
||||
('iLastFileArea', 'I'),
|
||||
('iLastFileGroup', 'I'),
|
||||
('sProtocol', '21s'),
|
||||
('Downloads', 'I'),
|
||||
('Uploads', 'I'),
|
||||
('UploadK', 'I'),
|
||||
('DownloadK', 'I'),
|
||||
('DownloadKToday', 'I'),
|
||||
('UploadKToday', 'I'),
|
||||
('iLastMsgArea', 'I'),
|
||||
('iTransferTime', 'I'),
|
||||
('iLastMsgGroup', 'I'),
|
||||
('iPosted', 'I'),
|
||||
('iLanguage', 'I'),
|
||||
('sHandle', '36s'),
|
||||
('iStatus', 'I'),
|
||||
('DownloadsToday', 'I'),
|
||||
('CrtDef', 'I'),
|
||||
('Protocol', 'I'),
|
||||
('flags3', 'B'),
|
||||
('Password', '15s'),
|
||||
('Charset', 'I'),
|
||||
('OLRext', 'I'),
|
||||
('OLRlast', '12s'),
|
||||
)
|
||||
|
||||
# flags2
|
||||
FLAG_HIDDEN = 1
|
||||
FLAG_HOTKEYS = 1 << 1
|
||||
FLAG_XGRAPHMODE = 1 << 2
|
||||
FLAG_DELETED = 1 << 3
|
||||
FLAG_NEVERDELETE = 1 << 4
|
||||
FLAG_XCHAT = 1 << 5
|
||||
FLAG_LOCKEDOUT = 1 << 6
|
||||
FLAG_DONOTDISTURB = 1 << 7
|
||||
|
||||
# flags2
|
||||
FLAG_CLS = 1
|
||||
FLAG_MORE = 1 << 1
|
||||
FLAG_XFSMSGED = 1 << 2
|
||||
FLAG_MAILSCAN = 1 << 3
|
||||
FLAG_GUEST = 1 << 4
|
||||
FLAG_OL_EXTINFO = 1 << 5
|
||||
|
||||
# flags3
|
||||
FLAG_IEMSI = 1
|
||||
FLAG_IEMNU = 1 << 1
|
||||
FLAG_IETAB = 1 << 2
|
||||
FLAG_IEASCII8 = 1 << 3
|
||||
FLAG_IENEWS = 1 << 4
|
||||
FLAG_IEFILE = 1 << 5
|
||||
FLAG_EMAIL = 1 << 6
|
||||
FLAG_FSEMACS = 1 << 7
|
35
python-mbse/mbse/parser.py
Normal file
35
python-mbse/mbse/parser.py
Normal file
@ -0,0 +1,35 @@
|
||||
import struct
|
||||
|
||||
def read_one(name, spec, fd):
|
||||
rsize = struct.calcsize(spec)
|
||||
raw = fd.read(rsize)
|
||||
|
||||
if not len(raw):
|
||||
raise EOFError()
|
||||
if len(raw) != rsize:
|
||||
raise ValueError('read %d bytes, expected %d' % (len(raw), rsize))
|
||||
|
||||
data = struct.unpack(spec, raw)[0]
|
||||
|
||||
return data
|
||||
|
||||
def parse_struct(spec, fd):
|
||||
parsed = {}
|
||||
|
||||
for fldspec in spec:
|
||||
try:
|
||||
fld, spec, sub = fldspec
|
||||
except ValueError:
|
||||
sub = None
|
||||
fld, spec = fldspec
|
||||
|
||||
if sub:
|
||||
data = parse_struct(sub, fd)
|
||||
elif isinstance(spec, tuple):
|
||||
data = [read_one(fld, s, fd) for s in spec]
|
||||
else:
|
||||
data = read_one(fld, spec, fd)
|
||||
|
||||
parsed[fld] = data
|
||||
|
||||
return parsed
|
12
python-mbse/setup.py
Normal file
12
python-mbse/setup.py
Normal file
@ -0,0 +1,12 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
version='1.0.0',
|
||||
name='mbse',
|
||||
packages=setuptools.find_packages(),
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'mbse-pwfix = mbse.cmd.pwfix:main',
|
||||
],
|
||||
}
|
||||
)
|
3
supervisord.d/bbs.conf
Normal file
3
supervisord.d/bbs.conf
Normal file
@ -0,0 +1,3 @@
|
||||
[program:mbtask]
|
||||
command=%(ENV_MBSE_ROOT)s/bin/mbtask -nd
|
||||
user=mbse
|
2
supervisord.d/cron.conf
Normal file
2
supervisord.d/cron.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[program:cron]
|
||||
command=/usr/sbin/cron -f
|
2
supervisord.d/ssh-server.conf
Normal file
2
supervisord.d/ssh-server.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[program:sshd]
|
||||
command=/usr/sbin/sshd -D
|
2
supervisord.d/web-server.conf
Normal file
2
supervisord.d/web-server.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[program:webfs]
|
||||
command=/usr/bin/webfsd -Fp 80 -r /opt/mbse/data/html -f index.html
|
2
supervisord.d/xinetd.conf
Normal file
2
supervisord.d/xinetd.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[program:xinetd]
|
||||
command=/usr/sbin/xinetd -dontfork
|
10
xinetd.d/binkp
Normal file
10
xinetd.d/binkp
Normal file
@ -0,0 +1,10 @@
|
||||
service binkp
|
||||
{
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = mbse
|
||||
instances = 10
|
||||
server = /opt/mbse/bin/mbcico
|
||||
server_args = -t ibn
|
||||
}
|
10
xinetd.d/fido
Normal file
10
xinetd.d/fido
Normal file
@ -0,0 +1,10 @@
|
||||
service fido
|
||||
{
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = mbse
|
||||
instances = 10
|
||||
server = /opt/mbse/bin/mbcico
|
||||
server_args = -t ifc
|
||||
}
|
15
xinetd.d/telnet
Normal file
15
xinetd.d/telnet
Normal file
@ -0,0 +1,15 @@
|
||||
service telnet
|
||||
{
|
||||
disable = no
|
||||
protocol = tcp
|
||||
instances = 10
|
||||
flags = REUSE
|
||||
log_on_failure += USERID
|
||||
socket_type = stream
|
||||
user = root
|
||||
server = /usr/sbin/in.telnetd
|
||||
server_args = -L /opt/mbse/bin/mblogin
|
||||
wait = no
|
||||
}
|
||||
|
||||
|
10
xinetd.d/tfido
Normal file
10
xinetd.d/tfido
Normal file
@ -0,0 +1,10 @@
|
||||
service tfido
|
||||
{
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = mbse
|
||||
instances = 10
|
||||
server = /opt/mbse/bin/mbcico
|
||||
server_args = -t itn
|
||||
}
|
52
zt-gpg-key
Normal file
52
zt-gpg-key
Normal file
@ -0,0 +1,52 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: GPGTools - https://gpgtools.org
|
||||
|
||||
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
|
||||
=JgAv
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
Reference in New Issue
Block a user