package main /* #include #include typedef struct mosquitto mosquitto; typedef const struct mosquitto_acl_msg const_mosquitto_acl_msg; typedef const char const_char; */ import "C" import ( "fmt" "log" "net/http" "os" "unsafe" ) var ( logger *log.Logger file *os.File = nil ) //export mosquitto_auth_plugin_version /* * Returns the value of MOSQ_AUTH_PLUGIN_VERSION defined in the mosquitto header file that the plugin was compiled * against. */ func mosquitto_auth_plugin_version() C.int { return C.MOSQ_AUTH_PLUGIN_VERSION } //export mosquitto_auth_plugin_init /* * Initialises the plugin. */ func mosquitto_auth_plugin_init(cUserData *unsafe.Pointer, cOpts *C.struct_mosquitto_opt, cOptCount C.int) C.int { var err error // copy opts from the C world into Go optMap := extractOptions(cOpts, cOptCount) // initialise logger if logger, file, err = initialiseLogger(optMap[optLogDest]); err != nil { fmt.Printf("error initialising logger, %s", err) return C.MOSQ_ERR_AUTH } logger.Println("plugin initializing") // initialise the user data that will be used in subsequent plugin calls userData, err := initialiseUserData(optMap) if err != nil { logger.Println("initialiseUserData failed with err:", err) return C.MOSQ_ERR_AUTH } *cUserData = unsafe.Pointer(&userData) return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_plugin_cleanup /* * Cleans up the plugin before the server shuts down. */ func mosquitto_auth_plugin_cleanup(cUserData unsafe.Pointer, cOpts *C.struct_mosquitto_opt, cOptCount C.int) C.int { //logger.Println("enter - plugin cleanup") // close logfile if file != nil { file.Sync() file.Close() file = nil } // set the client cache to nil so it can be garage collected clearUserData((*userData)(cUserData)) //logger.Println("leave - plugin cleanup") logger = nil return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_acl_check /* * Checks whether a client is authorised to read from or write to a topic. */ func mosquitto_auth_acl_check(cUserData unsafe.Pointer, cAccess C.int, cClient *C.mosquitto, cMsg *C.const_mosquitto_acl_msg) C.int { if cUserData == nil { logger.Printf("auth_acl_check[%p]: missing user data", cClient) return C.MOSQ_ERR_AUTH } access := access(cAccess) allow, err := authorise(http.DefaultClient, (*userData)(cUserData), access, unsafe.Pointer(cClient), C.GoString(cMsg.topic)) if err != nil { logger.Printf("auth_acl_check[%p]: error: %v", cClient, err) return C.MOSQ_ERR_AUTH } if !allow { logger.Printf("auth_acl_check[%p]: acl %q denied", cClient, access) return C.MOSQ_ERR_PLUGIN_DEFER } logger.Printf("auth_acl_check[%p]: acl %q granted", cClient, access) return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_unpwd_check /* * Authenticates the client by checking the supplied username and password. */ func mosquitto_auth_unpwd_check(cUserData unsafe.Pointer, cClient *C.mosquitto, cUsername, cPassword *C.const_char) C.int { if cUsername == nil || cPassword == nil { return C.MOSQ_ERR_AUTH } username := goStringFromConstant(cUsername) password := goStringFromConstant(cPassword) //logger.Printf("u: %s, p: %s\n", username, password) authorised, err := authenticate((*userData)(cUserData), unsafe.Pointer(cClient), username, password) if err != nil { logger.Printf("auth_unpwd_check[%p]: user %q error: %v", cClient, username, err) return C.MOSQ_ERR_AUTH } if !authorised { logger.Printf("auth_unpwd_check[%p]: user %q unauthorized", cClient, username) return C.MOSQ_ERR_PLUGIN_DEFER } logger.Printf("auth_unpwd_check[%p]: user %q authorized", cClient, username) return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_security_init /* * No-op function. Included to satisfy the plugin contract to Mosquitto. */ func mosquitto_auth_security_init(cUserData unsafe.Pointer, cOpts *C.struct_mosquitto_opt, cOptCount C.int, cReload C.bool) C.int { return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_security_cleanup /* * No-op function. Included to satisfy the plugin contract to Mosquitto. */ func mosquitto_auth_security_cleanup(cUserData unsafe.Pointer, cOpts *C.struct_mosquitto_opt, cOptCount C.int, cReload C.bool) C.int { return C.MOSQ_ERR_SUCCESS } //export mosquitto_auth_psk_key_get /* * No-op function. Included to satisfy the plugin contract to Mosquitto. */ func mosquitto_auth_psk_key_get(cUserData unsafe.Pointer, cClient *C.mosquitto, cHint, cIdentity *C.const_char, cKey *C.char, cMaxKeyLen C.int) C.int { return C.MOSQ_ERR_SUCCESS } func main() {}