created mirror

This commit is contained in:
whatever
2026-09-14 20:19:29 -04:00
commit 6764738d92
600 changed files with 87187 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
/*
PutMessage.java
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.io.*;
import java.util.*;
class GetMessage implements Session.Message {
public static boolean dbg = false;
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
private static void pa(String s) { ZZLogger.log(s); }
static String prefix = PutMessage.prefix;
public String name() { return "GET"; }
public String help() { return "Gets a subspace from the server"; }
public int prereqs() { return Session.FL_AUTH; }
public void invoke(Session sess, String[] args) throws IOException {
LineBufferedIO io = sess.getIO();
ZZSpace space = sess.space;
if (args.length != 1) {
io.writeln("5.0.1 Syntax: GET <subspace>");
return;
}
if (!args[0].equals("ALL")) {
io.writeln("5.4.1 No such subspace");
return;
}
io.writeln("3.4.1 Proceeding with subspace data ...");
synchronized (space) {
// Find all relevant dimensions
String[] dims;
{
Vector dimv = new Vector();
for (ZZCell c = space.getHomeCell().s("d.masterdim", 1); c != null;
c = c.s("d.masterdim", 1)) {
String name = c.getText();
if (name.length() >= prefix.length()
&& name.substring(0, prefix.length()).equals(prefix)) {
dimv.addElement(name.substring(prefix.length()));
}
}
dims = new String[dimv.size()];
for (int i = 0; i < dims.length; i++) {
dims[i] = (String)dimv.elementAt(i);
}
}
class Enum implements Enumeration {
Enumeration e;
Object cur;
private void Cur() {
cur = null;
while (e.hasMoreElements()) {
cur = e.nextElement();
ZZCell c = (ZZCell)cur;
p("considering " + c);
if (c.getID().substring(0, prefix.length()).equals(prefix))
p("OK");
break;
}
}
public Enum(Enumeration e) {
this.e = e;
Cur();
}
public boolean hasMoreElements() {
return cur != null;
}
public Object nextElement() {
Object rv = cur;
if (rv == null) throw new NoSuchElementException();
Cur();
p("nextElement = " + rv);
return rv;
}
};
SubspaceDump.dump(io,
new Enum(space.getHomeCell().s("d.ztpspace").enumRank("d.ztpspace")),
dims, prefix);
}
io.writeln("2.4.1 Subspace successfully got");
}
}

View File

@@ -0,0 +1,55 @@
/*
Listener.java
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.net.*;
import java.io.*;
public class Listener extends Thread {
public static boolean dbg = false;
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
private static void pa(String s) { ZZLogger.log(s); }
private ZZSpace space;
private ServerSocket lsock;
public Listener(ZZSpace space, ServerSocket lsock) {
this.space = space;
this.lsock = lsock;
}
public void run() {
pa("Listener starts");
while (!isInterrupted()) {
try {
p("waiting for connections");
Socket csock = lsock.accept();
p("connection request received");
Session sess = new Session(space, csock);
sess.start();
} catch (IOException e) {
ZZLogger.exc(e);
}
}
pa("Listener stops");
}
}

View File

@@ -0,0 +1,117 @@
/*
PutMessage.java
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.io.*;
import java.util.*;
class PutMessage implements Session.Message {
public static boolean dbg = false;
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
private static void pa(String s) { ZZLogger.log(s); }
static String prefix = "ztpspace!";
public String name() { return "PUT"; }
public String help() { return "Puts a subspace to the server"; }
public int prereqs() { return Session.FL_AUTH; }
public void invoke(Session sess, String[] args) throws IOException {
LineBufferedIO io = sess.getIO();
ZZSpace space = sess.space;
if (args.length != 1) {
io.writeln("5.0.1 Syntax: PUT <subspace>");
return;
}
if (!args[0].equals("ALL")) {
io.writeln("5.4.1 No such subspace");
return;
}
io.writeln("3.4.0 Please proceed with subspace data, end with 'F'");
SubspaceDump sd;
try {
sd = new SubspaceDump(io);
} catch (SubspaceDump.AbortedException e) {
io.writeln("5.4.0 " + e.getMessage());
return;
} catch (SyntaxError e) {
io.writeln("5.0.1 " + e.getMessage());
return;
}
// Verify that the cells all have a good ID.
for (Enumeration e = sd.cellids.keys(); e.hasMoreElements();) {
String s = (String)e.nextElement();
if (s.indexOf("@") == -1) {
io.writeln("5.4.2 Cannot put cells lacking a space ID");
return;
}
}
synchronized (space) {
// Delete old subspace
for (ZZCell c = space.getHomeCell().s("d.ztpspace", 1); c != null; ) {
ZZCell s = c.s("d.ztpspace", 1);
if (c.getID().substring(0, prefix.length()).equals(prefix)) {
c.delete();
}
c = s;
}
// Create the new subspace
{
ZZCell oc = space.getHomeCell();
for (Enumeration e = sd.cellids.keys(); e.hasMoreElements();) {
String s = (String)e.nextElement();
ZZCell c = space.getCellByID(prefix + s);
oc.connect("d.ztpspace", 1, c);
oc = c;
}
}
for (Enumeration e = sd.content.keys(); e.hasMoreElements();) {
String s = (String)e.nextElement();
ZZCell c = space.getCellByID(prefix + s);
c.setText((String)sd.content.get(s));
}
for (Enumeration e = sd.dims.keys(); e.hasMoreElements();) {
String dimname = (String)e.nextElement();
Hashtable dim = (Hashtable)sd.dims.get(dimname);
((ZZDimSpace)space).d(dimname);
for (Enumeration f = dim.keys(); f.hasMoreElements();) {
String s1 = (String)f.nextElement();
String s2 = (String)dim.get(s1);
ZZCell c1 = space.getCellByID(prefix + s1);
ZZCell c2 = space.getCellByID(prefix + s2);
c1.connect(prefix + dimname, c2);
}
}
space.commit();
}
io.writeln("2.4.0 Subspace successfully put");
}
}

View File

@@ -0,0 +1,227 @@
/*
Session.java
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.net.*;
import java.io.*;
import java.util.*;
public class Session extends Thread {
public static boolean dbg = false;
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
private static void pa(String s) { ZZLogger.log(s); }
public ZZSpace space;
private Socket socket = null;
interface Message {
String name();
String help();
int prereqs();
void invoke(Session sess, String[] args) throws IOException;
}
private LineBufferedIO io;
private boolean proper_close = false;
public LineBufferedIO getIO() { return io; }
private UserManager userManager;
public UserManager getUserManager() { return userManager; }
// prereq constants (orred)
static final int FL_AUTH = 1;
static final int FL_SAP = 2;
private int reqstatus;
public String user;
public void setFlag(int flag) { reqstatus |= flag; }
public void clearFlag(int flag) { reqstatus &= ~flag; }
private void login(UserRecord ur) throws IOException {
try {
if (ur.sap) {
setFlag(FL_SAP);
} else {
clearFlag(FL_SAP);
}
user = ur.username;
setFlag(FL_AUTH);
io.writeln("2.3.0 OK");
if (socket != null) {
pa("connection from " + socket.getInetAddress().getHostName()
+ " authenticated as " + user);
}
} catch (Throwable e) {
clearFlag(FL_AUTH);
ZZLogger.exc(e);
io.writeln("4.3.0 Problem authenticating user");
}
}
Message[] messages = {
new Message() {
public String name() { return "QUIT"; }
public String help() { return "Quit the session"; }
public int prereqs() { return 0; }
public void invoke(Session ses, String[] args) throws IOException {
clearFlag(FL_AUTH);
ses.interrupt();
ses.proper_close = true;
ses.io.writeln("2.2.1 Be seeing you");
}
},
new Message() {
public String name() { return "AUTH/PRE"; }
public String help() { return "Request preauthentication"; }
public int prereqs() { return 0; }
public void invoke(Session ses, String[] args) throws IOException {
LineBufferedIO io = ses.getIO();
if (args.length != 1) {
io.writeln("5.0.1 Syntax: AUTH/PRE <username>");
return;
}
UserRecord ur = ses.getUserManager().access(args[0]);
if (ur == null || !ur.auth_pre) {
io.writeln("5.3.0 Access denied");
return;
}
if (ur.susp) {
io.writeln("5.3.1 User disabled");
return;
}
ses.login(ur);
}
},
new Message() {
public String name() { return "AUTH/PASS"; }
public String help() { return "Request password authentication"; }
public int prereqs() { return 0; }
public void invoke(Session ses, String[] args) throws IOException {
LineBufferedIO io = ses.getIO();
if (args.length != 2) {
io.writeln("5.0.1 Syntax: AUTH/PASS <username> <password>");
return;
}
UserRecord ur = ses.getUserManager().access(args[0]);
if (ur == null || !ur.auth_pass || !ur.password.equals(args[1])) {
io.writeln("5.3.0 Access denied");
return;
}
if (ur.susp) {
io.writeln("5.3.1 User disabled");
return;
}
ses.login(ur);
}
},
new PutMessage(),
new GetMessage()
};
private static Hashtable sessions = new Hashtable();
public static Enumeration getActiveSessions() {
synchronized (sessions) {
return sessions.keys();
}
}
public Session(ZZSpace space, Socket sock) throws IOException {
this(space, sock.getInputStream(), sock.getOutputStream());
socket = sock;
}
public Session(ZZSpace space, InputStream in, OutputStream out) throws IOException {
this.space = space;
io = new LineBufferedIO(in, out);
socket = null;
}
public void run() {
try {
p("session start");
if (socket != null) {
pa("accepting connection from " + socket.getInetAddress().getHostName());
}
userManager = UserManager.create(space);
synchronized (sessions) {
sessions.put(this, this);
}
try {
io.writeln("2.2.0 Hello there!");
} catch (IOException e) {
ZZLogger.exc(e);
}
while (!io.isEOF() && !isInterrupted()) {
try {
try {
String line = io.readline();
p("read " + line);
ZTPCommand c = new ZTPCommand(line);
p("" + c);
Message m = null;
for (int i = 0; i < messages.length; i++) {
if (messages[i].name().toUpperCase().equals(c.name.toUpperCase())) {
m = messages[i];
}
}
if (m == null) {
io.writeln("5.0.1 What?");
} else {
if (((m.prereqs() & reqstatus) ^ m.prereqs()) == 0) {
m.invoke(this, c.args);
} else {
io.writeln("5.0.2 Permission denied");
}
}
} catch (SyntaxError e) {
io.writeln("5.0.1 " + e.getMessage());
}
} catch (IOException e) {
ZZLogger.exc(e);
}
}
} finally {
synchronized (sessions) {
try {
if (!proper_close) io.writeln("4.2.1 Aborting");
socket.close();
} catch (IOException e) {
ZZLogger.exc(e);
}
sessions.remove(this);
}
userManager.close();
}
if (socket != null) {
pa("closing connection from " + socket.getInetAddress().getHostName());
}
p("session end");
}
}

View File

@@ -0,0 +1,139 @@
/*
UserManager.java
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.util.*;
/** User manager for ZTP server. It enforces single-threaded access
* to the user table in the space. */
class UserManager {
public static boolean dbg = true;
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
private static void pa(String s) { ZZLogger.log(s); }
private static Hashtable managers = new Hashtable();
private int refcount;
private ZZSpace space;
private boolean live = false;
private void assertLiving() {
if (!live) throw new ZZError("UserManager closed");
}
/*
private ZZCell userlist;
*/
private UserManager(ZZSpace space) {
synchronized (managers) {
this.space = space;
if (managers.containsKey(space)) {
throw new ZZError("there already is a UserManager for that space");
}
managers.put(space, this);
live = true;
}
refcount = 0;
// NOT NOW
//// we find the user list here for convenience
//ZZCell home = space.getHomeCell();
//userlist = home.findText("d.system", 1, "ZTPUserList");
//if (userlist == null) {
///* userlist = home.N("d.system", 1);
//userlist.setText("ZTPUserList");*/
//throw new ZZError("no user list in space!");
//}
}
public static UserManager create(ZZSpace space) {
UserManager rv;
synchronized (managers) {
Object o = managers.get(space);
if (o == null) {
rv = new UserManager(space);
} else {
rv = (UserManager)o;
}
}
++rv.refcount;
return rv;
}
public void close() {
if (--refcount < 1) {
synchronized (managers) {
live = false;
managers.remove(space);
}
}
}
public synchronized UserRecord access(String username) {
assertLiving();
UserRecord rv = new UserRecord();
rv.username = "adm";
rv.password = "mda";
rv.susp = false;
rv.chpass = false;
rv.sap = true;
rv.auth_pre = true;
rv.auth_pass = true;
return username.equals(rv.username) ? rv : null;
}
public interface RecordHandler {
void doit(UserRecord ur);
}
public synchronized void access_atomic(String username, RecordHandler rh) {
UserRecord ur = access(username);
rh.doit(ur);
}
public synchronized void replace(UserRecord ur) {
throw new ZZError("user record replace not implemented at this time");
}
public synchronized void replace_atomic(String username, RecordHandler rh) {
UserRecord ur = access(username);
rh.doit(ur);
replace(ur);
}
public synchronized void delete(String uname) {
throw new ZZError("user record deletion not implemented at this time");
}
public synchronized void insert(UserRecord ur) {
throw new ZZError("user record insertion not implemented at this time");
}
}

View File

@@ -0,0 +1,56 @@
/*
UserRecord.zob
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Antti-Juhani Kaijanaho
*/
package org.gzigzag.ztp.server;
import org.gzigzag.*;
import org.gzigzag.ztp.*;
import java.util.*;
/** User manager for ZTP server. It enforces single-threaded access
* to the user table in the space. */
public class UserRecord implements ZOb {
STRUCTPARAMS {
/** The username. */
String username;
/** The password for AUTH/PASS. */
String password;
/** Is the user suspended? */
boolean susp;
/** Is the user allowed to change her password? */
boolean chpass;
/** Does the user have Space Administrator Privileges? */
boolean sap;
/** May the user use preauthentication? */
boolean auth_pre;
/** May the user use password authentication? */
boolean auth_pass;
}
}