int answer_to_connection( void* cls, struct MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls) { DAEMON_STATE dstate = (DAEMON_STATE)cls; REQUEST_STATE rstate = (REQUEST_STATE)*con_cls; if (rstate == NULL && added_client_overloads(dstate)) { return service_unavailable(connection); } else if (SMATCH(url, "/form.html")) { if (SMATCH(method, MHD_HTTP_METHOD_OPTIONS)) { return method_options( connection, COMMA_SEPARATED_STRING_LITERALS( MHD_HTTP_METHOD_POST, MHD_HTTP_METHOD_OPTIONS)); } else if (!SMATCH(method, MHD_HTTP_METHOD_POST)) { return bad_method( connection, COMMA_SEPARATED_STRING_LITERALS( MHD_HTTP_METHOD_POST, MHD_HTTP_METHOD_OPTIONS)); } else if (rstate == NULL && added_upload_client_overloads( dstate, TRUE)) { return service_unavailable(connection); } else if (rstate == NULL) { rstate = new_REQUEST_STATE( connection, method, &form_data_iterator); if (rstate == NULL) { return MHD_NO; } *con_cls = (void*)rstate; if (rstate->was_error) { return server_error(connection); } else { return MHD_YES; } } else if (*upload_data_size != 0) { MHD_post_process( rstate->processor, upload_data, *upload_data_size); *upload_data_size = 0; return MHD_YES; } else if (rstate->was_filename_issue) { return forbidden( connection, "The server is unable to use the " "given filename. Please try a " "different file name."); } else if (rstate->was_error) { return server_error(connection); } else { return gen_result(connection); } } else if (SMATCH_ANY(url, "/index.html", "/index.htm", "/")) { if (SMATCH(method, MHD_HTTP_METHOD_OPTIONS)) { return method_options( connection, COMMA_SEPARATED_STRING_LITERALS( MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_HEAD, MHD_HTTP_METHOD_OPTIONS)); } else if (!SMATCH_ANY( method, MHD_HTTP_METHOD_HEAD, MHD_HTTP_METHOD_GET)) { return bad_method( connection, COMMA_SEPARATED_STRING_LITERALS( MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_HEAD, MHD_HTTP_METHOD_OPTIONS)); } else if (rstate == NULL) { rstate = new_REQUEST_STATE(connection, method, NULL); if (rstate == NULL) { return MHD_NO; } *con_cls = (void*)rstate; if (rstate->was_error) { return server_error(connection); } else { return MHD_YES; } } else { return gen_form(connection, "/form.html", dstate); } } else if (SMATCH(method, MHD_HTTP_METHOD_OPTIONS) && SMATCH(url, "*")) { return method_options( connection, COMMA_SEPARATED_STRING_LITERALS( MHD_HTTP_METHOD_OPTIONS, MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_HEAD, MHD_HTTP_METHOD_POST)); } else { return not_found(connection, "/", "the front page"); } }
int pop3(ClientSession_T *session, const char *buffer) { /* returns a 0 on a quit * -1 on a failure * 1 on a success */ char *command, *value, *searchptr, *enctype, *s; Pop3Cmd cmdtype; int found = 0; //int indx = 0; int validate_result; bool login_disabled = FALSE; uint64_t result, top_lines, top_messageid, user_idnr; unsigned char *md5_apop_he; struct message *msg; ClientBase_T *ci = session->ci; s = (char *)buffer; strip_crlf(s); g_strstrip(s); TRACE(TRACE_DEBUG, "incoming buffer: [%s]", s); if (! strlen(s)) return 1; int state = session->state; /* check for command issued */ /* while (strchr(ValidNetworkChars, s[indx++])) ; */ command = s; value = strstr(command, " "); /* look for the separator */ if (value != NULL) { *value = '\0'; /* set a \0 on the command end */ value++; /* skip space */ if (strlen(value) == 0) value = NULL; /* no value specified */ else { TRACE(TRACE_DEBUG, "state[%d], command issued :cmd [%s], value [%s]\n", state, command, value); } } /* find command that was issued */ for (cmdtype = POP3_QUIT; cmdtype < POP3_FAIL; cmdtype++) if (strcasecmp(command, commands[cmdtype]) == 0) { session->was_apop = 1; break; } TRACE(TRACE_DEBUG, "command looked up as commandtype %d", cmdtype); /* commands that are allowed to have no arguments */ if (value == NULL) { switch (cmdtype) { case POP3_QUIT: case POP3_LIST: case POP3_STAT: case POP3_RSET: case POP3_NOOP: case POP3_LAST: case POP3_UIDL: case POP3_AUTH: case POP3_CAPA: case POP3_STLS: break; default: return pop3_error(session, "-ERR your command does not compute\r\n"); break; } } if (state == CLIENTSTATE_INITIAL_CONNECT) { if (server_conf->ssl) { Field_T val; GETCONFIGVALUE("login_disabled", "POP", val); if (SMATCH(val, "yes")) login_disabled = TRUE; } } switch (cmdtype) { case POP3_QUIT: /* We return 0 here, and then pop3_handle_connection cleans up * the connection, commits all changes, and sends the final * "OK" message indicating that QUIT has completed. */ session->state = CLIENTSTATE_LOGOUT; session->SessionResult = 0; pop3_close(session); return 0; case POP3_STLS: if (state != CLIENTSTATE_INITIAL_CONNECT) return pop3_error(session, "-ERR wrong command mode\r\n"); if (! server_conf->ssl) return pop3_error(session, "-ERR server error\r\n"); if (session->ci->sock->ssl_state) return pop3_error(session, "-ERR TLS already active\r\n"); ci_write(session->ci, "+OK Begin TLS now\r\n"); if (ci_starttls(session->ci) < 0) return -1; return 1; case POP3_USER: if (state != CLIENTSTATE_INITIAL_CONNECT) return pop3_error(session, "-ERR wrong command mode\r\n"); if (login_disabled && ! session->ci->sock->ssl_state) return pop3_error(session, "-ERR try STLS\r\n"); if (session->username != NULL) { /* reset username */ g_free(session->username); session->username = NULL; } if (session->username == NULL) { /* create memspace for username */ session->username = g_new0(char,strlen(value) + 1); strncpy(session->username, value, strlen(value) + 1); } ci_write(ci, "+OK Password required for %s\r\n", session->username); return 1; case POP3_PASS: if (state != CLIENTSTATE_INITIAL_CONNECT) return pop3_error(session, "-ERR wrong command mode\r\n"); if (login_disabled && ! session->ci->sock->ssl_state) return pop3_error(session, "-ERR try STLS\r\n"); if (session->password != NULL) { g_free(session->password); session->password = NULL; } if (session->password == NULL) { /* create memspace for password */ session->password = g_new0(char,strlen(value) + 1); strncpy(session->password, value, strlen(value) + 1); }