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