source: branches/monitor-improvement/oscam-simples.c@ 1587

Last change on this file since 1587 was 1587, checked in by alno, 11 years ago

WebIf:

  • Merging revisions 1576-1585 of trunk (ump1688)
File size: 12.3 KB
Line 
1#include "globals.h"
2
3static AES_KEY aeskey;
4
5void aes_set_key(char *key)
6{
7 AES_set_decrypt_key((const unsigned char *)key, 128, &aeskey);
8 AES_set_encrypt_key((const unsigned char *)key, 128, &client[cs_idx].aeskey);
9}
10
11void aes_decrypt(uchar *buf, int n)
12{
13 int i;
14 for(i=0; i<n; i+=16)
15 AES_decrypt(buf+i, buf+i, &aeskey);
16}
17
18void aes_encrypt_idx(int idx, uchar *buf, int n)
19{
20 int i;
21 for(i=0; i<n; i+=16)
22 AES_encrypt(buf+i, buf+i, &client[idx].aeskey);
23}
24
25char *remote_txt(void)
26{
27 if (is_server)
28 return("client");
29 else
30 return("remote server");
31}
32
33char *trim(txt)
34char *txt;
35{
36 register int l;
37 register char *p1, *p2;
38
39 if (*txt==' ')
40 {
41 for (p1=p2=txt;
42 (*p1==' ') || (*p1=='\t') || (*p1=='\n') || (*p1=='\r');
43 p1++);
44 while (*p1)
45 *p2++=*p1++;
46 *p2='\0';
47 }
48 if ((l=strlen(txt))>0)
49 for (p1=txt+l-1;
50 (*p1==' ') || (*p1=='\t') || (*p1=='\n') || (*p1=='\r');
51 *p1--='\0');
52
53 return(txt);
54}
55
56char *strtolower(char *txt)
57{
58 char *p;
59 for (p=txt; *p; p++)
60 if (isupper((uchar)*p)) *p=tolower((uchar)*p);
61 return(txt);
62}
63
64int gethexval(char c)
65{
66 if ((c>='0') && (c<='9')) return(c-'0');
67 if ((c>='A') && (c<='F')) return(c-'A'+10);
68 if ((c>='a') && (c<='f')) return(c-'a'+10);
69 return(-1);
70}
71
72int cs_atob(uchar *buf, char *asc, int n)
73{
74 int i, rc;
75 for (i=0; i<n; i++)
76 {
77 if ((rc=(gethexval(asc[i<<1])<<4)|gethexval(asc[(i<<1)+1]))&0x100)
78 return(-1);
79 buf[i]=rc;
80 }
81 return(n);
82}
83
84ulong cs_atoi(char *asc, int l, int val_on_err)
85{
86 int i, n=0;
87 ulong rc=0;
88 for (i=((l-1)<<1), errno=0; (i>=0) && (n<4); i-=2)
89 {
90 int b;
91 b=(gethexval(asc[i])<<4) | gethexval(asc[i+1]);
92 if (b<0)
93 {
94 errno=EINVAL;
95 rc=(val_on_err) ? 0xFFFFFFFF : 0;
96 break;
97 }
98 rc|=b<<(n<<3);
99 n++;
100 }
101 return(rc);
102}
103
104int byte_atob(char *asc)
105{
106 int rc;
107
108 if (strlen(trim(asc))!=2)
109 rc=(-1);
110 else
111 if ((rc=(gethexval(asc[0])<<4)|gethexval(asc[1]))&0x100)
112 rc=(-1);
113 return(rc);
114}
115
116long word_atob(char *asc)
117{
118 long rc;
119
120 if (strlen(trim(asc))!=4)
121 rc=(-1);
122 else
123 {
124 rc=gethexval(asc[0])<<12 | gethexval(asc[1])<<8 |
125 gethexval(asc[2])<<4 | gethexval(asc[3]);
126 if (rc&0x10000)
127 rc=(-1);
128 }
129 return(rc);
130}
131
132int key_atob(char *asc, uchar *bin)
133{
134 int i, n1, n2, rc;
135 for (i=rc=0; i<32; i+=2)
136 {
137 if ((n1=gethexval(asc[i ]))<0) rc=(-1);
138 if ((n2=gethexval(asc[i+1]))<0) rc=(-1);
139 bin[i>>1]=(n1<<4)+(n2&0xff);
140 }
141 return(rc);
142}
143
144int key_atob14(char *asc, uchar *bin)
145{
146 int i, n1, n2, rc;
147 for (i=rc=0; i<28; i+=2)
148 {
149 if ((n1=gethexval(asc[i ]))<0) rc=(-1);
150 if ((n2=gethexval(asc[i+1]))<0) rc=(-1);
151 bin[i>>1]=(n1<<4)+(n2&0xff);
152 }
153 return(rc);
154}
155
156int key_atob_l(char *asc, uchar *bin, int l)
157{
158 int i, n1, n2, rc;
159 for (i=rc=0; i<l; i+=2)
160 {
161 if ((n1=gethexval(asc[i ]))<0) rc=(-1);
162 if ((n2=gethexval(asc[i+1]))<0) rc=(-1);
163 bin[i>>1]=(n1<<4)+(n2&0xff);
164 }
165 return(rc);
166}
167
168char *key_btoa(char *asc, uchar *bin)
169{
170 int i;//, n1, n2, rc;
171 static char buf[33];
172 if (!asc)
173 asc=buf;
174 for (i=0; i<16; i++)
175 sprintf(asc+(i<<1), "%02X", bin[i]);
176 return(asc);
177}
178
179char *cs_hexdump(int m, uchar *buf, int n)
180{
181 int i;
182 static char dump[520];
183
184 dump[i=0]='\0';
185 m=(m)?3:2;
186 if (m*n>=(int)sizeof(dump)) n=(sizeof(dump)/m)-1;
187 while (i<n)
188 sprintf(dump+(m*i++), "%02X%s", *buf++, (m>2)?" ":"");
189 return(dump);
190}
191
192static int inet_byteorder=0;
193in_addr_t cs_inet_order(in_addr_t n)
194{
195 if (!inet_byteorder)
196 inet_byteorder=((inet_addr("1.2.3.4")+1)==inet_addr("1.2.3.5")) ? 1 : 2;
197 switch (inet_byteorder)
198 {
199 case 1:
200 break;
201 case 2:
202 n=((n&0xff000000) >> 24 ) |
203 ((n&0x00ff0000) >> 8 ) |
204 ((n&0x0000ff00) << 8 ) |
205 ((n&0x000000ff) << 24 );
206 break;
207 }
208 return(n);
209}
210
211char *cs_inet_ntoa(in_addr_t n)
212{
213 struct in_addr in;
214 in.s_addr=cs_inet_order(n);
215 return((char *)inet_ntoa(in));
216}
217
218in_addr_t cs_inet_addr(char *txt)
219{
220 if (!inet_byteorder)
221 inet_byteorder=((inet_addr("1.2.3.4")+1)==inet_addr("1.2.3.5")) ? 1 : 2;
222 if (inet_byteorder == 1)
223 return(inet_addr(txt));
224 else
225 return(inet_network(txt));
226}
227
228ulong b2i(int n, uchar *b)
229{
230 switch(n)
231 {
232 case 2:
233 return ((b[0]<<8) | b[1]);
234 case 3:
235 return ((b[0]<<16) | (b[1]<<8) | b[2]);
236 case 4:
237 return (((b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3]) & 0xffffffffL);
238 default:
239 cs_log("Error in b2i, n=%i",n);
240 }
241 return 0;
242}
243
244ullong b2ll(int n, uchar *b)
245{
246 int i;
247 ullong k=0;
248 for(i=0; i<n; k+=b[i++])
249 k<<=8;
250 return(k);
251}
252
253uchar *i2b(int n, ulong i)
254{
255 static uchar b[4];
256 switch(n)
257 {
258 case 2:
259 b[0]=(i>> 8) & 0xff;
260 b[1]=(i ) & 0xff;
261 break;
262 case 3:
263 b[0]=(i>>16) & 0xff;
264 b[1]=(i>> 8) & 0xff;
265 b[2]=(i ) & 0xff;
266 case 4:
267 b[0]=(i>>24) & 0xff;
268 b[1]=(i>>16) & 0xff;
269 b[2]=(i>> 8) & 0xff;
270 b[3]=(i ) & 0xff;
271 break;
272 }
273 return(b);
274}
275
276ulong a2i(char *asc, int bytes)
277{
278 int i, n;
279 ulong rc;
280 for (rc=i=0, n=strlen(trim(asc))-1; i<(abs(bytes)<<1); n--, i++)
281 if (n>=0)
282 {
283 int rcl;
284 if ((rcl=gethexval(asc[n]))<0)
285 {
286 errno=EINVAL;
287 return(0x1F1F1F);
288 }
289 rc|=(rcl<<(i<<2));
290 }
291 else
292 if (bytes<0)
293 rc|=(0xf<<(i<<2));
294 errno=0;
295 return(rc);
296}
297
298int boundary(int exp, int n)
299{
300 return((((n-1)>>exp)+1)<<exp);
301}
302
303void cs_ftime(struct timeb *tp)
304{
305#ifdef NO_FTIME
306 struct timeval tv;
307 gettimeofday(&tv, (struct timezone *)0);
308 tp->time=tv.tv_sec;
309 tp->millitm=tv.tv_usec/1000;
310#else
311 ftime(tp);
312#endif
313}
314
315void cs_sleepms(unsigned int msec)
316{
317 //does not interfere with signals like sleep and usleep do
318 struct timespec req_ts;
319 req_ts.tv_sec = msec/1000;
320 req_ts.tv_nsec = (msec % 1000) * 1000000L;
321 nanosleep (&req_ts, NULL);
322}
323
324int bytes_available(int fd)
325{
326 struct pollfd pfds;
327 pfds.fd=fd;
328 pfds.events=POLLIN;
329 pfds.revents=0;
330 if (poll(&pfds, 1, 0)!=1)
331 return(0);
332 else
333 return(((pfds.revents)&POLLIN)==POLLIN);
334}
335
336
337#ifdef OS_CYGWIN32
338#include <windows.h>
339void cs_setpriority(int prio)
340{
341 HANDLE WinId;
342 ulong wprio;
343 switch((prio+20)/10)
344 {
345 case 0: wprio=REALTIME_PRIORITY_CLASS; break;
346 case 1: wprio=HIGH_PRIORITY_CLASS; break;
347 case 2: wprio=NORMAL_PRIORITY_CLASS; break;
348 default: wprio=IDLE_PRIORITY_CLASS; break;
349 }
350 WinId=GetCurrentProcess();
351 SetPriorityClass(WinId, wprio);
352}
353#else
354void cs_setpriority(int prio)
355{
356#ifdef PRIO_PROCESS
357 setpriority(PRIO_PROCESS, 0, prio); // ignore errors
358#endif
359}
360#endif
361
362/* Helper function for urldecode.*/
363int x2i(int i){
364 i=toupper(i);
365 i = i - '0';
366 if(i > 9) i = i - 'A' + '9' + 1;
367 return i;
368}
369
370/* Decodes values in a http url */
371void urldecode(char *s){
372 int c, c1, n;
373 char *s0,*t;
374 t = s0 = s;
375 n = strlen(s);
376 while(n >0){
377 c = *s++;
378 if(c == '+') c = ' ';
379 else if(c == '%' && n > 2){
380 c = *s++;
381 c1 = c;
382 c = *s++;
383 c = 16*x2i(c1) + x2i(c);
384 n -= 2;
385 }
386 *t++ = c;
387 n--;
388 }
389 *t = 0;
390}
391
392/* Helper function for urlencode.*/
393char to_hex(char code){
394 static char hex[] = "0123456789abcdef";
395 return hex[code & 15];
396}
397
398/* Encode values in a http url. Note: Be sure to free() the returned string after use */
399char *urlencode(char *str){
400 char *pstr = str, *buf = (char *) malloc((strlen(str) * 3 + 1) * sizeof(char)), *pbuf = buf;
401 while (*pstr) {
402 if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') *pbuf++ = *pstr;
403 else if (*pstr == ' ') *pbuf++ = '+';
404 else {
405 *pbuf++ = '%';
406 *pbuf++ = to_hex(*pstr >> 4);
407 *pbuf++ = to_hex(*pstr & 15);
408 }
409 ++pstr;
410 }
411 *pbuf = '\0';
412 pbuf = (char *) malloc((strlen(buf) + 1) * sizeof(char));
413 strcpy(pbuf, buf);
414 free(buf);
415 return pbuf;
416}
417
418/* Converts a long value to a char array in bitwise representation.
419 Note that the result array MUST be at least 33 bit large and that
420 this function assumes long values to hold only values up to 32bits and to be positive!
421 the result of e.g. long 7 is 11100000000000000000000000000000 this means the array
422 is reversed */
423void long2bitchar(long value, char *result){
424 int pos;
425 for (pos=0;pos<32;pos++) result[pos]='0';
426 result[pos] = '\0';
427
428 pos=0;
429 while (value > 0 && pos < 32){
430 if(value % 2 == 1) result[pos]='1';
431 else result[pos]='0';
432 value=value / 2;
433 pos++;
434 }
435}
436
437/* Converts a char array to a char array with hex values (needed for example for md5). The hex2ascii
438 array is a lookup table with the corresponding hex string on the array position of the integer representation
439 of the ascii value. Note that you need to "free" the resulting array after usage or you'll get a memory leak!*/
440char *char_to_hex(const unsigned char* p_array, unsigned int p_array_len, char hex2ascii[256][2]) {
441 unsigned char* str = (unsigned char*)malloc(p_array_len*2+1);
442 str[p_array_len*2] = '\0';
443 const unsigned char* p_end = p_array + p_array_len;
444 size_t pos=0;
445 const unsigned char* p;
446 for( p = p_array; p != p_end; p++, pos+=2 ) {
447 str[pos] = hex2ascii[*p][0];
448 str[pos+1] = hex2ascii[*p][1];
449 }
450 return (char*)str;
451}
452
453/* Creates a random string with specified length. Note that dst must be one larger than size to hold the trailing \0*/
454void create_rand_str(char *dst, int size){
455 static const char text[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
456 int i;
457 for (i = 0; i < size; ++i){
458 dst[i] = text[rand() % (sizeof(text) - 1)];
459 }
460 dst[i] = '\0';
461}
462
463/* Return 1 if the file exists, else 0 */
464int file_exists(const char * filename){
465 FILE *file;
466 if ((file = fopen(filename, "r"))){
467 fclose(file);
468 return 1;
469 }
470 return 0;
471}
472
473/* Clears the s_ip structure provided. The pointer will be set to NULL so everything is cleared.*/
474void clear_sip(struct s_ip **sip){
475 struct s_ip *cip = *sip, *lip;
476 for (*sip = NULL; cip != NULL; cip = lip){
477 lip = cip->next;
478 free(cip);
479 }
480}
481
482/* Clears the s_ptab struct provided by setting nfilts and nprids to zero. */
483void clear_ptab(struct s_ptab *ptab){
484 int i;
485 for (i = 0; i < ptab->nports; i++) {
486 ptab->ports[i].ftab.nfilts = 0;
487 ptab->ports[i].ftab.filts[0].nprids = 0;
488 }
489 ptab->nports = 0;
490}
491
492/* Overwrites destfile with tmpfile. If forceBakOverWrite = 0, the bakfile will not be overwritten if it exists, else it will be.*/
493int safe_overwrite_with_bak(char *destfile, char *tmpfile, char *bakfile, int forceBakOverWrite){
494 if(forceBakOverWrite != 0 && file_exists(bakfile)){
495 if(remove(bakfile) < 0) cs_log("Error removing backup conf file %s (errno=%d)! Will try to proceed nonetheless...", bakfile, errno);
496 }
497 if(file_exists(bakfile)){
498 if(remove(destfile) < 0) {
499 cs_log("Error removing original conf file %s (errno=%d). Will maintain original one!", destfile, errno);
500 if(remove(tmpfile) < 0) cs_log("Error removing temp conf file %s (errno=%d)!", tmpfile, errno);
501 return(1);
502 }
503 } else {
504 if(rename(destfile, bakfile) < 0){
505 cs_log("Error renaming original conf file %s to %s (errno=%d). Will maintain original one!", destfile, bakfile, errno);
506 if(remove(tmpfile) < 0) cs_log("Error removing temp conf file %s (errno=%d)!", tmpfile, errno);
507 return(1);
508 }
509 }
510 if(rename(tmpfile, destfile) < 0){
511 cs_log("Error renaming new conf file %s to %s (errno=%d). The config will be missing upon next startup as this is non-recoverable!", tmpfile, destfile, errno);
512 return(1);
513 }
514 return(0);
515}
516
517/* Replacement of fprintf which adds necessary whitespace to fill up the varname to a fixed width.
518 If varname is longer than varnameWidth, no whitespace is added*/
519void fprintf_conf(FILE *f, int varnameWidth, const char *varname, const char *fmtstring, ...){
520 int varlen = strlen(varname);
521 int max = (varlen > varnameWidth) ? varlen : varnameWidth;
522 char varnamebuf[max + 3];
523 char *ptr = varnamebuf + varlen;
524 va_list argptr;
525
526 strcpy(varnamebuf, varname);
527 while(varlen < varnameWidth){
528 ptr[0] = ' ';
529 ++ptr;
530 ++varlen;
531 }
532 strcpy(ptr, "= ");
533 fwrite(varnamebuf, sizeof(char), strlen(varnamebuf), f);
534 if(strlen(fmtstring) > 0){
535 va_start(argptr, fmtstring);
536 vfprintf(f, fmtstring, argptr);
537 va_end(argptr);
538 }
539}
540
541/* Ordinary strncpy does not terminate the string if the source is exactly as long or longer as the specified size. This can raise security issues.
542 This function is a replacement which makes sure that a \0 is always added. num should be the real size of char array (do not subtract -1). */
543void cs_strncpy(char * destination, const char * source, size_t num){
544 uint32 l, size = strlen(source);
545 if(size > num - 1) l = num - 1;
546 else l = size;
547 memcpy(destination, source, l);
548 destination[l] = '\0';
549}
Note: See TracBrowser for help on using the repository browser.