20 #include <sys/types.h> 49 message = strdup(message);
50 result = regcomp(&preg,
"[a-z0-9._+-]+@[a-z0-9.-]+", REG_EXTENDED|REG_ICASE);
51 result |= regexec(&preg, message, 1, match, 0);
54 if (result != 0 || match[0].rm_so == -1) {
59 v->
state = UNVERIFIED;
62 *(message + match[0].rm_eo) =
'\0';
63 v->
email = strdup(message + match[0].rm_so);
68 v->
code = calloc(1,11);
69 if ((pipe = popen(
"pwgen 10 1",
"r")) == NULL) {
70 log_write(user->
sm->
log, LOG_ERR,
"Error generating email code for %s using 'pwgen'. %d:%s", v->
email, errno, strerror(errno));
73 if (fgets(v->
code, 11, pipe) == NULL) {
74 log_write(user->
sm->
log, LOG_ERR,
"Error getting email code for %s from 'pwgen'. %d:%s", v->
email, errno, strerror(errno));
78 if (pclose(pipe) == -1) {
79 log_write(user->
sm->
log, LOG_ERR,
"Error closing email code for %s from 'pwgen'. %d:%s", v->
email, errno, strerror(errno));
83 if ((pipe = popen(
"sendmail -t -F 'Jabber Server'",
"w")) == NULL) {
84 log_write(user->
sm->
log, LOG_ERR,
"Error starting sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
89 o = os_object_new(os);
90 os_object_put(o,
"email", v->
email, os_type_STRING);
91 os_object_put(o,
"code", v->
code, os_type_STRING);
92 os_object_put(o,
"state", &v->
state, os_type_INTEGER);
93 if (storage_replace(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, os) != st_SUCCESS) {
104 "Subject: Jabberd email verification\n" 106 "Please reply the following line to the jabber server to confirm your email address.\n\n" 109 log_write(user->
sm->
log, LOG_ERR,
"Error writing sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
113 if (pclose(pipe) == -1) {
114 log_write(user->
sm->
log, LOG_ERR,
"Error closing sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
118 "subject",
"Verification email sent");
120 "A verification email has been sent to the specified " 121 "address. Please check your inbox and follow the " 122 "instructions given in the mail.");
129 "An error occurred while trying to send the verification email to you.\n" 130 "Please try again later. If the problem persists, please contact the\n" 142 if (v->
code == NULL) {
146 if (strstr(message, v->
code) != NULL) {
151 o = os_object_new(os);
152 os_object_put(o,
"email", v->
email, os_type_STRING);
153 os_object_put(o,
"code", v->
code, os_type_STRING);
154 os_object_put(o,
"state", &v->
state, os_type_INTEGER);
155 if (storage_replace(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, os) != st_SUCCESS) {
156 log_write(user->
sm->
log, LOG_ERR,
"Error writing verification state to DB for %s", v->
email);
160 "subject",
"Code accepted");
162 "Your verification code has been accepted.\n" 163 "You are now a verified user.");
166 "subject",
"Code rejected");
168 "Your verification code did not match.\n" 169 "Please try to re-submit it, or send another \n" 170 "\"email: \" line to gat a new code sent to you.");
177 "subject",
"Please enter your email address");
179 "You are blocked from this jabber server until " 180 "you have entered and validated your email address! " 181 "To do this, please type in \"email: \" followed by " 182 "your email address as a reply to this message, e.g.\n\n" 183 "email: johndoe@example.com\n\n" 184 "A verification code with further instructions will then " 185 "be sent to that email address.");
210 cdata = malloc(len+1);
211 strncpy(cdata,
NAD_CDATA(nad, body), len);
216 if (strstr(cdata,
"email: ") == cdata) {
218 }
else if (strstr(cdata,
"code: ") == cdata) {
235 if (v->
email != NULL)
245 storage_delete(mi->
sm->
st,
"verify",
jid_user(jid), NULL);
258 if (storage_get(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, &os) == st_SUCCESS) {
259 if (os_iter_first(os)) {
260 o = os_iter_object(os);
261 if (os_object_get_str(os, o,
"email", &v->
email) &&
262 os_object_get_str(os, o,
"code", &v->
code) &&
263 os_object_get_int(os, o,
"state", &state)) {
266 v->
state = ( state == VERIFIED ) ? VERIFIED : UNVERIFIED;
268 v->
state = UNVERIFIED;
283 if(mod->
init)
return 0;
user_t user
user this session belongs to
pkt_type_t type
packet type
jid_t jid
session jid (user@host/res)
static mod_ret_t _verify_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt)
data structures and prototypes for the session manager
static int _verify_user_load(mod_instance_t mi, user_t user)
#define NAD_CDATA_L(N, E)
const char * id
component id
const char * jid_user(jid_t jid)
expand and return the user
static void check_code(verify_t *v, user_t user, pkt_t res, char *message)
static void print_instructions(pkt_t res)
const char * jid_full(jid_t jid)
expand and return the full
single instance of a module in a chain
int init
number of times the module intialiser has been called
void log_write(log_t log, int level, const char *msgfmt,...)
struct _verify_st verify_t
int nad_insert_elem(nad_t nad, unsigned int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
static void send_email(verify_t *v, user_t user, pkt_t res, char *message)
void pool_cleanup(pool_t p, pool_cleanup_t f, void *arg)
public cleanup utils, insert in a way that they are run FIFO, before mem frees
mod_ret_t(* in_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt)
in-sess handler
enum _verify_st::@0 state
pool_t p
memory pool this user is allocated off
module_t mod
module that this is an instance of
packet summary data wrapper
storage_t st
storage subsystem
nad_t nad
nad of the entire packet
void pkt_router(pkt_t pkt)
packet was unhandled, should be passed to the next module
static void _verify_user_delete(mod_instance_t mi, jid_t jid)
packet was handled (and freed)
There is one instance of this struct per user who is logged in to this c2s instance.
int(* user_load)(mod_instance_t mi, user_t user)
user-load handler
int nad_find_elem(nad_t nad, unsigned int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
void(* user_delete)(mod_instance_t mi, jid_t jid)
user-delete handler
DLLEXPORT int module_init(mod_instance_t mi, char *arg)
jid_t jid
user jid (user@host)
void ** module_data
per-user module data
static void _verify_user_free(verify_t *v)
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from)
mod_ret_t
module return values