/* * Called with the server locked. */ void smb_close_socket(struct smb_sb_info *server) { struct file * file = server->sock_file; if (file) { #ifdef SMBFS_DEBUG_VERBOSE printk("smb_close_socket: closing socket %p\n", server_sock(server)); #endif #ifdef SMBFS_PARANOIA if (server_sock(server)->sk->data_ready == smb_data_callback) printk("smb_close_socket: still catching keepalives!\n"); #endif server->sock_file = NULL; fput(file); } }
/** * test_server_loop() 関数テスト * * @return なし */ void test_server_loop(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ int count = 1; /* ループカウント */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); count = 2; g_sig_handled = 1; while (count--) server_loop(ssock); exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); } }
int smb_dont_catch_keepalive(struct smb_sb_info *server) { struct socket *socket; struct sock *sk; void * data_ready; int error; error = -EINVAL; socket = server_sock(server); if (!socket) { printk(KERN_DEBUG "smb_dont_catch_keepalive: did not get valid server!\n"); goto out; } sk = socket->sk; if (sk == NULL) { printk(KERN_DEBUG "smb_dont_catch_keepalive: sk == NULL"); goto out; } /* Is this really an error?? */ if (server->data_ready == NULL) { printk(KERN_DEBUG "smb_dont_catch_keepalive: " "server->data_ready == NULL\n"); goto out; } DEBUG1("sk->d_r = %x, server->d_r = %x\n", (unsigned int) (sk->data_ready), (unsigned int) (server->data_ready)); /* * Restore the original callback atomically to avoid races ... */ data_ready = xchg(&sk->data_ready, server->data_ready); server->data_ready = NULL; if (data_ready != smb_data_ready) { printk(KERN_ERR "smb_dont_catch_keepalive: " "sk->data_ready != smb_data_ready\n"); } error = 0; out: return error; }
/* * smb_receive * fs points to the correct segment */ static int smb_receive(struct smb_sb_info *server) { struct socket *socket = server_sock(server); unsigned char * packet = server->packet; int len, result; unsigned char peek_buf[4]; result = smb_get_length(socket, peek_buf); if (result < 0) goto out; len = result; /* * Some servers do not respect our max_xmit and send * larger packets. Try to allocate a new packet, * but don't free the old one unless we succeed. */ if (len + 4 > server->packet_size) { int new_len = smb_round_length(len + 4); result = -ENOMEM; packet = smb_vmalloc(new_len); if (packet == NULL) goto out; smb_vfree(server->packet); server->packet = packet; server->packet_size = new_len; } memcpy(packet, peek_buf, 4); result = smb_receive_raw(socket, packet + 4, len); if (result < 0) { #ifdef SMBFS_DEBUG_VERBOSE printk("smb_receive: receive error: %d\n", result); #endif goto out; } server->rcls = *(packet + smb_rcls); server->err = WVAL(packet, smb_err); #ifdef SMBFS_DEBUG_VERBOSE if (server->rcls != 0) printk("smb_receive: rcls=%d, err=%d\n", server->rcls, server->err); #endif out: return result; }
/** * test_server_sock() 関数テスト * * @return なし */ void test_server_sock(void) { dbglog("start"); if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); dbglog("server_sock=%d", ssock); cut_assert_not_equal_int(EX_NG, ssock); csock = inet_sock_client(); if (csock < 0) cut_error("inet_sock_client"); }
int main() { std::cout << "서버 초기화 시작" << std::endl; Poco::Net::SocketAddress server_add(PORT); Poco::Net::ServerSocket server_sock(server_add); std::cout << "서버 초기화 완료. 클라이언트 접속 대기 중..." << std::endl; while (true) { Poco::Net::StreamSocket ss = server_sock.acceptConnection(); try { char buffer[256] = { 0, }; int n = ss.receiveBytes(buffer, sizeof(buffer)); std::cout << "클라이언트에서 받은 메시지: " << buffer << std::endl; while (n > 0) { char szSendMessage[256] = { 0, }; sprintf_s(szSendMessage, 128 - 1, "Re:%s", buffer); int nMsgLen = strnlen_s(szSendMessage, 256 - 1); ss.sendBytes(szSendMessage, nMsgLen); n = ss.receiveBytes(buffer, sizeof(buffer)); std::cout << "클라이언트에서 받은 메시지: " << buffer << std::endl; } std::cout << "클라이언트와 연결이 끊어졌습니다" << std::endl; } catch (Poco::Exception& exc) { std::cerr << "EchoServer: " << exc.displayText() << std::endl; } } getchar(); return 0; }
int smb_catch_keepalive(struct smb_sb_info *server) { struct socket *socket; struct sock *sk; void *data_ready; int error; error = -EINVAL; socket = server_sock(server); if (!socket) { printk(KERN_DEBUG "smb_catch_keepalive: did not get valid server!\n"); server->data_ready = NULL; goto out; } sk = socket->sk; if (sk == NULL) { DEBUG1("sk == NULL"); server->data_ready = NULL; goto out; } DEBUG1("sk->d_r = %x, server->d_r = %x\n", (unsigned int) (sk->data_ready), (unsigned int) (server->data_ready)); /* * Install the callback atomically to avoid races ... */ data_ready = xchg(&sk->data_ready, smb_data_ready); if (data_ready != smb_data_ready) { server->data_ready = data_ready; error = 0; } else printk(KERN_ERR "smb_catch_keepalive: already done\n"); out: return error; }
/** * test_server_proc() 関数テスト * * @return なし */ void test_server_proc(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ thread_data *dt = NULL; /* ソケット情報構造体 */ void *servret = NULL; /* テスト関数戻り値 */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); dt = (thread_data *)malloc(sizeof(thread_data)); if (!dt) { outlog("malloc: size=%zu", sizeof(thread_data)); exit(EXIT_FAILURE); } (void)memset(dt, 0, sizeof(thread_data)); dt->len = (socklen_t)sizeof(dt->addr); dt->sock = accept(ssock, (struct sockaddr *)&dt->addr, &dt->len); if (dt->sock < 0) { outlog("accept: ssock=%d", ssock); memfree((void **)&dt, NULL); exit(EXIT_FAILURE); } g_sig_handled = 1; /* テスト関数実行 */ servret = server.server_proc(dt); if (servret) { outlog("server_proc"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) cut_error("child failed"); } }
static int smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command, int ldata, unsigned char *data, int lparam, unsigned char *param) { struct socket *sock = server_sock(server); struct scm_cookie scm; int err; /* I know the following is very ugly, but I want to build the smb packet as efficiently as possible. */ const int smb_parameters = 15; const int oparam = ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3); const int odata = ROUND_UP(oparam + lparam); const int bcc = odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2); const int packet_length = SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2; unsigned char padding[4] = {0,}; char *p; struct iovec iov[4]; struct msghdr msg; /* N.B. This test isn't valid! packet_size may be < max_xmit */ if ((bcc + oparam) > server->opt.max_xmit) { return -ENOMEM; } p = smb_setup_header(server, SMBtrans2, smb_parameters, bcc); WSET(server->packet, smb_tpscnt, lparam); WSET(server->packet, smb_tdscnt, ldata); /* N.B. these values should reflect out current packet size */ WSET(server->packet, smb_mprcnt, TRANS2_MAX_TRANSFER); WSET(server->packet, smb_mdrcnt, TRANS2_MAX_TRANSFER); WSET(server->packet, smb_msrcnt, 0); WSET(server->packet, smb_flags, 0); DSET(server->packet, smb_timeout, 0); WSET(server->packet, smb_pscnt, lparam); WSET(server->packet, smb_psoff, oparam - 4); WSET(server->packet, smb_dscnt, ldata); WSET(server->packet, smb_dsoff, odata - 4); WSET(server->packet, smb_suwcnt, 1); WSET(server->packet, smb_setup0, trans2_command); *p++ = 0; /* null smb_name for trans2 */ *p++ = 'D'; /* this was added because OS/2 does it */ *p++ = ' '; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_iov = iov; msg.msg_iovlen = 4; msg.msg_flags = 0; iov[0].iov_base = (void *) server->packet; iov[0].iov_len = oparam; iov[1].iov_base = (param == NULL) ? padding : param; iov[1].iov_len = lparam; iov[2].iov_base = padding; iov[2].iov_len = odata - oparam - lparam; iov[3].iov_base = (data == NULL) ? padding : data; iov[3].iov_len = ldata; err = scm_send(sock, &msg, &scm); if (err >= 0) { err = sock->ops->sendmsg(sock, &msg, packet_length, &scm); scm_destroy(&scm); } return err; }
/* * Called with the server locked */ int smb_request(struct smb_sb_info *server) { unsigned long flags, sigpipe; mm_segment_t fs; sigset_t old_set; int len, result; unsigned char *buffer; result = -EBADF; buffer = server->packet; if (!buffer) goto bad_no_packet; result = -EIO; if (server->state != CONN_VALID) goto bad_no_conn; if ((result = smb_dont_catch_keepalive(server)) != 0) goto bad_conn; len = smb_len(buffer) + 4; DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]); spin_lock_irqsave(¤t->sigmask_lock, flags); sigpipe = sigismember(¤t->signal, SIGPIPE); old_set = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); fs = get_fs(); set_fs(get_ds()); result = smb_send_raw(server_sock(server), (void *) buffer, len); if (result > 0) { result = smb_receive(server); } /* read/write errors are handled by errno */ spin_lock_irqsave(¤t->sigmask_lock, flags); if (result == -EPIPE && !sigpipe) sigdelset(¤t->signal, SIGPIPE); current->blocked = old_set; recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); set_fs(fs); if (result >= 0) { int result2 = smb_catch_keepalive(server); if (result2 < 0) { printk(KERN_ERR "smb_request: catch keepalive failed\n"); result = result2; } } if (result < 0) goto bad_conn; /* * Check for fatal server errors ... */ if (server->rcls) { int error = smb_errno(server); if (error == EBADSLT) { printk(KERN_ERR "smb_request: tree ID invalid\n"); result = error; goto bad_conn; } } out: DEBUG1("result = %d\n", result); return result; bad_conn: PARANOIA("result %d, setting invalid\n", result); server->state = CONN_INVALID; smb_invalidate_inodes(server); goto out; bad_no_packet: printk(KERN_ERR "smb_request: no packet!\n"); goto out; bad_no_conn: printk(KERN_ERR "smb_request: connection %d not valid!\n", server->state); goto out; }
/*-------------------------------------------------------------------- echo_server() ------------------------------------------------------------------*/ void echo_server () { int ssock, csock, more, nread, nwritten, status; unsigned char i; pid_t pid; char ibuf[64], obuf[64], *p; struct sockaddr_in sin; socklen_t slen = sizeof( sin ); int hostlen=1024; char *host=(char *)malloc( hostlen*sizeof( char )); /* creates server socket */ ssock = server_sock(); gethostname( host,hostlen ); printf( "host: [%s]\n",host ); /*printf( "port: %d\n", ntohs( get_port( ssock )));*/ printf( "port --> for non-linux=[%d] or for linux=[%d]\n", ntohs( get_port( ssock )),get_port( ssock )); /* accept returns a socket descriptor for the accepted socket */ if (( csock = accept( ssock, (struct sockaddr *)&sin, &slen )) == -1 ) { sysabort( "server/accept" ); } fprintf( stdout,"server: socket created/listen/accepted\n" ); fflush( stdout ); /* loop while reading on the socket... */ more = 1; while ( more ) { if (( nread = read( csock, &i, sizeof(i))) < 0 ) { sysabort( "server/read" ); } else { fprintf( stdout,"server: i=%d\n",i ); fflush( stdout ); if (( nread = read( csock, ibuf, i )) < 0 ) { sysabort( "server/read" ); } ibuf[nread] = '\0'; if ( ibuf[0] == TERM ) { more = 0; } else { fprintf( stdout,"server: read message [%s]\n",ibuf ); fflush( stdout ); /* now do output... */ strcpy( obuf,"okay" ); p = obuf; i = strlen( obuf ); fprintf( stdout,"server: writing message [%s]\n",p ); fflush( stdout ); if (( nwritten = write( csock, &i, sizeof(i) )) == -1 ) { sysabort( "server/write" ); } if (( nwritten = write( csock, p, strlen(p) )) == -1 ) { sysabort( "server/write" ); } } } } /* end while more */ /* close socket connection */ close( csock ); } /* end of echo_server() */
void test_ssl() { interface ifs[16]; active_interfaces(ifs, 16); char *passwd = "password"; char *dir = chdir_temp_dir(); kdfp kdfp = { .N = 2, .r = 1, .p = 1}; uint8_t kek[KEY_LEN] = { 0 }; struct server_cfg cfg = { .passwd = passwd, .cert = "server.pem", .ifa = &ifs[0], }; pthread_t tid; EC_GROUP *group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(EC_CURVE_NAME)); EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); init_certs(group, passwd, "server.pem", "client.pem"); init_certs(group, passwd, "zerver.pem", "zlient.pem"); init_index("index", kek, &kdfp); EC_GROUP_free(group); assert(pthread_create(&tid, NULL, &run_server, &cfg) == 0); struct timeval timeout = { .tv_usec = 500 }; uint32_t usecs = 10000; sockaddr6 addr; X509 *cert = NULL, *sert = NULL; EVP_PKEY *pk = NULL, *sk = NULL; SSL_CTX *ctx = NULL; SSL *ssl = NULL; uint8_t data[KDFP_LEN]; // client/server cert & pk mismatch read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); read_pem("server.pem", NULL, passwd, &sk, 0); assert(client_ctx(sert, cert, sk) == NULL); assert(server_sock(&ctx, sert, pk, cfg.ifa, &addr) == -1); assert(ctx == NULL); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect signature on pong read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert); assert(find_server(sk, &addr, usecs, 30) == false); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect server certificate read_pem("server.pem", NULL, passwd, &sk, 1, &sert); assert(find_server(sk, &addr, usecs, 30) == true); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); X509_free(sert); read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert); ctx = client_ctx(sert, cert, pk); assert(client_socket(ctx, &addr, &timeout) == NULL); assert(ERR_GET_REASON(ERR_get_error()) == SSL_R_CERTIFICATE_VERIFY_FAILED); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect client certificate read_pem("zlient.pem", NULL, passwd, &pk, 1, &cert); read_pem("server.pem", NULL, passwd, &sk, 1, &sert); ctx = client_ctx(sert, cert, pk); assert(client_socket(ctx, &addr, &timeout) == NULL); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // valid certificates read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); read_pem("server.pem", NULL, passwd, &sk, 0); ctx = client_ctx(sert, cert, pk); assert((ssl = client_socket(ctx, &addr, &timeout))); assert(SSL_read(ssl, &data, KDFP_LEN) == KDFP_LEN); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); pthread_kill(tid, SIGINT); pthread_join(tid, NULL); unlink("server.pem"); unlink("client.pem"); unlink("zerver.pem"); unlink("zlient.pem"); unlink("index"); rmdir_temp_dir(dir); }