From 724f4ee59b0af7b64a3317af3c9ee5d3f45e9fc4 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 3 Apr 2016 12:15:44 -0400 Subject: various fixes --- README.md | 19 ++++++++++++------- src/auth.c | 15 +++++++++------ src/auth.h | 6 +++--- src/client.c | 16 +++++++++------- src/hash.c | 8 ++++++++ src/obj.c | 6 ++---- src/server.c | 17 ++++++----------- src/server_reqs.c | 5 ++++- src/telnet.c | 4 +++- src/telnet.h | 2 +- src/userdb.c | 13 ++++++------- src/world.c | 11 ++++------- worlds/test.c | 5 +++-- 13 files changed, 70 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 6bbe8bb..f97f183 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,8 @@ and a pipe for the master to write to. Both of these pipes are created in "packet mode" (see pipe(2)) if available, and as UNIX domain socket pairs if not, which is slightly -wasteful.s +wasteful, as they are full-duplex but only used in a half-duplex +manner. Many operations, such as listing clients, require the help of the master process. To request an operation, the child writes its request @@ -98,17 +99,15 @@ number. #### 0.4.0 (skipped) -* Object support [DONE] +* Object support -* User inventory support [DONE] - -### Roadmap +* User inventory support #### 0.5.0 -* Verb support [DONE] +* Verb support -* World hooks/scripting [DONE] +* World hooks/scripting ##### 0.5.1 @@ -118,6 +117,8 @@ number. * Many bugfixes +### Roadmap + #### 0.6.0 * NPC users @@ -125,3 +126,7 @@ number. #### 0.7.0 * Dynamic world editing + +#### 1.0.0 + +* Procedural generation diff --git a/src/auth.c b/src/auth.c index c7b53d3..5797c83 100644 --- a/src/auth.c +++ b/src/auth.c @@ -20,6 +20,7 @@ #include "auth.h" #include "client.h" +#include "server.h" #include "userdb.h" static bool valid_login_name(const char *name); @@ -38,7 +39,7 @@ static char *hash_pass_hex(const char *pass, const char *salt) unsigned char hash[AUTH_HASHLEN]; - SHA512(salted, pass_len + SALT_LEN, hash); + AUTH_HASHFUNC(salted, pass_len + SALT_LEN, hash); unsigned char tmp[AUTH_HASHLEN]; /* now hash the hash a million times to slow things down */ @@ -176,13 +177,16 @@ void first_run_setup(void) struct userdata_t *auth_check(const char *name2, const char *pass2) { + if(!are_child) + debugf("WARNING: auth_check called from master!\n"); + /* get our own copy to remove newlines */ char *name = strdup(name2); char *pass = strdup(pass2); remove_cruft(name); remove_cruft(pass); - /* find it in the user list */ + /* request data from the master process */ struct userdata_t *data = userdb_request_lookup(name); free(name); @@ -191,8 +195,6 @@ struct userdata_t *auth_check(const char *name2, const char *pass2) if(data) { - debugf("auth module: user %s found\n", name2); - /* hashes are in lowercase hex to avoid the Trucha bug * but still allow comparison with strcmp() */ char *new_hash_hex = hash_pass_hex(pass, salt); @@ -216,12 +218,13 @@ struct userdata_t *auth_check(const char *name2, const char *pass2) } } - debugf("auth failure for user %s\n", name2); + debugf("Authentication failure for user %s\n", name2); memset(pass, 0, strlen(pass)); free(pass); - /* failure */ + /* failure: note that this function should be run exclusively by + * child processes */ sleep(2); return NULL; } diff --git a/src/auth.h b/src/auth.h index c5c9dc1..306d8d6 100644 --- a/src/auth.h +++ b/src/auth.h @@ -20,13 +20,13 @@ #include "globals.h" -#define SALT_LEN 12 +#define SALT_LEN 16 #define AUTH_HASHLEN SHA512_DIGEST_LENGTH #define AUTH_HASHFUNC SHA512 -//#define HASH_ITERS 500000 #define HASH_ITERS 1 +//#define HASH_ITERS 1 -/* makes admin account */ +/* makes admin account based on terminal input */ void first_run_setup(void); struct userdata_t; diff --git a/src/client.c b/src/client.c index d66836e..7c69708 100644 --- a/src/client.c +++ b/src/client.c @@ -158,7 +158,7 @@ tryagain: { ssize_t len = read(client_fd, buf + bufidx, CLIENT_READ_SZ - bufidx - 1); if(len <= 0) - error("lost connection (%d)", fds[i].revents); + error("lost connection"); buf[CLIENT_READ_SZ - 1] = '\0'; @@ -316,6 +316,7 @@ int client_cb(char **save) { const char *msg = "Kicking everyone...\n"; send_master(REQ_KICKALL, msg, strlen(msg)); + out("All clients kicked.\n"); return CMD_OK; } /* weird pointer voodoo */ @@ -338,7 +339,6 @@ int client_cb(char **save) sizeof(pidbuf) - sizeof(pid_t), "You were kicked.\n"); send_master(REQ_KICK, pidbuf, len); - debugf("Success.\n"); } else out("Usage: CLIENT KICK \n"); @@ -438,6 +438,8 @@ int drop_cb(char **save) int chpass_cb(char **save) { + (void) save; + out("Changing password for %s\n", current_user); out("Enter current password: "); char *current = client_read_password(); @@ -448,7 +450,7 @@ int chpass_cb(char **save) if(!current_data) { - out("Password mismatch.\n"); + out("Authentication failed.\n"); return CMD_OK; } @@ -477,6 +479,8 @@ int chpass_cb(char **save) memset(pass1, 0, strlen(pass1)); + out("Password updated.\n"); + return CMD_OK; } @@ -526,11 +530,9 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from) telnet_init(); char *ip = inet_ntoa(addr->sin_addr); - debugf("New client %s\n", ip); + debugf("== New client %s ==\n", ip); debugf("Total clients: %d\n", total); - debugf("client is running with uid %d\n", getuid()); - auth: out("NetCosm " NETCOSM_VERSION "\n"); @@ -597,7 +599,7 @@ auth: client_change_state(STATE_LOGGEDIN); /* authenticated, begin main command loop */ - debugf("client: Authenticated as %s\n", current_user); + debugf("Client %s: authenticated as %s.\n", ip, current_user); client_change_user(current_user); current_room = 0; diff --git a/src/hash.c b/src/hash.c index ce91ceb..1cfd704 100644 --- a/src/hash.c +++ b/src/hash.c @@ -371,6 +371,14 @@ void hash_del_internal_node(void *ptr, const struct hash_export_node *node) struct hash_map *map = ptr; CHECK_SENTINEL(map); + struct hash_node *node_val = node->node; + + if(map->free_data) + map->free_data((void*)node_val->data); + if(map->free_key) + map->free_key((void*)node_val->key); + free(node_val); + if(node->last) ((struct hash_node*)node->last)->next = node->next; else diff --git a/src/obj.c b/src/obj.c index 296fbb5..ce4a890 100644 --- a/src/obj.c +++ b/src/obj.c @@ -144,7 +144,7 @@ struct object_t *obj_copy(struct object_t *obj) struct object_t *obj_dup(struct object_t *obj) { - debugf("Adding an object reference to #%" PRI_OBJID ".\n", obj->id); + //debugf("Adding an object reference to #%" PRI_OBJID ".\n", obj->id); ++obj->refcount; return obj; } @@ -154,11 +154,9 @@ void obj_free(void *ptr) struct object_t *obj = ptr; --obj->refcount; - debugf("Freeing an object reference for #%" PRI_OBJID" (%s, %d).\n", obj->id, obj->name, obj->refcount); - if(!obj->refcount) { - debugf("Freeing object #%"PRI_OBJID"\n", obj->id); + //debugf("Freeing object #%"PRI_OBJID"\n", obj->id); if(obj->class->hook_destroy) obj->class->hook_destroy(obj); diff --git a/src/server.c b/src/server.c index 6d90c61..a4280c2 100644 --- a/src/server.c +++ b/src/server.c @@ -41,7 +41,7 @@ static uint16_t port = DEFAULT_PORT; static int server_socket; -#define SAVE_INTERVAL 8 +#define SAVE_INTERVAL 10 /* saves state periodically */ void server_save_state(bool force) @@ -111,7 +111,7 @@ static void handle_client(int fd, struct sockaddr_in *addr, client_main(fd, addr, nclients, to, from); } -static void __attribute__((noreturn)) server_cleanup(void) +static void __attribute__((noreturn)) server_shutdown(void) { if(!are_child) debugf("Shutdown server.\n"); @@ -150,7 +150,7 @@ static void __attribute__((noreturn)) server_cleanup(void) /* shut down libev */ ev_default_destroy(); - exit(0); + _exit(0); } static void __attribute__((noreturn)) sigint_handler(int s) @@ -170,6 +170,7 @@ static void check_userfile(void) first_run_setup(); else auth_user_add(autouser, autopass, PRIV_ADMIN); + userdb_write(USERFILE); } if(access(USERFILE, R_OK | W_OK) < 0) @@ -269,11 +270,7 @@ static void new_connection_cb(EV_P_ ev_io *w, int revents) else debugf("WARNING: Using a SOCK_DGRAM socket pair for IPC, performance may be degraded.\n"); } - else - debugf("Using a SOCK_SEQPACKET socket pair for IPC.\n"); } - else - debugf("Using a packet-mode pipe for IPC.\n"); if(pipe2(outpipe, O_DIRECT) < 0) { @@ -312,8 +309,6 @@ static void new_connection_cb(EV_P_ ev_io *w, int revents) /* shut down libev */ ev_default_destroy(); - debugf("Child with PID %d spawned\n", getpid()); - server_socket = new_sock; handle_client(new_sock, &client, num_clients, readpipe[1], outpipe[0]); @@ -449,7 +444,7 @@ int server_main(int argc, char *argv[]) hash_setfreedata_cb(child_map, free_child_data); hash_setfreekey_cb(child_map, free); - debugf("Listening on port %d\n", port); + debugf("Listening on port %d.\n", port); server_socket = server_bind(); @@ -465,7 +460,7 @@ int server_main(int argc, char *argv[]) ev_io_start(EV_A_ &server_watcher); - atexit(server_cleanup); + atexit(server_shutdown); /* everything's ready, hand it over to libev */ ev_loop(loop, 0); diff --git a/src/server_reqs.c b/src/server_reqs.c index 21787f4..ab283ca 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -133,7 +133,10 @@ static void req_kick_client(unsigned char *data, size_t datalen, { pid_t kicked_pid = *((pid_t*)data); if(kicked_pid == child->pid) + { send_packet(child, REQ_KICK, data + sizeof(pid_t), datalen - sizeof(pid_t)); + send_msg(sender, "Success.\n"); + } } } @@ -625,7 +628,7 @@ bool handle_child_req(int in_fd) struct child_request *req = hash_lookup(request_map, &cmd); - debugf("Child %d sends request %d\n", sender_pid, cmd); + //debugf("Child %d sends request %d\n", sender_pid, cmd); if(!req) { diff --git a/src/telnet.c b/src/telnet.c index 9932d84..6795b89 100644 --- a/src/telnet.c +++ b/src/telnet.c @@ -36,7 +36,7 @@ uint16_t telnet_get_height(void) return term_height; } -enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen) +enum telnet_status telnet_parse_data(unsigned char *buf, size_t buflen) { bool iac = false; bool found_cmd = false; @@ -51,6 +51,8 @@ enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen) iac = true; else if(c == '\n' || c == '\r') line_done = true; + else if(c == '\0') // ignore NULLs + buf[i] = ' '; if(iac) { diff --git a/src/telnet.h b/src/telnet.h index 2f40c51..8a7d62e 100644 --- a/src/telnet.h +++ b/src/telnet.h @@ -27,7 +27,7 @@ enum telnet_status { TELNET_DATA = 0, TELNET_LINEOVER, TELNET_EXIT }; -enum telnet_status telnet_parse_data(const unsigned char*, size_t); +enum telnet_status telnet_parse_data(unsigned char*, size_t); uint16_t telnet_get_width(void); uint16_t telnet_get_height(void); diff --git a/src/userdb.c b/src/userdb.c index 0a13319..0ebe159 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -110,8 +110,6 @@ void userdb_init(const char *file) bool userdb_write(const char *file) { - debugf("Writing userdb...\n"); - int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600); if(fd < 0) return false; @@ -154,7 +152,6 @@ bool userdb_write(const char *file) struct object_t *obj = iter->val; if(!strcmp(iter->key, obj->name)) { - debugf("Writing an object to disk...\n"); obj_write(fd, iter->val); } iter = iter->next; @@ -164,8 +161,6 @@ bool userdb_write(const char *file) } close(fd); - debugf("Done writing userdb.\n"); - return true; } @@ -178,7 +173,7 @@ bool userdb_remove(const char *key) { if(hash_remove(map, key)) { - userdb_write(db_file); + server_save_state(false); return true; } return false; @@ -186,6 +181,8 @@ bool userdb_remove(const char *key) bool userdb_add(struct userdata_t *data) { + if(!data) + return false; struct userdata_t *new = calloc(1, sizeof(*new)); /* only in C! */ memcpy(new, data, sizeof(*new)); @@ -206,7 +203,9 @@ bool userdb_add(struct userdata_t *data) hash_overwrite(map, new->username, new); - return userdb_write(db_file); + server_save_state(false); + + return true; } void userdb_dump(void) diff --git a/src/world.c b/src/world.c index 8c25d7d..222155d 100644 --- a/src/world.c +++ b/src/world.c @@ -83,8 +83,6 @@ void world_save(const char *fname) size_t n_objects = room_obj_count_noalias(i); write(fd, &n_objects, sizeof(n_objects)); - debugf("Room %d has %d objects.\n", i, n_objects); - room_id id = i; void *save; while(1) @@ -101,7 +99,6 @@ void world_save(const char *fname) const char *name = iter->key; if(!strcmp(name, obj->name)) { - debugf("writing object '%s' in room %d\n", obj->name, i); obj_write(fd, obj); } iter = iter->next; @@ -132,7 +129,7 @@ void world_save(const char *fname) /* now write the map of room names to ids */ void *ptr = world_map, *save; - for(unsigned int i = 0; i < world_sz; ++i) + while(1) { void *key; struct room_t *room = hash_iterate(ptr, &save, &key); @@ -158,6 +155,7 @@ void world_free(void) } hash_free(world_verb_map()); + hash_free(world_map); free(world); world = NULL; @@ -255,7 +253,6 @@ bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz { const char *key = read_string(fd); room_id id = read_roomid(fd); - debugf("'%s' -> %d\n", key, id); hash_insert(world_map, key, world + id); } @@ -285,7 +282,7 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name) //world[i].uniq_id = strdup(world[i].uniq_id); world[i].data.name = strdup(world[i].data.name); world[i].data.desc = strdup(world[i].data.desc); - debugf("Loading room '%s'\n", world[i].data.uniq_id); + //debugf("Loading room '%s'\n", world[i].data.uniq_id); if(hash_insert(world_map, world[i].data.uniq_id, world + i)) error("Duplicate room ID '%s'", world[i].data.uniq_id); @@ -386,7 +383,7 @@ static void init_map(void) bool world_verb_add(struct verb_t *verb) { init_map(); - debugf("Added global verb %s\n", verb->name); + //debugf("Added global verb %s\n", verb->name); return !hash_insert(verb_map, verb->name, verb); } diff --git a/worlds/test.c b/worlds/test.c index f662c1f..79b8429 100644 --- a/worlds/test.c +++ b/worlds/test.c @@ -126,6 +126,7 @@ static void mailroom_init(room_id id) /* insert IAC NOP to prevent the extra whitespace from being dropped */ new->userdata = strdup("All of the bins are empty. Looking closely you can see that there are names written at the bottom of each bin, but most of them are faded away so that you cannot read them. You can only make out three names:\n\377\361 Jeffrey Collier\n\377\361 Robert Toukmond\n\377\361 Thomas Stock\n"); room_obj_add(id, new); + room_obj_add_alias(id, new, "mail bins"); } static void computer_room_init(room_id id) @@ -140,6 +141,8 @@ static void computer_room_init(room_id id) /* flag for whether computer is active */ room_get(id)->userdata = malloc(sizeof(bool)); + bool *b = room_get(id)->userdata; + *b = false; } const struct roomdata_t netcosm_world[] = { @@ -589,8 +592,6 @@ const struct verb_class_t netcosm_verb_classes[] = { type_exec }, { "climb", climb_exec }, - */ - /* { "feed", feed_exec }, */ -- cgit v1.1