00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "defines.h"
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <ctype.h>
00027 #include <string.h>
00028 #include <sys/types.h>
00029
00030 #include <time.h>
00031
00032 #include "readline.h"
00033 #include "hashlib.h"
00034 #include "utils.h"
00035 #include "configparser.h"
00036 #include "cfcgi.h"
00037 #include "template.h"
00038 #include "clientlib.h"
00039 #include "fo_post.h"
00040
00041
00042 struct {
00043 int poas_must_validate;
00044 u_char **bws;
00045 long bws_len;
00046 int bws_allowed;
00047 float fds_allowed;
00048 int qp;
00049 int qp_must_validate;
00050 } flt_poas_conf = { 0, NULL, 0, 3, 5.0, 25, 0 };
00051
00052 int last_chars_consist_of(u_char *str,u_char *signs,size_t backnum,int all) {
00053 register u_char *ptr,*sign;
00054 size_t matched;
00055 u_char *lsigns = strdup(signs);
00056
00057 for(ptr=str;ptr != str-backnum;ptr--) {
00058 for(matched=0,sign=signs;*sign;sign++) {
00059 if(*ptr == *sign) {
00060 matched = 1;
00061 break;
00062 }
00063 }
00064
00065 if(matched == 0) {
00066 free(lsigns);
00067 return -1;
00068 }
00069
00070 lsigns[sign-signs] = '\0';
00071 }
00072
00073 if(all) {
00074 for(matched=0;matched<strlen(signs);matched++) {
00075 if(lsigns[matched] != '\0') {
00076 free(lsigns);
00077 return -1;
00078 }
00079 }
00080 }
00081
00082 free(lsigns);
00083 return 0;
00084 }
00085
00086 float flt_poas_check_for_signs(u_char *str,int strict,int musthave) {
00087 register u_char *ptr;
00088 int signs;
00089 int gotsigns = 0;
00090
00091 for(signs = 0,ptr=str;*ptr;ptr++) {
00092 switch(*ptr) {
00093 case '.':
00094 case '!':
00095 case '?':
00096 case ':':
00097 case ';':
00098 case ',':
00099 signs++;
00100 gotsigns = 1;
00101 break;
00102 default:
00103 if(signs >= 2) {
00104
00105 if(signs > 3) return 3.0;
00106
00107 switch(strict) {
00108 case 0:
00109 case 1:
00110
00111 if(cf_strncmp(ptr-signs,"...",signs)) break;
00112
00113
00114 if(last_chars_consist_of(ptr,"?!",signs,1) == 0) break;
00115
00116
00117 if(strict == 1) return 2.0;
00118 break;
00119
00120 case 2:
00121 return 2.0;
00122 break;
00123 }
00124 }
00125
00126 signs = 0;
00127 }
00128 }
00129
00130 if(musthave && gotsigns == 0) return 3.0;
00131
00132 return .0;
00133 }
00134
00135 int flt_poas_check_for_cases(u_char *str) {
00136 register u_char *ptr;
00137 int has_big = 0,has_small,big_after = 0;
00138
00139 for(ptr=str;*ptr;ptr++) {
00140 if(isupper(*ptr)) {
00141 has_big++;
00142 big_after++;
00143 }
00144 else if(islower(*ptr)) {
00145 has_small++;
00146 big_after = 0;
00147 }
00148 else big_after = 0;
00149
00150 if(big_after > 4) return has_small ? 2.0 : 3.0;
00151 }
00152
00153 if(!has_small) return 3.0;
00154 if(!has_big) return 1.0;
00155
00156 return .0;
00157 }
00158
00159 int flt_poas_check_newlines(u_char *str) {
00160 register u_char *ptr;
00161 int nl;
00162
00163 for(ptr=str,nl=0;*ptr;ptr++) {
00164 if(*ptr == '<') {
00165 if(cf_strncmp(ptr,"<br />",6) == 0) {
00166 nl++;
00167 }
00168 }
00169 }
00170
00171 if(nl <= 2) return 3.0;
00172
00173 return .0;
00174 }
00175
00176 int flt_poas_standardchecks(t_message *p) {
00177 float score = flt_poas_conf.fds_allowed;
00178
00179 score -= flt_poas_check_for_signs(p->subject,0,0);
00180 score -= flt_poas_check_for_signs(p->author,2,0);
00181 score -= flt_poas_check_for_signs(p->content,1,1);
00182
00183 score -= flt_poas_check_for_cases(p->subject);
00184 score -= flt_poas_check_for_cases(p->author);
00185 score -= flt_poas_check_for_cases(p->content);
00186
00187 score -= flt_poas_check_newlines(p->content);
00188
00189 return score >= .0 ? 0 : -1;
00190 }
00191
00192 int flt_poas_execute(t_cf_hash *head,t_configuration *dc,t_configuration *pc,t_message *p,int sock,int mode) {
00193
00194 if(cf_cgi_get(head,"assicheck") == NULL || flt_poas_conf.poas_must_validate) {
00195 if(flt_poas_standardchecks(p) != 0) {
00196 cf_cgi_set(head,"assicheck","1");
00197 strcpy(ErrorString,"E_posting_format");
00198 display_posting_form(head);
00199 return FLT_EXIT;
00200 }
00201
00202 return FLT_OK;
00203 }
00204
00205 return FLT_DECLINE;
00206 }
00207
00208 int flt_poas_handle(t_configfile *cfile,t_conf_opt *opt,u_char **args,int argnum) {
00209 switch(*opt->name) {
00210 case 'P':
00211 flt_poas_conf.poas_must_validate = cf_strcmp(args[0],"yes") == 0;
00212 break;
00213 case 'F':
00214 flt_poas_conf.fds_allowed = atof(args[0]);
00215 break;
00216 case 'B':
00217 if(cf_strcmp(opt->name,"BadWords") == 0) flt_poas_conf.bws_len = split(args[0],",",&flt_poas_conf.bws);
00218 else flt_poas_conf.bws_allowed = atoi(args[0]);
00219 break;
00220 case 'Q':
00221 if(cf_strcmp(args[0],"QuotingPercent") == 0) flt_poas_conf.qp = atoi(args[0]);
00222 else flt_poas_conf.qp_must_validate = cf_strcmp(args[0],"yes") == 0;
00223 break;
00224
00225 default:
00226 return 1;
00227 }
00228
00229 return 0;
00230 }
00231
00232 void flt_poas_finish(void) {
00233 }
00234
00235 t_conf_opt flt_poas_config[] = {
00236 { "PostingAssistantMustValidate", flt_poas_handle, NULL },
00237 { "BadWords", flt_poas_handle, NULL },
00238 { "BadwordsAllowed", flt_poas_handle, NULL },
00239 { "FormateDeficitesAllowed", flt_poas_handle, NULL },
00240 { "QuotingPercent", flt_poas_handle, NULL },
00241 { "QuoteMustValidate", flt_poas_handle, NULL },
00242 { NULL, NULL, NULL }
00243 };
00244
00245 t_handler_config flt_poas_handlers[] = {
00246 { NEW_POST_HANDLER, flt_poas_execute },
00247 { 0, NULL }
00248 };
00249
00250 t_module_config flt_poas = {
00251 flt_poas_config,
00252 flt_poas_handlers,
00253 NULL,
00254 NULL,
00255 NULL,
00256 flt_poas_finish
00257 };
00258
00259