728x90

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *replaceAll(char *s, const char *olds, const char *news);


void main(void){
  char s[] = "봉숭아 학당! 봉숭아 학당! 봉숭아 학당! 봉숭아 학당!";
  char *s2;

  printf("원본: %s\n", s);

  s2 = replaceAll(s, "봉숭아", "맹구");

  // 에러가 있으면 NULL 을 리턴. 에러가 없으면 결과 출력
  (s2 != NULL) ? printf("치환: %s\n", s2) : fputs("Replace String Error...\n", stderr);
}




char *replaceAll(char *s, const char *olds, const char *news) {
  char *result, *sr;
  size_t i, count = 0;
  size_t oldlen = strlen(olds); if (oldlen < 1) return s;
  size_t newlen = strlen(news);


  if (newlen != oldlen) {
    for (i = 0; s[i] != '\0';) {
      if (memcmp(&s[i], olds, oldlen) == 0) count++, i += oldlen;
      else i++;
    }
  } else i = strlen(s);


  result = (char *) malloc(i + 1 + count * (newlen - oldlen));
  if (result == NULL) return NULL;


  sr = result;
  while (*s) {
    if (memcmp(s, olds, oldlen) == 0) {
      memcpy(sr, news, newlen);
      sr += newlen;
      s  += oldlen;
    } else *sr++ = *s++;
  }
  *sr = '\0';

  return result;
}

728x90

I created this small function just to practice C code. It's a simple random string generator.

#include <string.h>
#include <time.h>

char *randstring(int length) {    
    static int mySeed = 25011984;
    char *string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
    size_t stringLen = strlen(string);        
    char *randomString = NULL;

    srand(time(NULL) * length + ++mySeed);

    if (length < 1) {
        length = 1;
    }

    randomString = malloc(sizeof(char) * (length +1));

    if (randomString) {
        short key = 0;

        for (int n = 0;n < length;n++) {            
            key = rand() % stringLen;          
            randomString[n] = string[key];
        }

        randomString[length] = '\0';

        return randomString;        
    }
    else {
        printf("No memory");
        exit(1);
    }
}

The code seems to work ok. Any ideas, improvements or bugs?

I added the mySeed var so that if I call it twice with the same length it doesn't give me the same exact string.

EDIT:

I have changed the code to this:

char *randstring(size_t length) {

    static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";        
    char *randomString = NULL;

    if (length) {
        randomString = malloc(sizeof(char) * (length +1));

        if (randomString) {            
            for (int n = 0;n < length;n++) {            
                int key = rand() % (int)(sizeof(charset) -1);
                randomString[n] = charset[key];
            }

            randomString[length] = '\0';
        }
    }

    return randomString;
}

I know that in the sizeof(charset) you don't have to use the (). You only need them when using sizeof with types, but it's just out of habit.

Your function is nice but has a few issues, the main one being that it should not call srand.srand should be called elsewhere (eg in main) just once. This seeds the random number generator, which need only be done once.

A minor issue is that string is badly named - charset might be better. It should be const and you then need not call strlen to find its length sizeof charset -1 is enough. For me, randomString is an unnecessarily long name.

On failing to allocate memory for the string, I would prefer to see a NULL return than an exit. If you want an error message, use perror, but perhaps in the caller, not here. I would be inclined to avoid the possibility of such an error but passing in the buffer and its length instead of allocating.

Some minor points: sizeof(char) is 1 by definition and using short for key is pointless - just use int. Also key should be defined where it is used and I would leave a space after the ; in the for loop definition.

Note also that using rand() % n assumes that the modulo division is random - that is not what rand promises.

Here is how I might do it:

static char *rand_string(char *str, size_t size)
{
    const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK...";
    if (size) {
        --size;
        for (size_t n = 0; n < size; n++) {
            int key = rand() % (int) (sizeof charset - 1);
            str[n] = charset[key];
        }
        str[size] = '\0';
    }
    return str;
}

Edit July 31 23:07UTC

Why would I write the function to take a buffer instead of allocating the string inside the function?

Returning dynamically allocated strings works fine. And if the memory is later freed there is no problem. But writing this sort of function is a great way to leak memory, for example if the caller doesn't know the memory must be freed or forgets to free memory, or even if he frees it in the main path but forgets to free it in other paths etc.

Memory leaks in a desktop applications might not be fatal, but leaks in an embedded system will lead eventually to failure. This can be serious, depending upon the system involved. In many embedded systems, dynamic allocation is often not allowed or is at least best avoided.

Although it certainly is common not to know the size of strings or buffers at compile time, the opposite is also often true. It is often possible to write code with fixed buffer sizes. I always prefer this option if possible so I would be reluctant to use your allocating function. Perhaps it is better to add a wrapper to a non-allocating function for those cases where you really must allocate dynamically (for example when the random string has to outlive the calling context):

char* rand_string_alloc(size_t size)
{
     char *s = malloc(size + 1);
     if (s) {
         rand_string(s, size);
     }
     return s;
}
  • note that you don't need to return any result because the str parameter is mutable – Quonux Jul 30 '13 at 20:09
  • 1
    That is true but many standard library functions do this too. It can make life easier, eg in printf("%s\n", rand_string(buf, sizeof buf)); – William Morris Jul 30 '13 at 20:12 
  • your right, if you speak of easy life you grab c++,java,go,python,haskell,ruby or d unless your really need the last 100%-20% performance or your forced to use c – Quonux Jul 30 '13 at 20:17 
  • 1
    The questioner is asking specifically about C, not C++, not Java, not go, python etc. Thanks for your input. – William Morris Jul 31 '13 at 0:50
  • @WilliamMorris Could you provide some more insight on why you pass the buffer and not just create the buffer in the string with malloc and return it? Is it because this way it would be easier to free the memory? Is it not possible to free the returned pointer? Thanks. – AntonioCS Jul 31 '13 at 20:56 


'LINUX' 카테고리의 다른 글

How to change broken language -korean  (0) 2019.03.03
C and CPP replace string for function  (0) 2018.07.12
mysql_close segmentation fault (core dumped)  (0) 2018.06.26
Mod_Security2 Ajax Blocking Problem  (0) 2018.06.25
Curl in C usage  (0) 2018.06.24
728x90
MYSQL       *connection=NULL, conn;
MYSQL_RES *sql_result;
MYSQL_ROW sql_row;
int query_stat;

char name[12];
char address[80];
char tel[12];
char query[255];

mysql_init(&conn);

connection = mysql_real_connect(&conn, DB_HOST,
DB_USER, DB_PASS,
DB_NAME, 3306,
(char *)NULL, 0);

위와같이 MYSQL 형 conn 은 MYSQL 형 Socket 을 생성하기 때문에, 연결된 소켓을 connection 에 넘기면 mysql_close 시에 segmentation fault 가 난다.


#include <my_global.h>
#include <mysql.h>

int main(int argc, char **argv)
{  
  MYSQL *con = mysql_init(NULL);

  if (con == NULL) 
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      exit(1);
  }

  if (mysql_real_connect(con, "localhost", "root", "root_pswd", 
          NULL, 0, NULL, 0) == NULL) 
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }  

  if (mysql_query(con, "CREATE DATABASE testdb")) 
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }

  mysql_close(con);
  exit(0);
}

이와 같이 conn 은 1개여야 한다. 절대로 connection 같은것을 만들어 넘기지 않도록 한다.

'LINUX' 카테고리의 다른 글

C and CPP replace string for function  (0) 2018.07.12
Random String generator in C  (0) 2018.07.04
Mod_Security2 Ajax Blocking Problem  (0) 2018.06.25
Curl in C usage  (0) 2018.06.24
Dynamic Library and Static Library  (0) 2018.06.24
728x90

이건 매우 상급 이니까.  아 해봐야지 하고 덤볐다가는 멘탈 붕괴가 무엇인지 느끼게 해준다 =ㅅ=a

apache web server 에 mod_security를 도입하고 OWASP 룰셋를 적용한다음에 관리하는 방법까지 이다.

먼저 mod_security 를 설치 를 위한 의존성 프로그램 을 설치한다.

그후 다운 로드 및 설치.

그다음 httpd.conf 에 불러오는 설정을 해야 겠지요 ‘ㅅ’a

물론 Include 경로를 자신이 운영하는 웹서버 경로에 바꿔야 하는걸 잊지 말자.

음 mod_security 설치는 되었다.

 

이제 룰셋 적용부분.. http://www.modsecurity.org/rules.html

공식 사이트에서는 아래와 같이 두가지 를 추천하고 있다.

무료 – OWASP ModSecurity Core Rule Set (CRS)
유료 – Commercial Rules from Trustwave SpiderLabs

물론 다른 방화벽 업체에서도 룰셋 제공을 하고 있다.

무료 – Comodo Web Application Firewall (CWAF)

여시서는 OWASP 룰셋을 적용할 예정이다.

OWASP 는 (The Open Web Application Security Project) 오픈소스 웹 애플리케이션 보안 프로젝트 이다 자세한 설명은 http://ko.wikipedia.org/wiki/OWASP 요기서 참조 ‘ㅅ’a

여기까지가 설치 완료는 아니고 사용할 룰셋을 익티베이트 룰셋 폴더에 심볼링 링크를 건다.

이후 owasp-modsecurity-crs 요 폴더를 자신의 httpd.conf 에서 불러 오도록 하면 되겠다.

 

호환성에 염두하지 않고 보안 적인 취약점을 막기 위해 제작된 룰셋이기 때문에

바로 돌리면 사이트가 안뜬다 -_-;;

먼저 php.ini 수정이 필요하다.

 

modsecurity_crs_10_setup.conf 파일에 아래부분을 추가 한다.

SecRuleEngine On -> DetectionOnly 로 설정하면 감시만 하고 실제 차단은 하지 않는다.

다만 이 디텍트모드에서 기존 사이트 운영중인것에서 걸리는 룰셋을 수정 하거나 해제 해야 한다.

httpd.conf 를 수정한다.

위와 같이  SecRuleRemoveById 으로 제거를 할수 있으며 디렉토리 혹은 파일명까지 지정하여 사용할 수 있다.

혹은 아래와 같이 가상호스트에서 특정 호스트만 룰셋(SecRuleEngine Off)적용을 끄거나 특정룰만 제거(SecRuleRemoveById)할 수도 있다.

Ajax 를 사용하는 경우 SecRequestBodyAccess On, SecResponseBodyAccess On 두개의 옵션 때문에

Ajax 가 비정상 동작을 할수 있는데 이것역시 Location 혹은 VirtualHost 에서 각기 Off 가 가능하다.

 

정리 하자면 사용할수 있는것은 아래 4가지 이며.

SecRuleEngine Off
SecRequestBodyAccess Off
SecResponseBodyAccess Off
SecRuleRemoveById 룰셋ID

이 일부 혹은 전체 끄는 옵션을을 VirtualHost 혹은 LocationMatch 안에 넣어 일부 허용만 할 수 있다.

 

아래는 이러한 룰셋을 분석하기 위해 아파치의 error_log 를 분석하기 위한 명령어 이다.

 

모드 시큐리티는 apache / nginx 에 도입이 가능하다.

다만 nginx 는 테스트 결과 룰셋에 걸리는 웹접근이 이루어 질때 메모리 및 CPU 가 과다 사용이 되고

kernel – oom – killer 에 의해 프로세스가 강제 종료되는 사례가 발생하였다.

nginx 에서의 모드시큐리티 사용은 좀더 두고 봐야 할것이라고 생각된다.

'LINUX' 카테고리의 다른 글

Random String generator in C  (0) 2018.07.04
mysql_close segmentation fault (core dumped)  (0) 2018.06.26
Curl in C usage  (0) 2018.06.24
Dynamic Library and Static Library  (0) 2018.06.24
Wowza rest api to change content path of streaming video  (0) 2018.06.22

+ Recent posts