/* ************************************************************************ ** ** Copyright (c) 2010..2012 by ** Core|Vision B.V. ** Cereslaan 10b ** 5384 VT Heesch ** The Netherlands ** ** All Rights Reserved ** ************************************************************************ */ /* ************************************************************************ ** ** Project name: Dual Inventive: Server for MTinfo Secure ** Filename: secureserver.h ** Author: Jack Weeland ** Date: February 17, 2010 ** File version: $Revision: 1.14 $ ** $Date: 2014/02/05 10:45:20 $ ** ************************************************************************ */ /* ************************************************************************ ** ** Secure Server ** Definitions ** ************************************************************************ */ #ifndef _SECURESERVER_H #define _SECURESERVER_H #include #include #include #include #include #include #include #include #include #include /* ** Error and status bits (currently only used to give a reason for a disconnect) */ #define TCP_NO_ERROR 0 #define TCP_ERROR 1 #define TCP_DISCONNECTED 2 #define TCP_TIMEOUT 3 #define TCP_ABORTED 4 #define TCP_KILLED 5 #define TCP_PROTOCOL 6 // protocol violation // device flags #define ZKL_ACTIVE 0x0001 #define ZKL_CAN_SWITCH 0x0002 #define ZKL_IS_RS3000 0x1000 // currently without meaning // flags to signal a prototol violation or not (boolean flag for // 'signal_protocol_violation()' #define VIOLATION 0 #define USER_ERROR 1 #define DEVICE_ERROR 2 #define USER_LOCKED 3 #define INTERNAL_ERROR 4 #define SERVER_ERROR 5 /* ** Type definitions */ // database identifiers for a ZKL, user and project typedef unsigned int zkl_t; typedef unsigned int user_t; typedef unsigned int project_t; // reason why a new work instruction is offered typedef enum WI_REASON { R_INVALID = -1, R_NEW = 0, R_O_CONCEPT, R_O_READY, R_O_VERIFY, R_O_VALIDATE, R_P_CONCEPT, R_P_READY, R_P_VERIFY, R_P_VALIDATE, R_S_RELEASE, R_S_WITHDRAW, R_S_CHECK, R_S_REQ_ON, R_S_ON, R_S_REQ_OFF, R_S_OFF, R_ALARM, R_S_VERIFY, R_SECURE, // pseudo reason, the reason below don't work on a work instruction R_LED_HIGH, R_LED_LOW, R_EXT_ON, R_EXT_OFF, R_LANT_ON, R_LANT_OFF, R_RELAY_ON, R_RELAY_OFF, R_GPS_TRACKTRACE, R_RESET_SECUREHANDSHAKE, R_CHECK_CONNECTION, R_DELETE } reason_t; // states typedef enum WI_STATE { S_INVALID = -1, S_CONCEPT = 0, S_READY, S_VERIFY, S_VALIDATE, S_WITHDRAW, S_RELEASE, S_REQ_ON, S_ON, S_REQ_OFF, S_OFF } state_t; // verification methods typedef enum WI_VERIFICATION { VER_INVALID = -1, VER_SMS = 0, VER_PIN, VER_RS3000 } verification_t; // methods to send an alarm message typedef enum WI_ALARM { ALARM_INVALID = -1, ALARM_SMS = 0, ALARM_EMAIL } alarm_t; // work instructions and supporting classes struct WI_DEVICE { zkl_t id; // identifier for the device unsigned int flags; // ZKL_xxx flags int status; // status after running a command char imei[16]; // IMEI of the device char serial[32]; // serial number char idcode[32]; // ID-code of the device unsigned char rs3000_verification[DIGITAL_SIGNATURE_BITS >> 3]; char server[PATH_MAX]; // IP-address and port of the TCP-server for this device gps_position_t gps; // GPS position after communication with the device and when applicable }; struct WI_USER { user_t id; // identifier for the user char user_name[32]; // user name char i18n[16]; // translation for the SMS messages char tz[64]; // time zone to format the time correctly // user verification verification_t method; // method of verification unsigned char verification[DIGITAL_SIGNATURE_BITS >> 3]; char phonenr[16]; // phone number for SMS verification }; struct WI_NOTIFY { alarm_t method; // e-mail or SMS char da[PATH_MAX]; // e-mail address or phone number }; // work instruction; user data for the master cp3000_device_t object typedef struct WI_HEADER { project_t id; // identifier for the project/period char name[64]; // project name user_t mtinfo_user; // user in MTinfo who sent the request reason_t reason; // reason for this communication state_t req_state; // requested state int status; // status code to return to the client // devices and users associated with the request int n_devices; int n_users; lst_t devices; lst_t users; // used with a request to switch a device user_t user; // actor verification_t method; // SMS, PIN or RS3000 time_t expiration; // expiration time for device check _or_ // SMS verification code (mutually exclusive) unsigned char verification[DIGITAL_SIGNATURE_BITS >> 3]; // digital signature unsigned char signature[DIGITAL_SIGNATURE_BITS >> 3]; // TCP-server for logging cp3000_device_t log_server; unsigned int log_session; // database handle db_t db; // tokens for the hash (signature) lst_t hash_tokens; // semaphore to protect against simultaneous access to the same work instruction cp3000_sem_t semaphore; } *wi_t; /* ** Exported functions */ // // implemented in "secureserver.c" // // debugging enabled? extern int debug; // log server extern cp3000_device_t log_server; // get the wi_t object wi_t get_wi(cp3000_device_t); // get the db_t object db_t get_db(cp3000_device_t); // convert reason string to a reason_t, state_t, verification_t, alarm_t reason_t get_reason(const char*); state_t get_state(const char*); verification_t get_verification_method(const char*); alarm_t get_notify_method(const char*); // convert reason_t, state_t, verification_t and alarm_t to string // (simple look-up array) extern const char *reason_str[]; extern const char *state_str[]; extern const char *verification_str[]; extern const char *notification_str[]; // get the base name for the mutex/semaphore int get_mutex_name(wi_t wi, char *buffer, size_t bufsz); // set security for a cp3000_device_t object (must be done before a // connection is made) int set_security(cp3000_device_t); // kill this instance of the secure server (signal handler for SIGTERM, // but also called after a protocol violation (with SIGUSR1) void tcp_terminate(int); // // implemented in "wi.c" // // command (sequence) and device time-out in seconds extern int command_timeout; extern int device_timeout; // user lock-out in seconds and number of allowed attempts extern int user_lockout_time; extern int user_lockout_tries; // validity of a device check extern int device_check_validity; // validity and length of an SMS code extern int verification_validity; extern int verification_code_len; // get a user or device from the transmitted work instruction const struct WI_USER *wi_get_user(wi_t, user_t); const struct WI_DEVICE *wi_get_device(wi_t, zkl_t); // delete the work instruction after a security violation int wi_delete(cp3000_device_t, wi_t); // main entry: read the request from MTinfo, verify it and execute it int handle_request(cp3000_device_t, token_info_t, void*); // close and clean-up an open connection int secureserver_shutdown(cp3000_device_t, int reason); // // implemented in "notify.c" // // fixed list (from configuration) of e-mail addresses for protocol violations extern char notify_list[]; // e-mail "from" address, priority and locale extern char notify_from[]; extern char notify_priority[]; extern char notify_i18n[]; extern char notify_tz[]; // line separator for SMS messages (default " * ") extern char sms_separator[]; // fatal error (protocol violation) // the work instruction is deleted in the case of a protocol violaton, // but not in the case of a non-fatal error such as TCPERR_ACCESS // sends a notification via e-mail and/or sms int signal_protocol_violation( cp3000_device_t, int is_violation, int error_code, const char *fmt, ... ); // send verification code via SMS; the generated code is stored (encoded) // in the work instruction (wi_t parameter, field 'verification') int send_sms_verification_code(cp3000_device_t, wi_t, user_t); // // implemented in "log-server.c" // // connect and login with a TCP-server for logging (which is stored // in the 'wi_t' user data of the device) // note: all log entries are also written to syslog(3) int log_start(cp3000_device_t, reason_t, user_t, const char *log_server); // record overall status and disconnect from log server int log_end(cp3000_device_t, int status, const char *fmt, ...); // log device activity and changes to a user in the work instruction // (user activity, i.e. the user as actor, is logged via the main entry) int log_device(cp3000_device_t, zkl_t, int status, const char *fmt, ...); int log_user(cp3000_device_t, user_t, int status, const char *fmt, ...); // intermediate messages, not related to a device or a user int log_wi(cp3000_device_t, int status, const char *fmt, ...); // // implemented in "database-if.c" // // flags for 'db_update_xxx()' (the three stages) // NB: non-essential data in the device and user list is always updated #define WI_UPDATE_DESIGN 0x0001 // i.e. the switchable device list #define WI_UPDATE_PLANNING 0x0002 // i.e. the user list and non-switchable devices #define WI_UPDATE_SWITCHSTATE 0 // (placeholder) #define WI_UPDATE_DEVICES 0 // device list (TCP server address only) #define WI_UPDATE_USERS 0 // user list (i18n, tz, phone number or PIN) #define WI_UPDATE (WI_UPDATE_DEVICES | WI_UPDATE_USERS) #define WI_UPDATE_USER 0x0100 // the user allowed to switch #define WI_UPDATE_VERIFICATION 0x0200 // update verification code sent via SMS #define WI_SET_EXPIRATION 0x0400 // expiration time for a check on switchability #define WI_REPLACE 0x8000 // replace data instead of updating it, where applicable // verify the signature of the database records // returns CP3000 status code int db_verify_signature(cp3000_device_t, wi_t); // compare the database data with the data in the work instruction // returns CP3000 status code int db_verify_wi(cp3000_device_t, wi_t); // get project state (design, planning, switching) // returns CP3000 status code int db_get_state(cp3000_device_t, wi_t, state_t*, state_t*, state_t*); // verify a user and expiry of the device check // returns CP3000 status code int db_verify_user(cp3000_device_t, wi_t, user_t, const unsigned char*, size_t); int db_check_expiration(cp3000_device_t, wi_t); // find a user int db_find_user(cp3000_device_t, wi_t, user_t, struct WI_USER*); // add a new work instruction, update an existing one (data and state _separately_) // or delete a work instruction. // all return CP3000 status code int db_insert_wi(cp3000_device_t, wi_t, state_t init_state); int db_update_wi(cp3000_device_t, wi_t, unsigned int flags); int db_update_state(cp3000_device_t, wi_t, state_t new_state, unsigned int flags); int db_update_gps_position(cp3000_device_t, wi_t); int db_delete_wi(cp3000_device_t, wi_t); // add a list with notification numbers to the work instruction // a possible existing list will be replaced // returns CP3000 status code int db_insert_notify_list(cp3000_device_t, wi_t); // get the list; the lists themselves may be NULL if not interested in // one or the other // returns CP3000 status code int db_get_notify_list(cp3000_device_t, wi_t, lst_t email, lst_t sms); // update the signature over the database data int db_update_signature(cp3000_device_t device, wi_t wi); #endif /* _SECURESERVER_H */