Exemple #1
0
  def __init__(self, db, address, password, filename, length):
    print("from",address,"pw",password,"recv",filename,"len",length)

    # based on length choose to process data in memory (check received data length)
    # or save to disk
    # packets
    # bundles
    # freqs
    # tics
    # files

    self.db = db
    self.address = address
    if password is not None:
      if password == get_link_password(db, address):
        self.protected = True
      else:
        raise FTNWrongPassword()
    else:
      self.protected = False

    savedir = inbound_dir(address, self.protected, True)
    if not os.path.exists(savedir):
      os.makedirs(savedir)
    mod = 0
    while True:
      try:
        self.file = os.path.join(savedir, modname(filename, mod))
        self.fo = os.fdopen(os.open(self.file, os.O_CREAT | os.O_EXCL | os.O_WRONLY), "wb") # should add  | os.O_BINARY
        break
      except OSError as e:
        if e.args[0]!=17:
          raise e

      mod += 1
Exemple #2
0
                for link_id in ftnconfig.find_link(node):
                    my, pw = ftnaccess.link_password(db, link_id, True)
                    # FIX choose sender address (=my)
                    sess.send_message(ftnconfig.SYSOP, ("node", node), robot,
                                      None, pw, "-" + area)

            sess.forget_address(domain, area)

    exit()

exit()

# ???
outp = []

pw = ftnconfig.get_link_password(db, link, True)
#print(pw)

for echo in db.prepare(
        "select a.text from subscriptions s, addresses a "
        "where a.id=s.target and s.subscriber=$1 and a.domain=$2")(
            lid, db.FTN_domains[domain]):

    outp.append("+" + echo[0] + "\n")

if len(outp) == 0:
    print("nothing to relink")
else:
    print("".join(outp))

    with ftnimport.session(db) as sess:
Exemple #3
0
from socketutil import *

try:
  os.mkdir("test")
except:
  pass

if not os.path.isdir("test"):
  print ("please make dir test")
  exit()

s = socket.socket(socket.AF_INET)

import ftnconfig
db=ftnconfig.connectdb()
password = ftnconfig.get_link_password(db, address)
print (address, password)

do_send = False

s.connect(("127.0.0.1", 24555))
try:
  print(readline(s))

  s.send(b"ADDRESS "+address.encode(encoding)+b"\n")
  s.send(b"PASSWORD "+password.encode(encoding)+b"\n")

  if do_send:
    s.send(b"FILENAME test1.dat\n")
    s.send(b"BINARY 100\n")
    s.send(b"*"*100)
Exemple #4
0
#for k, v in hubs.items():
#  print ("%-17s: "%k, ", ".join(v))
#print ()
#exit()

downlinks = ftnexport.get_subnodes(db, ADDRESS)
#print (downlinks)
#exit()

selfsubscribers = set()
selfsubscribers.add(ADDRESS)
selfsubscribers.add(ADDRESS+".999")

# filter links that are not password-protected
for x in list(links) + downlinks:
  if not get_link_password(db, x):
    print ("skip", x)
  else:
    selfsubscribers.add(x)

#print ("direct links =", ", ".join(selfsubscribers))

# add subscription for self
for l in selfsubscribers:
  hubs.setdefault(l, set()).add(l)

#print ("subscriptions")
#for k, v in hubs.items():
#  print ("subscribe %s to"%k, ", ".join(v))
#print ()
#exit()
Exemple #5
0
from ftnconfig import connectdb, get_link_password

db = connectdb()

fareas = {}

for a, b in db.prepare(
        "select t.text, sr.text from subscriptions s, addresses sr, addresses t "
        "where s.subscriber=sr.id and s.target=t.id and t.domain=3")():
    fareas.setdefault(a, set()).add(b)

fa = open("fareas.bbs", "w")
fa.write("*****\n")
for k, v in fareas.items():
    fa.write("/tank/home/fido/fareas/" + k.lower() + " " + k + " " +
             " ".join(v) + "\n")
fa.close()

pw = open("passwd", "w")

for a in db.prepare("select a.text from links l, addresses a "
                    "where l.address=a.id and a.domain=$1 order by a.text")(
                        db.FTN_domains["node"]):
    #print (a[0])

    linkpw = get_link_password(db, a[0])
    if linkpw is not None:
        pw.write("password %-23s %s\n" % (a[0], linkpw))

pw.close()
Exemple #6
0
    def feed(self, d):
        self.b.write(d)
        print(len(d), "bytes added")


db = ftnconfig.connectdb()

for lid, addr, conn in db.prepare("select id, address, connection from links"):
    if conn is not None:
        ftp = conn.find("FTP")
        if ftp is not None:
            #print (addr, ftp.keys(), ftp.get("host"))
            domain, address = ftnconfig.get_addr(db, addr)
            link_pkt_format = ftnconfig.get_link_pkt_format(db, address)
            password = ftnconfig.get_link_password(db, address)

            print(ftp.get("username"), ftp.get("password"), ftp.get("host"),
                  ftp.get("port", 0))

            with ftplib.FTP() as ftpc:
                ftpc.connect(host=ftp.get("host"),
                             port=int(ftp.get("port", 0)))
                ftpc.login(user=ftp.get("username"),
                           passwd=ftp.get("password"))
                #print (ftpc.getwelcome())
                ftpc.set_pasv(ast.literal_eval(ftp.get("passive", "False")))

                path = ftp.get("getfrom")
                print(path)
                if path:
Exemple #7
0
#!/usr/local/bin/python3

link = '2:5020/1042'
list = 'lists/GFD.txt'
orphans = list  #'upl'
domain = 'fileecho'
oldlink = ['2:5020/758', '2:5020/1200']

robotname = ftnconfig.robotnames[domain]

import ftnconfig
import ftnimport

db = ftnconfig.connectdb()
pw = ftnconfig.get_link_password(db, link, forrobots=True)

pwold = {}
for ol in oldlink:
    pwold[ol] = ftnconfig.get_link_password(db, ol, forrobots=True)

avail = set()
for l in open(list):
    avail.add(l.strip().upper())

orphan = set()
for l in open(orphans):
    orphan.add(l.strip().upper())

print(len(orphan), len(avail), len(orphan.intersection(avail)))

with ftnimport.session(db) as sess:
Exemple #8
0
try:
  cmd = sys.argv[1]
  domain = sys.argv[2]
  area = sys.argv[3]
  subscriber = sys.argv[4]
except:
  print("usage: ./util_subscription.py add|addvital|remove echo|fileecho AREANAME 2:5020/9999")
  exit()

try:
  robot = ftnconfig.robotnames[domain]
except:
  raise Exception("cannot manage subscriptions in domain", domain)

pw = ftnconfig.get_link_password(db, subscriber, forrobots=True)

with ftnimport.session(db) as sess:
  if cmd == "add":
    try:
      sess.add_subscription(None, domain, area, subscriber)
    except FTNAlreadySubscribed:
      print ("local subscription exists")
    if subscriber != ftnconfig.ADDRESS:
      sess.send_message(ftnconfig.SYSOP, ("node", subscriber), robot, None, pw, "+"+area, sendmode="direct")
    else:
      print ("local subscription")

  elif cmd == "remove":
    sess.remove_subscription(domain, area, subscriber)
    if subscriber != ftnconfig.ADDRESS:
Exemple #9
0
#!/usr/local/bin/python3 -bb

from ftnconfig import connectdb, get_link_password

db=connectdb()

fareas={}

for a, b in db.prepare("select t.text, sr.text from subscriptions s, addresses sr, addresses t "
            "where s.subscriber=sr.id and s.target=t.id and t.domain=3")():
  fareas.setdefault(a, set()).add(b)

fa=open("/tank/home/fido/fareas.bbs", "w")
fa.write("*****\n")
for k, v in fareas.items():
  fa.write("/tank/home/fido/fareas/"+k.lower()+" "+k+" "+" ".join(v)+"\n")
fa.close()


pw=open("/tank/home/fido/passwd", "w")

for a in db.prepare("select a.text from links l, addresses a "
            "where l.address=a.id and a.domain=$1 order by a.text")(db.FTN_domains["node"]):
  #print (a[0])

  linkpw = get_link_password(db, a[0])
  if linkpw is not None:
    pw.write("password %-23s %s\n"%(a[0], linkpw))

pw.close()
Exemple #10
0
link='2:5020/1042'
domain = "fileecho"

import ftnconfig
import ftnimport

robot = ftnconfig.robotnames[domain]

db=ftnconfig.connectdb()

lid = ftnconfig.get_addr_id(db, db.FTN_domains["node"], link)

outp=[]

pw = ftnconfig.get_link_password(db, link, True)
#print(pw)

for echo in db.prepare("select a.text from subscriptions s, addresses a "
            "where a.id=s.target and s.subscriber=$1 and a.domain=$2")(lid, db.FTN_domains[domain]):

    outp.append("+"+echo[0]+"\n")

if len(outp)==0:
    print ("nothing to relink")
else:
    print ("".join(outp))

    with ftnimport.session(db) as sess:
        sess.send_message("Sergey Dorofeev", ("node", link),
                            robot, None, pw, "".join(outp))
Exemple #11
0
db=ftnconfig.connectdb()

domain=sys.argv[1]
area=sys.argv[2].upper()

print ("pq://*****:*****@host/database")
db=ftnconfig.connectdb(input("enter connection string for admin connection: "))

robot = ftnconfig.robotnames[domain]

addr_id = ftnconfig.get_addr_id(db, db.FTN_domains[domain], area)
print (addr_id)
#msg_from = db.prepare("select count (*) from messages where source=$1")(addr_id)
#print ("from:", msg_from)
#msg_from = db.prepare("select count (*) from messages where destination=$1")(addr_id)
#print ("to:", msg_from)

assert( input("enter 'yes' to confirm: ")=="yes" )

with ftnimport.session(db) as sess:
  for (link_addr,subs_id) in db.prepare("select a.text, s.id from addresses a, subscriptions s where a.id=s.subscriber and s.target=$1")(addr_id):
    print ("unsubscribing",link_addr)
    db.prepare("delete from subscriptions where id=$1")(subs_id)
    pw=ftnconfig.get_link_password(db, link_addr, forrobots=True)
    sess.send_message(ftnconfig.SYSOP, ("node", link_addr), robot, None, pw, "-"+area, sendmode="direct")
  sess.send_message(ftnconfig.SYSOP, ("echo", "FLUID.LOCAL"), "All", None, "removal", domain+" "+area+" removed from node")
  db.prepare("delete from addresses where id=$1")(addr_id)

exit()
Exemple #12
0
#!/usr/local/bin/python3

link = '2:5020/1042'
list = 'lists/GFD.txt'
orphans = list #'upl'
domain = 'fileecho'
oldlink = ['2:5020/758', '2:5020/1200']

robotname = ftnconfig.robotnames[domain]

import ftnconfig
import ftnimport

db=ftnconfig.connectdb()
pw = ftnconfig.get_link_password(db, link, forrobots=True)

pwold = {}
for ol in oldlink: 
  pwold[ol] = ftnconfig.get_link_password(db, ol, forrobots=True)


avail = set()
for l in open(list):
  avail.add(l.strip().upper())

orphan = set()
for l in open(orphans):
  orphan.add(l.strip().upper())

print (len(orphan), len(avail), len(orphan.intersection(avail)))
Exemple #13
0
#!/usr/local/bin/python3 -bb

import ftnconfig
import ftnimport

db = ftnconfig.connectdb()

area = "FLUID.LOCAL"

robot = ftnconfig.robotnames["echo"]

with ftnimport.session(db) as sess:
    for (link_addr, ) in db.prepare(
            "select a.text from links l, addresses a where a.id=l.address"):
        print(link_addr)
        sess.add_subscription(None, "echo", area, link_addr)
        pw = ftnconfig.get_link_password(db, link_addr, forrobots=True)
        sess.send_message(ftnconfig.SYSOP, ("node", link_addr),
                          robot,
                          None,
                          pw,
                          "+" + area,
                          sendmode="direct")
Exemple #14
0
def file_export(db, address, password, what):
  """ This generator fetches messages from database and
      yields objects, that contain the file information
      and instructions how to commit to db inforamtion
      about successful message delivery """

    # first netmail
    # then requested file
    # then echoes
    # then filebox
    # and at last fileechoes

  print("export to", repr(address), repr(password), repr(what))

  if password != (get_link_password(db, address) or ""):
      raise FTNWrongPassword()

  print("password is correct" if password else "password is empty")


  # WARNING!
  # unprotected sessions never must do queries as it may result in leaking netmail
  # if address of some hub is spoofed

  addr_id = get_addr_id(db, db.FTN_domains["node"], address)
  link_pkt_format = get_link_pkt_format(db, address)
  link_bundler = get_link_bundler(db, address)


  if password and ("netmail" in what):
    explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["netmail"], addr_id)))
    if explock.acquire(False):
      try:

        print ("exporting netmail")
    # only vital subscriptions is processed
    # non-vital (CC) should be processed just like echomail

    # set password in netmail packets
        p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: netmailcommitter())

    #..firstly send pkts in outbound
        for id_msg, src, dest, msgid, header, body, origcharset, recvfrom in get_subscriber_messages_n(db, addr_id, db.FTN_domains["node"]):

          print("netmail %d recvfrom %d pack to %s"%(id_msg, recvfrom, repr(address)))

      # if exporting to utf8z always use UTF-8
          if link_pkt_format == "utf8z":
            origcharset = "utf-8"

          myvia = "PyFTN " + ADDRESS + " " + time.asctime()
          srca=db.prepare("select domain, text from addresses where id=$1").first(src)
          dsta=db.prepare("select domain, text from addresses where id=$1").first(dest)

          try:
            msg, msgcharset = denormalize_message(
            (db.FTN_backdomains[srca[0]], srca[1]),
            (db.FTN_backdomains[dsta[0]], dsta[1]),
            msgid, header, body, origcharset, address, addvia = myvia)
          except:
            raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc())

          try:
            print ("export msg attributes", msg.attr)
          except:
            traceback.print_exception()

          if 'AuditRequest' in ftn.attr.binary_to_text(msg.attr):
            audit_reply = (db.FTN_backdomains[srca[0]], srca[1]), header.find("sendername").text, address, msg, msgcharset
          else:
            audit_reply = None

          for x in p.add_item(msg, (id_msg, audit_reply)): # add ARQ flag
            yield x

        for x in p.flush():
          yield x

        del p

      finally:
        explock.release()
    else:
      print ("could not acquire netmail lock")

  if "direct" in what: # available for unprotected sessions
    # export messages with processed==8 and destination==addr_id
   explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["netmail"], addr_id)))
   if explock.acquire(False):

    print ("exporting direct netmail")
    # only vital subscriptions is processed
    # non-vital (CC) should be processed just like echomail

    # set password in netmail packets
    link_id=get_link_id(db, address, withfailback=True)
    p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, link_id), lambda: netmailcommitter(newstatus=7))

    #..firstly send pkts in outbound
    for id_msg, src, dest, msgid, header, body, origcharset, recvfrom in get_direct_messages(db, addr_id):

      print("direct netmail %d recvfrom %d pack to %s"%(id_msg, recvfrom, repr(address)))

      # if exporting to utf8z always use UTF-8
      if link_pkt_format == "utf8z":
        origcharset = "utf-8"

      myvia = "PyFTN " + ADDRESS + " DIRECT " + time.asctime()
      srca=db.prepare("select domain, text from addresses where id=$1").first(src)
      dsta=db.prepare("select domain, text from addresses where id=$1").first(dest)

      try:
        msg, msgcharset = denormalize_message(
            (db.FTN_backdomains[srca[0]], srca[1]),
            (db.FTN_backdomains[dsta[0]], dsta[1]), 
            msgid, header, body, origcharset, address, addvia = myvia)
      except:
        raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc())

      try:
        print ("export msg attributes", msg.attr)
      except:
        traceback.print_exception()

      if 'AuditRequest' in ftn.attr.binary_to_text(msg.attr):
        audit_reply = (db.FTN_backdomains[srca[0]], srca[1]), header.find("sendername").text, address, msg, msgcharset
      else:
        audit_reply = None

      for x in p.add_item(msg, (id_msg, audit_reply)): # add ARQ flag
        yield x

    for x in p.flush():
      yield x

    del p

    explock.release()
    pass

  if password and ("echomail" in what):
    explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["echomail"], addr_id)))
    if explock.acquire(False):
      try:
        print ("exporting echomail")
        #..firstly send bundles in outbound

        #

        if link_bundler:
          p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: echomailcommitter(),
            bundlepacker(link_bundler, address, lambda: get_bundle_n(db, get_link_id(db, address)), lambda: echomailcommitter()))
        else:
          p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: echomailcommitter())

        subscache = {}
        for id_msg, xxsrc, dest, msgid, header, body, origcharset, recvfrom, withsubscr, processed in get_subscriber_messages_e(db, addr_id, db.FTN_domains["echo"]):

          will_export = True # do we really must send message or just update last_sent pointer

          #print("echomail %d"%id_msg, repr(dest))
          #print("dest %d recvfrom %s subscr %s pack to %s"%(dest, repr(recvfrom), repr(withsubscr), address))
          # ignore src - for echomail it is just recv_from

          # if exporting to utf8z always use UTF-8
          if link_pkt_format == "utf8z":
            origcharset = "utf-8"

          if recvfrom == addr_id:
            #print ("Message from this link, will not export")
            will_export = False

          if processed == 5:
            #print ("Archived message, will not export")
            will_export = False

          # check commuter
          subscriber_comm = db.FTN_commuter.get(withsubscr)
          if subscriber_comm is not None: # must check as None==None => no export at all
            # get subscription through what message was received
            recvfrom_subscription = db.prepare("select id from subscriptions where target=$1 and subscriber=$2").first(sub_tart, m_recvfrom)
            recvfrom_comm = db.FTN_commuter.get(recvfrom_subscription)
            if recvfrom_comm == subscriber_comm:
              print("commuter %d - %d, will not export"%(withsubscr, recvfrom_subscription))
              will_export = False
    #          continue # do not forward between subscriptions in one commuter group (e.g. two uplinks)

          if dest in subscache:
            subscribers = subscache[dest]
          else:
            subscribers = db.prepare("select a.domain, a.text from subscriptions s, addresses a where s.target=$1 and s.subscriber=a.id")(dest)

            if not all([x[0]==db.FTN_domains["node"] for x in subscribers]):
              raise FTNFail("subscribers from wrong domain for "+str(sub_targ))

            #    print(sub_id, sub_targ, "all subscribers:", [x[1] for x in subscribers])

            subscribers = subscache[dest] = [x[1] for x in subscribers]

          #print("subscribers:", repr(subscribers))

    #      if withsubscr not in subscribers:
    #        raise Exception("strange: exporting to non-existent subscription", withsubscr)

          dsta = db.prepare("select domain, text from addresses where id=$1").first(dest)

          # modify path and seen-by
          # seen-by's - get list of all subscribers of this target; add subscribers list
          #... if go to another zone remove path and seen-by's and only add seen-by's of that zone -> ftnexport

          if will_export: # create MSG else do not bother
           try:
            msg, msgcharset = denormalize_message( 
                ("node", ADDRESS),
                (db.FTN_backdomains[dsta[0]], dsta[1]), 
                msgid, header, body, origcharset, address, addseenby=subscribers, addpath=ADDRESS)
           except:
            raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc())

          for x in p.add_item((msg if will_export else None), (withsubscr, id_msg)):
            yield x

        for x in p.flush():
          yield x

      finally:
        explock.release()
    else:
      print("could not acquire echomail lock")

  if password and ("filebox" in what):
   explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["filebox"], addr_id)))
   if explock.acquire(False):
    # ..send freq filebox
    print ("exporting filebox")
    dsend = addrdir(DOUTBOUND, address)
    if os.path.isdir(dsend):
      print ("exporting daemon outbound")
      for f in os.listdir(dsend):
        fname = os.path.join(dsend, f)
        if os.path.isfile(fname):
          obj = outfile()
          obj.data = open(fname, "rb")
          obj.filename = f
          obj.length = os.path.getsize(fname)
          yield obj, filecommitter(fname)

    explock.release()


  if password and ("fileecho" in what):
   explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["fileecho"], addr_id)))
   if explock.acquire(False):
    # ..send fileechoes
    print ("exporting fileechoes (nothing here)")
    pass #1/0
    explock.release()

  return