JunkBox_Lib  1.10.2
isnet_client.c
Go to the documentation of this file.
1 // クライアント側でのコマンド送信処理
3 //
4 
22 int send_command_recv_ans(int sock, char* command, int tm, Buffer* key, EVP_CIPHER* cipher)
23 {
24  int cc, nn;
25  Buffer ret, ans, buf, eno;
26 
27  if (command==NULL) return JBXL_ARGS_ERROR;
28 
30  copy_s2Buffer(command, &buf);
31  cat_s2Buffer("\r\n", &buf);
32  cc = tcp_send_crypt_sBuffer(sock, &buf, key, cipher);
33  free_Buffer(&buf);
34 
35  ret = make_Buffer(LNAME);
36  cc = tcp_recv_Buffer_wait(sock, &ret, tm);
37  if (cc<=0) {
38  free_Buffer(&ret);
39  return cc;
40  }
41  buf = get_plain_sBuffer(ret, key, cipher);
42  chomp_Buffer(&buf);
43  ans = get_command(buf);
44 
45  if (!strcmp("OK", (const char*)ans.buf)) nn = 0;
46  else if (!strcmp("ERR", (const char*)ans.buf)) {
47  eno = get_operand(buf);
48  nn = atoi((const char*)eno.buf);
49  free_Buffer(&eno);
50  DEBUG_MODE PRINT_MESG("SEND_COMMAND_RECV_ANS: error = %d\n", nn);
51  }
52  else nn = JBXL_ISNET_CMD_ERROR;
53 
54  free_Buffer(&ret);
55  free_Buffer(&buf);
56  free_Buffer(&ans);
57 
58  return nn;
59 }
60 
61 
77 Buffer recv_mesg_until_end(int sock, int tm, Buffer* key, EVP_CIPHER* cipher)
78 {
79  int cc;
80  Buffer ret, buf, dec;
81 
82  ret = make_Buffer(LBUF);
84 
85  do {
86  cc = tcp_recv_Buffer_wait(sock, &buf, tm);
87  if (cc>0) {
88  cat_Buffer(&buf, &ret);
89  clear_Buffer(&buf);
90  if (key!=NULL && cipher!=NULL) {
91  if (!strnrvscmp("\r\n", (const char*)ret.buf, 2)) break;
92  }
93  else {
94  if (!strnrvscmp("\r\nEND\r\n", (const char*)ret.buf, 7) ||
95  !strnrvscmp("\nEND\n", (const char*)ret.buf, 5)) break;
96  }
97  }
98  } while(cc>0);
99 
100  dec = get_plain_sBuffer(ret, key, cipher);
101  free_Buffer(&buf);
102  free_Buffer(&ret);
103  return dec;
104 }
105 
106 
120 Buffer send_algor_recv_spki(int sock, char* algor, int tm, Buffer* key, EVP_CIPHER* cipher)
121 {
122  int cc;
123  Buffer com, ret, buf;
124 
125  ret = init_Buffer(); // 初期化
126  if (algor==NULL) return ret;
127 
128  com = make_Buffer_bystr((char*)"KEYEX ");
129  cat_s2Buffer(algor, &com);
130  cc = send_command_recv_ans(sock, (char*)com.buf, tm, key, cipher);
131  free_Buffer(&com);
132  if (cc!=0) { ret.state = cc; return ret; }
133 
134  ret = recv_mesg_until_end(sock, tm, key, cipher); // サーバの返答
135  buf = get_line_Buffer(ret, 1); // SPKI(BASE64)
136  free_Buffer(&ret);
137 
138  ret = decode_base64_Buffer(buf); // 鍵をデコードする.
139  free_Buffer(&buf);
140 
141  return ret;
142 }
143 
144 
159 int send_spki_recv_ans(int sock, Buffer mkey, int tm, Buffer* key, EVP_CIPHER* cipher)
160 {
161  int cc;
162  Buffer enc;
163 
164  cc = send_command_recv_ans(sock, (char*)"KEYEX SPKI", tm, key, cipher);
165  if (cc!=0) return cc;
166 
167  enc = encode_base64_Buffer(mkey); // 自分の公開鍵情報をエンコード
168  cc = send_command_recv_ans(sock, (char*)enc.buf, tm, key, cipher);
169  free_Buffer(&enc);
170 
171  return cc;
172 }
173 
174 
176 // クライアント側での認証処理
177 //
178 
207 int check_auth(Buffer ahost, int aport, Buffer userid, Buffer passwd, int chmode, int keyex, int cryptm, char* cfn, int cont)
208 {
209  int cryptf, sock, cc, tm = 10;
210  Buffer ipaddr, buf, salt;
211  Buffer shdkey;
212  char* pass;
213  char* chip;
214 
215  if (ahost.buf==NULL) return JBXL_ARGS_ERROR;
216 
217  // 認証サーバへ接続
218  sock = tcp_client_socket((char*)ahost.buf, aport);
219  if (sock<0) {
220  DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server open error.\n");
222  }
223  DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server opened.\n");
224 
225  // 通信開始
226  cc = send_command_recv_ans(sock, (char*)"HELLO", tm, NULL, NULL);
227  if (cc!=0) {
228  socket_close(sock);
229  return JBXL_ISNET_START_ERROR;
230  }
231 
232  shdkey = init_Buffer();
233  // supported only DH now
234  //if (keyex!=SSL_DH) return JBXL_ISNET_PUBKEYALG_ERROR;
235 
236  // 暗号合意
237  cryptf = FALSE;
238  EVP_CIPHER* cipher = NULL;
239  if (keyex!=0 && cryptm!=0) {
240  cryptf = TRUE;
241  chip = get_ipaddr_byname((char*)ahost.buf, AF_INET);
242  ipaddr = make_Buffer_bystr(chip);
243  freeNull(chip);
244  cc = start_CRYPT_transfer(sock, keyex, cryptm, ipaddr, cfn, tm, &shdkey, &cipher);
245  free_Buffer(&ipaddr);
246  if (cc!=0 && !cont) {
247  free_EVP_CIPHER(&cipher);
248  socket_close(sock);
249  return cc;
250  }
251  // 以後暗号化通信
252  }
253 
254  // チャレンジキー合意
255  if (cryptf==FALSE) chmode = ON;
256 
257  if (chmode==ON) {
258  cc = send_command_recv_ans(sock, (char*)"KEYEX CHLNG", tm, &shdkey, cipher);
259  if (cc!=0) {
260  socket_close(sock);
262  }
263  }
264  else {
265  cc = send_command_recv_ans(sock, (char*)"KEYEX NOCHLNG", tm, &shdkey, cipher);
266  if (cc!=0) {
267  if (cc==169) { // Unkown KEYEX operand. Support for old version.
268  chmode = ON;
269  }
270  else {
271  socket_close(sock);
273  }
274  }
275  }
276 
278  // ユーザIDを送る.
279  buf = make_Buffer(LBUF);
280  copy_s2Buffer("USERID ", &buf);
281  cat_Buffer(&userid, &buf);
282  cc = send_command_recv_ans(sock, (char*)buf.buf, tm, &shdkey, cipher);
283  if (cc!=0) {
284  free_Buffer(&buf);
285  free_EVP_CIPHER(&cipher);
286  socket_close(sock);
287  return JBXL_ISNET_USER_ERROR;
288  }
289 
290  // SALTを得る.
291  if (chmode==ON) {
292  salt = recv_mesg_until_end(sock, tm, &shdkey, cipher);
293  //DEBUG_MODE PRINT_ESC("SALT = [%s]\n", (char*)salt.buf);
294  }
295  clear_Buffer(&buf);
296 
297  // パスワードを計算して送る.
298  copy_s2Buffer("PASSWD ", &buf);
299  if (chmode==ON) {
300  pass = x2crypt((char*)passwd.buf, (char*)salt.buf);
301  cat_s2Buffer(pass, &buf);
302  freeNull(pass);
303  }
304  else {
305  cat_s2Buffer((char*)passwd.buf, &buf);
306  }
307  cc = send_command_recv_ans(sock, (char*)buf.buf, tm, &shdkey, cipher);
308  free_Buffer(&buf);
309 
310  if (cc) {
311  free_EVP_CIPHER(&cipher);
312  socket_close(sock);
314  }
315 
316  // 暗号化通信終了
317  if (cryptf) cc = stop_CRYPT_transfer(sock, tm, &shdkey, cipher);
318 
319  cc = send_command_recv_ans(sock, (char*)"BYE", tm, &shdkey, cipher);
320 
321  socket_close(sock);
322  DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server normally closed.\n");
323 
324  free_EVP_CIPHER(&cipher);
325  if (cryptf) free_Buffer(&shdkey);
326 
327  return 0;
328 }
329 
330 
332 // クライアント側での暗号開始・終了処理
333 //
334 
357 int start_CRYPT_transfer(int sock, int keyex, int cryptm, Buffer ipaddr, char* cfn, int tm, Buffer* shdkey, EVP_CIPHER** cipher)
358 {
359  Buffer spki, mpki;
360 
361  if (cfn!=NULL && ipaddr.buf!=NULL) {
362  if (!check_server_spki(ipaddr, spki, cfn)) return JBXL_ISNET_SERVER_ERROR;
363  }
364 
365  if (keyex==SSL_DH) {
366  spki = send_algor_recv_spki(sock, (char*)"DH", tm, NULL, NULL);
367  //
368  if (spki.buf!=NULL) {
369  JBXL_DH* dhkey = NULL;
370  mpki = gen_DHspki_fs(spki, &dhkey);
371  if (dhkey!=NULL) {
372  gen_CRYPT_SharedKey(keyex, spki, shdkey, (void*)dhkey);
373  JBXL_DH_free(dhkey);
374  }
375  else {
376  PRINT_MESG("ERROR: start_CRYPT_transfer: DH Key is NULL\n");
377  return JBXL_ISNET_DHKEY_ERROR;
378  }
379  }
380  else {
381  PRINT_MESG("ERROR: start_CRYPT_transfer: spki is NULL\n");
383  }
384  }
385  //else if (keyex==SSL_RSA) spki = send_algor_recv_spki(sock, (char*)"RSA", tm);
386  else return JBXL_ISNET_PUBKEYALG_ERROR;
387 
388  /*
389  DEBUG_MODE {
390  Buffer enc;
391  enc = encode_base64_Buffer(spki);
392  PRINT_MESG("SERVER SPKI = [%s]\n", enc.buf);
393  free_Buffer(&enc);
394  }*/
395 
396  int cc = send_spki_recv_ans(sock, mpki, tm, NULL, NULL);
397  if (cc==0) {
398  if (cryptm==SSL_AES128CBC) {
399  cc = send_command_recv_ans(sock, (char*)"CRYPT AES128CBC", tm, NULL, NULL);
400  *cipher = init_EVPAPI_Buffer(SSL_AES128CBC);
401  }
402  else if (cryptm==SSL_3DES3CBC) {
403  cc = send_command_recv_ans(sock, (char*)"CRYPT 3DES3CBC", tm, NULL, NULL);
404  *cipher = init_EVPAPI_Buffer(SSL_3DES3CBC);
405  }
406  }
407 
408  free_Buffer(&spki);
409  free_Buffer(&mpki);
410  if (cc!=0) {
411  free_Buffer(shdkey);
412  *cipher = NULL;
413  return cc;
414  }
415 
416  return 0;
417 }
418 
419 
436 int stop_CRYPT_transfer(int sock, int tm, Buffer* shdkey, EVP_CIPHER* cipher)
437 {
438  int cc;
439 
440  cc = send_command_recv_ans(sock, (char*)"CRYPT RESET", tm, shdkey, cipher);
441  return cc;
442 }
443 
444 
Buffer encode_base64_Buffer(Buffer buf)
バイナリデータ buf.bufの buf.vldszバイトを Base64にエンコード する
Definition: buffer.c:804
Buffer get_line_Buffer(Buffer str, int n)
複数行の文字列バッファから任意の行を取り出す.
Definition: buffer.c:956
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
void chomp_Buffer(Buffer *str)
最初の改行コード以降を無視する.
Definition: buffer.c:1347
void clear_Buffer(Buffer *str)
Buffer型変数 のバッファ部を 0クリアする.
Definition: buffer.c:272
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
Buffer decode_base64_Buffer(Buffer str)
strのバッファを Base64からデコードする
Definition: buffer.c:850
int cat_Buffer(Buffer *src, Buffer *dst)
Buffer変数 srcから dstへバッファを catする.
Definition: buffer.c:384
#define copy_s2Buffer(src, dst)
copy_b2Buffer()
Definition: buffer.h:108
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define LNAME
Definition: common.h:153
#define RECVBUFSZ
256K
Definition: common.h:134
#define LBUF
Definition: common.h:146
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
#define ON
Definition: common.h:230
Buffer get_operand(Buffer msg)
Definition: isnet.c:65
Buffer get_command(Buffer msg)
Definition: isnet.c:36
int start_CRYPT_transfer(int sock, int keyex, int cryptm, Buffer ipaddr, char *cfn, int tm, Buffer *shdkey, EVP_CIPHER **cipher)
Definition: isnet_client.c:357
int send_spki_recv_ans(int sock, Buffer mkey, int tm, Buffer *key, EVP_CIPHER *cipher)
Definition: isnet_client.c:159
int check_auth(Buffer ahost, int aport, Buffer userid, Buffer passwd, int chmode, int keyex, int cryptm, char *cfn, int cont)
Definition: isnet_client.c:207
Buffer send_algor_recv_spki(int sock, char *algor, int tm, Buffer *key, EVP_CIPHER *cipher)
Definition: isnet_client.c:120
int stop_CRYPT_transfer(int sock, int tm, Buffer *shdkey, EVP_CIPHER *cipher)
Definition: isnet_client.c:436
int send_command_recv_ans(int sock, char *command, int tm, Buffer *key, EVP_CIPHER *cipher)
Definition: isnet_client.c:22
Buffer recv_mesg_until_end(int sock, int tm, Buffer *key, EVP_CIPHER *cipher)
Definition: isnet_client.c:77
#define JBXL_ARGS_ERROR
不正な引数(NULLなど)
Definition: jbxl_state.h:42
#define JBXL_ISNET_PUBKEYALG_ERROR
知らない公開鍵暗号アルゴリズム
Definition: jbxl_state.h:151
#define JBXL_ISNET_CONNECT_ERROR
認証サーバとの接続エラー
Definition: jbxl_state.h:154
#define JBXL_ISNET_SERVER_ERROR
認証ホストの検証エラー
Definition: jbxl_state.h:150
#define JBXL_ISNET_NULLANS_ERROR
サーバからの返答が NULL
Definition: jbxl_state.h:153
#define JBXL_ISNET_CMD_ERROR
サーバから 'OK', 'ERR' 以外のものを受信した
Definition: jbxl_state.h:147
#define JBXL_ISNET_START_ERROR
認証サーバとの通信開始エラー(相手は認証サーバでない?)
Definition: jbxl_state.h:155
#define JBXL_ISNET_PASSWD_ERROR
ユーザ認証失敗(ユーザは存在するが,パスワードが一致しない)
Definition: jbxl_state.h:149
#define JBXL_ISNET_DHKEY_ERROR
DH鍵エラー(ISNET内)
Definition: jbxl_state.h:159
#define JBXL_ISNET_USER_ERROR
ユーザ認証失敗(ユーザが存在しない)
Definition: jbxl_state.h:148
#define JBXL_ISNET_CHALLENGE_ERROR
チャレンジキー合意エラー
Definition: jbxl_state.h:157
unsigned char ** buf
Definition: jpeg_tool.h:96
int socket_close(int sofd)
call shutdown(), close()
Definition: network.c:1022
char * get_ipaddr_byname(const char *hostname, int family)
ホスト名 → IPv4/IPv6 アドレス(文字列)
Definition: network.c:1781
#define tcp_client_socket(h, p)
Definition: network.h:130
char * x2crypt(char *pass, char *bsalt)
Definition: password.c:194
int tcp_send_crypt_sBuffer(int sock, Buffer *mesg, Buffer *key, EVP_CIPHER *cipher)
Definition: ssl_tool.c:351
void free_EVP_CIPHER(EVP_CIPHER **p_cipher)
Definition: ssl_tool.c:773
int check_server_spki(Buffer ipaddr, Buffer spki, char *filename)
Definition: ssl_tool.c:524
EVP_CIPHER * init_EVPAPI_Buffer(int type)
Definition: ssl_tool.c:645
int gen_CRYPT_SharedKey(int keyex, Buffer spki, Buffer *shdkey, void *ptr)
Definition: ssl_tool.c:91
Buffer get_plain_sBuffer(Buffer mesg, Buffer *key, EVP_CIPHER *cipher)
Definition: ssl_tool.c:423
Definition: buffer.h:35
int state
変数の状態を表す.正常は JBXL_NORMAL
Definition: buffer.h:38
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
int strnrvscmp(const char *s1, const char *s2, int n)
文字列 s1と s2を後ろから n文字比較する.一致するなら 0
Definition: tools.c:674
#define freeNull(p)
Definition: tools.h:201
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475
#define DEBUG_MODE
Definition: tools.h:502
int tcp_recv_Buffer_wait(int sock, Buffer *str, int tm)
TCP経由でデータを受信する.待ち時間(タイムアウト)を指定できる.
Definition: xtools.c:370