기본 콘텐츠로 건너뛰기

라벨이 C++인 게시물 표시

Google 서비스 계정 액세스토큰을 C/C++로 얻어내기

OAuth2에서 인증을 흔히 3단계 과정으로 얻어내는데, 이것을 "three-legged OAuth(줄여서 3LO)"라고 한다. 여기에서 반드시 사람이 OAuth를 제공하는 측 인증화면에 인증질을 하는게 보통이다. 그러나 서비스를 개발하면서 자동인증이 필요할 때가 있다. 서비스 감사 등의 부분에서 말이다. 이때 구글 OAuth2는 2LO를 지원한다. 단, 특수 계정이 필요하고, 지원 API가 한정적이다. (보안이슈 등) 참조:  Using OAuth 2.0 for Server to Server Applications 위 문서에서 다른 건 필요 없고, 개발 콘솔에서 <서비스 계정>을 생성하고, P12(PKCS#12) 파일을 다운로드 받아놓는 것에 주목하자. 문서에 보면 OAuth 주소 어찌고 저찌고... 요청응답 순서는 이렇지만, 그러지 말고 구글에서 미리 만들어놓은 클라이언트 라이브러리 가져다 써라 어쩌라 되어 있다. 좋다. 구글은 미리 예쁘게 Java, Python, PHP 등으로 클라이언트 라이브러리를 짜놨다. 하지만 C/C++은 없더라. 그래서 구글이 만들어놓은 PHP 클라이언트 라이브러리 소스 뜯어 보면서 액세스 토큰을 C/C++로 얻어내보았다. 사용라이브러리는 아래와 같다. OpenSSL >= 1.0.0 : http://openssl.org JsonCpp:  https://github.com/open-source-parsers/jsoncpp cURL:  http://curl.haxx.se 그러나 예제 소스에는 거의 의사코드 수준으로만... ㅋㅋㅋ Google OAuth2에 서비스 계정을 만드려면, JWT(Json Web Token, 발음 주의: 좃)이라는 포맷으로 요청을 해야한다. JWT 참조:  http://jwt.io/ (여기에서도 C/C++ 라이브러리는 찾아 볼 수가 없다) 영어 다시 해석하려면 어려우니까 미리 말을 남겨놔야겠다. ㅋㅋ...

간단한 정수 이야기

C/C++ 정수 타입에는 여러가지가 있다. 크기별로 int8_t, int16_t, int32_t, int64_t 등이 있고, 앞에 sign-bit 사용 여부에 따라 앞에 u를 붙이기도 한다. 크기나 길이를 나타내는 size_t/ssize_t라는 것도 있다. 시스템마다 다르며, 보통 컴파일러가 지원하는 가장 큰 정수를 기반으로 만들어진다. printf 등에 사용할 포맷으로는 %zd, %zu로 쓸 수 있다. 포인터는 메모리 주소값이고, 이것 역시 정수로 표현이 가능하다. 이러한 것은 intptr_t/uintptr_t를 쓸 수 있다. 컴파일러가 지원하는 가장 큰 정수는 intmax_t/uintmax_t이고, printf 등에 사용할 포맷으로 %jd, %ju를 쓸 수 있다. 문자열을 정수로 변환하는 함수로 많이 쓰이는 atoi는 10진법 문자열을 int형태로만 변환할 수 있다. 정수 크기에 따라, 진법에 따라 문자열을 정수로 변환할 때는 strtoXXX함수를 쓸 수 있다. 지원하는 함수는 strtol, strtoll, strtoul, strtoull 등이 있으며, intmax_t/uintmax_t을 위해 strtoimax/strtoumax 가 있다. 원본 위치: http://purewell.egloos.com/5075891

Double free

각종 표준에는 이미 해체한 메모리를 다시 해체하려고 할 때 행동을 정의하지 않고 있으나, GLIBC는 깔끔하게 자살해주고 있다. 자살할 때 패턴을 눈에 익혀 놓으면 나중에 왜 죽었지?하는 일이 줄어들 것이다. #include <stdlib.h> int main(int argc, char* argv[]) { void* p(malloc(1024)); free(p); free(p); return 0; } 컴파일 및 실행 $ g++ -O2 -g dblfree.cpp -o dblfree $ ./dblfree *** glibc detected *** ./dblfree: double free or corruption (top): 0x000000001460a010 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3704671684] /lib64/libc.so.6(cfree+0x8c)[0x3704674ccc] ./dblfree(__gxx_personality_v0+0x10e)[0x4005de] /lib64/libc.so.6(__libc_start_main+0xf4)[0x370461d8b4] ./dblfree(__gxx_personality_v0+0x39)[0x400509] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:07 45776987 /home/purewell/tmp/dblfree 00600000-00601000 rw-p 00000000 08:07 45776987 /home/purewell/tmp/dblfree 1460a000-1462b000 rw-p 1460a000 00:00 0 3703600000-370361a000 r-xp 00000000 08:03 4845228 ...

char도 부호가 있다

#include <stdlib.h> #include <stdio.h> int main(int argc, char* argv[]) { char b = 255; int a = b; printf("%d\n", a); return 0; } 아무런 옵션을 주지 않고 gcc로 컴파일 하면 결과는 -1 이 나온다. 그러나 " -funsigned-char "옵션을 주고 컴파일하면 255 가 나온다. 어떤게 표준이려나? 전자일까? Powered by ScribeFire . 원본 위치: http://purewell.egloos.com/3576438

unsigned type & loop

C/C++에는 여러가지 숫자변수형태가 있고, 이는 부호가 있는 것(signed)과 없는 것(unsigned)으로 나눌 수 있다. 오늘 할 이야기는 그 중에 하나 키가 크고요~...가 아니라 부호가 없는 것에 대한 저주스런 이야기이다. size_t i(delta); while ( i >= 0 ) { // blar blar... --i; } 이 소스는 CPU 100%를 쳐먹으면서 기계를 혹사시킬 것이다. 컴파일러나 라이브러리에 따라 그 구현이 다르겠지만, 보통 size_t는 unsigned long형이다. 십장생. i가 0이어도 루프는 한 번 더 돈다. 마지막에 i가 0이지만 감소연산을 때리면, i는 그것이 가질 수 있는 최대값으로 변모한다. 당연하지... unsigned니까. 결국 저 악마 같은 코드는 무한루프를 도는 것이다. 몇 년을 C/C++로 밥 벌어먹고 살아도 실수는 계속하기 마련인가?! 원본 위치: http://purewell.egloos.com/3417102