Introduction to Information Security - Cs Team Site | courses.cs.tau.ac.il

Download Report

Transcript Introduction to Information Security - Cs Team Site | courses.cs.tau.ac.il

Introduction to
Information
Security
Networking
Transmission Control
Protocol (aka TCP)
• Most widely used protocol
• A TCP Connection is based on 6 crucial parmeters:
o
o
o
o
o
o
Source IP
Destination IP
Source port
Destination port
Source byte counter
Destination byte counter
TCP/IP Continued
• In order to establish a tcp connection a 3-way
handshake occurs.
• Once the handshake is established and the
connection is up and running tcp ensures:
o Delivery of _all_ packets
o Delivery of in order
o Delivery with no errors.
Server implementation
• The server listens on a specific port (aka the
destination port)
• Once a connection is established, the server can
accept more connections while handling the first
connection.
• Establish multi processing of connections can be
gained by:
o
o
o
o
Fork() – Multi process solution.
Multi-Threaded solutions.
Select() – Single process solutions
Other OS specific solutions.
Client implementation
• Usually handles only one connection at a time.
(extreme contrary example: uTorrent).
• Source port is randomized by operating system.
Network Programming
• Most popular guide ever released for network
programming is beej’s guide which is a very good
starter reference
o http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html
Server implementation in C
(taken from beej) - includes
/*
** server.c - a stream socket server demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
C-Server Cleanup and
defines
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue
will hold
//Cleaning up dead child processes:
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
C-Server main
int main(void)
{
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector’s address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
C-Server continued
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
== -1) {
C-Server continued
{
}
while(1) { // main accept() loop
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
perror("accept");
continue;
}
return 0;
}
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd); // parent doesn't need this
C-Client - includes
/*
** client.c - a stream socket client demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 3490 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
C-Client main
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr; // connector's address information
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
C-Client main continued
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
-1) {
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) ==
perror("connect");
exit(1);
}
if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
}
buf[numbytes] = '\0';
printf("Received: %s",buf);
close(sockfd);
return 0;
Python client
#!usr/bin/python
from socket import *
PORT = 3490
def main():
sock = socket(AF_INET, SOCK_STREAM)
sock.connect(("127.0.0.1", PORT))
res = sock.recv(1000) # 1000 = Maximum number of bytes to
# receive, however, it may return with less bytes
# than expected
print res
sock.close()
if __name__ == '__main__':
main()
Python server example
#!usr/bin/python
from socket import *
PORT = 3490
def main():
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("0.0.0.0", PORT))
sock.listen(10) # set backlog
while 1:
(clisock, addr) = sock.accept()
print "Got incoming connection..."
res = clisock.send("Hello, World!")
clisock.close()
sock.close()
if __name__ == '__main__':
main()
File descriptors
• Serially assigned to process and can be shared
between processes.
• Reference based (file closes when the last
descriptor closes)
• Popular descriptors:
o
o
o
o
0 – stdin
1 – stdout
2 – stderr
3 – graphics
• Can be dup()licated using dup() and dup2()
dup2()
• Using dup2() can be used to easily connect
processes inputs and outputs to an existing TCP
connection!
• Assuming sockfd is an already created and
connected file descriptor we run:
dup2(sockfd, 0); // dup standard input
dup2(sockfd,1); // dup standard output
dup2(sockfd,2); // dup standard error output
• Now we can run:
execv(“someprocess”, NULL)