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));
77 if (pclose(pipe) == -1) {
78 log_write(user->
sm->
log, LOG_ERR,
"Error closing email code for %s from 'pwgen'. %d:%s", v->
email, errno, strerror(errno));
82 if ((pipe = popen(
"sendmail -t -F 'Jabber Server'",
"w")) == NULL) {
83 log_write(user->
sm->
log, LOG_ERR,
"Error starting sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
88 o = os_object_new(os);
89 os_object_put(o,
"email", v->
email, os_type_STRING);
90 os_object_put(o,
"code", v->
code, os_type_STRING);
91 os_object_put(o,
"state", &v->
state, os_type_INTEGER);
92 if (storage_replace(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, os) != st_SUCCESS) {
103 "Subject: Jabberd email verification\n"
105 "Please reply the following line to the jabber server to confirm your email address.\n\n"
108 log_write(user->
sm->
log, LOG_ERR,
"Error writing sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
111 if (pclose(pipe) == -1) {
112 log_write(user->
sm->
log, LOG_ERR,
"Error closing sendmail to %s. %d:%s", v->
email, errno, strerror(errno));
116 "subject",
"Verification email sent");
118 "A verification email has been sent to the specified "
119 "address. Please check your inbox and follow the "
120 "instructions given in the mail.");
127 "An error occured while trying to send the verification email to you.\n"
128 "Please try again later. If the problem persists, please contact the\n"
140 if (v->
code == NULL) {
144 if (strstr(message, v->
code) != NULL) {
149 o = os_object_new(os);
150 os_object_put(o,
"email", v->
email, os_type_STRING);
151 os_object_put(o,
"code", v->
code, os_type_STRING);
152 os_object_put(o,
"state", &v->
state, os_type_INTEGER);
153 if (storage_replace(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, os) != st_SUCCESS) {
154 log_write(user->
sm->
log, LOG_ERR,
"Error writing verification state to DB for %s", v->
email);
158 "subject",
"Code accepted");
160 "Your verification code has been accepted.\n"
161 "You are now a verified user.");
164 "subject",
"Code rejected");
166 "Your verification code did not match.\n"
167 "Please try to re-submit it, or send another \n"
168 "\"email: \" line to gat a new code sent to you.");
175 "subject",
"Please enter your email address");
177 "You are blocked from this jabber server until "
178 "you have entered and validated your email adddress! "
179 "To do this, please type in \"email: \" followed by "
180 "your email address as a reply to this message, e.g.\n\n"
181 "email: johndoe@example.com\n\n"
182 "A verification code with further instructions will then "
183 "be sent to that email address.");
207 cdata = strncpy(malloc(len+1),
NAD_CDATA(nad, body), len);
212 if (strstr(cdata,
"email: ") == cdata) {
214 }
else if (strstr(cdata,
"code: ") == cdata) {
229 if (v->
email != NULL)
239 storage_delete(mi->
sm->
st,
"verify",
jid_user(jid), NULL);
252 if (storage_get(user->
sm->
st,
"verify",
jid_user(user->
jid), NULL, &os) == st_SUCCESS) {
253 if (os_iter_first(os)) {
254 o = os_iter_object(os);
255 if (os_object_get_str(os, o,
"email", &v->
email) &&
256 os_object_get_str(os, o,
"code", &v->
code) &&
257 os_object_get_int(os, o,
"state", &state)) {
260 v->
state = ( state == VERIFIED ) ? VERIFIED : UNVERIFIED;
262 v->
state = UNVERIFIED;
277 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
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
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 nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
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
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
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