int start_server(const char *url, const char *rtspport) { int mediafd = -1, listenfd, tempfd, maxfd; int videofd; struct addrinfo *info; struct sockaddr_storage remoteaddr; socklen_t addrlen = sizeof remoteaddr; fd_set readfds, masterfds; int nready, i; int videosize, videoleft; int recvd, sent; char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE]; unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE]; char *temp; RTSPMsg rtspmsg; Client streamclient; /* The current state of the protocol */ int mediastate = IDLE; int quit = 0; init_client(&streamclient); /* Open the a file where the video is to be stored */ if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { fatal_error("Error opening the temporary videofile"); } /* Create the RTSP listening socket */ resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info); listenfd = server_socket(info); maxfd = listenfd; FD_ZERO(&readfds); FD_ZERO(&masterfds); FD_SET(listenfd, &masterfds); while (!quit) { readfds = masterfds; if ((nready = Select(maxfd + 1, &readfds, NULL)) == -1) { write_log(logfd, "Select interrupted by a signal\n"); } for (i = 0; i <= maxfd; i++) { if (FD_ISSET(i, &readfds)) { nready--; /* New connection from a client */ if (i == listenfd) { if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) { if (errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) { fatal_error("accept"); } } /* If we are already serving a client, close the new connection. Otherwise, continue. */ if (streamclient.state != NOCLIENT) close (tempfd); else { streamclient.rtspfd = tempfd; streamclient.state = CLICONNECTED; maxfd = max(2, streamclient.rtspfd, maxfd); FD_SET(streamclient.rtspfd, &masterfds); } } /* Data from the media source */ else if (i == mediafd) { switch (mediastate) { case GETSENT: /* Read ONLY the HTTP message from the socket and store the video size */ recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK); temp = strstr((char *)msgbuf, "\r\n\r\n"); recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0); temp = strstr((char *)msgbuf, "Content-Length:"); sscanf(temp, "Content-Length: %d", &videosize); videoleft = videosize; mediastate = RECVTCP; break; case RECVTCP: if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); printf("Socket closed\n"); } writestr(videofd, msgbuf, recvd); videoleft -= recvd; if (videoleft <= 0) mediastate = STREAM; break; /* TODO: Start streaming, currently just exits the program */ case STREAM: /* close(videofd); close(mediafd); close(listenfd); quit = 1; */ break; default: break; } } /* Data from a client ( i == streamclient.rtspfd) */ else { if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); printf("Socket closed\n"); streamclient.state = NOCLIENT; } else { printf("%s", msgbuf); parse_rtsp(&rtspmsg, msgbuf); } switch (streamclient.state) { case CLICONNECTED: if (rtspmsg.type == OPTIONS) { sent = rtsp_options(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); } else if (rtspmsg.type == DESCRIBE) { /* Start fetching the file from the server */ parse_url(url, urlhost, urlpath); resolve_host(urlhost, "80", SOCK_STREAM, 0, &info); mediafd = client_socket(info, 0); FD_SET(mediafd, &masterfds); maxfd = max(2, maxfd, mediafd); /* Send the GET message */ http_get(url, msgbuf); send_all(mediafd, msgbuf, strlen((char *)msgbuf)); mediastate = GETSENT; /* TODO: parse SDP from the media file rather than hardcoding it */ sent = rtsp_describe(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); streamclient.state = SDPSENT; } break; case SDPSENT: if (rtspmsg.type == SETUP) { sent = rtsp_setup(&rtspmsg, sendbuf, 50508, 50509); send_all(i, sendbuf, sent); write_remote_ip(tempstr, streamclient.rtspfd); resolve_host(tempstr, rtspmsg.clirtpport, 0, SOCK_DGRAM, &info); streamclient.videofds[0] = client_socket(info, 50508); resolve_host(tempstr, rtspmsg.clirtcpport, 0, SOCK_DGRAM, &info); streamclient.videofds[1] = client_socket(info, 50509); streamclient.state = SETUPSENT; } break; case SETUPSENT: if (rtspmsg.type == PLAY) { } break; default: break; } } } if (nready <= 0) break; } } return 1; }
Buffer* http_query(char *host, char *page, int port) { int client_fd; Buffer *buffer; char *request; char strbuf[DL_SIZE]; int sz; // prepare http request header request = (char *) malloc(strlen(HTTP_REQ_GET) + strlen(page) + strlen(host) + 1); sprintf(request, HTTP_REQ_GET, page, host); // open connection to remote server client_fd = client_socket(host, port); // send http request to remote server if ((sz = write(client_fd, request, strlen(request))) < 0) { perror("write"); fprintf(stderr, "Error: Failed to send http request to http://%s%s\n", host, page); exit(2); } // free http request free(request); // receive http response buffer = (Buffer *) calloc(1, sizeof(Buffer)); // allocate memory and fill with zeros memset(strbuf, 0, DL_SIZE); // read from socket while ((sz = read(client_fd, strbuf, DL_SIZE)) != 0) { if (sz < 0) { perror("read"); fprintf(stderr, "Error: Failed to fetch http response from http://%s%s\n", host, page); exit(1); } else { // use realloc to increase size for variable length data // why use length+sz+1? because valgrind will complain about there is no space left for buffer->data buffer->data = realloc(buffer->data, buffer->length + sz + 1); // copy downloaded data from buffer to data with actual download size memcpy(buffer->data + buffer->length, strbuf, sz); // increase the recorded data size buffer->length += sz; } memset(strbuf, 0, DL_SIZE); } close(client_fd); // If the server return nothing, we will not create the object if (buffer->length == 0) { free(buffer); return NULL; } return buffer; }
static int do_connect(int *out, char const *file, char const *server) { int sockfd; ssize_t r; fr_channel_type_t channel; char buffer[65536]; uint32_t magic; /* * Close stale file descriptors */ if (*out != -1) { close(*out); *out = -1; } if (file) { /* * FIXME: Get destination from command line, if possible? */ sockfd = fr_socket_client_unix(file, false); if (sockfd < 0) { fr_perror("radmin"); if (errno == ENOENT) { fprintf(stderr, "Perhaps you need to run the commands:"); fprintf(stderr, "\tcd /etc/raddb\n"); fprintf(stderr, "\tln -s sites-available/control-socket " "sites-enabled/control-socket\n"); fprintf(stderr, "and then re-start the server?\n"); } return -1; } } else { sockfd = client_socket(server); } /* * Only works for BSD, but Linux allows us * to mask SIGPIPE, so that's fine. */ #ifdef SO_NOSIGPIPE { int set = 1; setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); } #endif /* * Set up the initial header data. */ magic = 0xf7eead16; magic = htonl(magic); memcpy(buffer, &magic, sizeof(magic)); memset(buffer + sizeof(magic), 0, sizeof(magic)); r = fr_channel_write(sockfd, FR_CHANNEL_INIT_ACK, buffer, 8); if (r <= 0) { do_close: fprintf(stderr, "%s: Error in socket: %s\n", progname, fr_syserror(errno)); close(sockfd); return -1; } r = fr_channel_read(sockfd, &channel, buffer + 8, 8); if (r <= 0) goto do_close; if ((r != 8) || (channel != FR_CHANNEL_INIT_ACK) || (memcmp(buffer, buffer + 8, 8) != 0)) { fprintf(stderr, "%s: Incompatible versions\n", progname); close(sockfd); return -1; } if (server && secret) { r = do_challenge(sockfd); if (r <= 0) goto do_close; } *out = sockfd; return 0; }
bool loop() { const char msg[10] = ""; // // Ping out role. Repeatedly send the current time // if (role == role_ping_out) { // First, stop listening so we can talk. radio.stopListening(); // Take the time, and send it. This will block until complete // unsigned long time = __millis(); // char msg[9] = "lamp1_on"; // printf("Now sending %s...",msg); bool ok = radio.write( msg, 10 ); if (ok) printf("ok..."); else printf("failed.\n\r"); // Now, continue listening radio.startListening(); // Wait here until we get a response, or timeout (250ms) unsigned long started_waiting_at = __millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) { // by bcatalin » Thu Feb 14, 2013 11:26 am __msleep(5); //add a small delay to let radio.available to check payload if (__millis() - started_waiting_at > 200 ) timeout = true; } // Describe the results if ( timeout ) { printf("Failed, response timed out.\n\r"); return false; } else { // Grab the response, compare, and send to debugging spew char got[10]; radio.read( &got, 10 ); // Spew it printf("Got response %s\n",got); return true; } // Try again 1s later // delay(1000); //sleep(1); } // // Pong back role. Receive each packet, dump it out, and send it back // if ( role == role_pong_back ) { // if there is data ready if ( radio.available() ) { // Dump the payloads until we've gotten everything unsigned long got_time = 0; bool done = false; while (!done) { // Fetch the payload, and see if this was the last one. // done = radio.read( &got_time, sizeof(unsigned long) ); float celsius; // done = radio.read( &celsius, sizeof(float)); char tempC[100]; char len[2]; std::string recievedStr; // int i = 0; // while(i<16) // { // done = radio.read( &len, 2); // cout << len << endl; // i++; // } // printf("Payload length: %s... ",len); int payloadSize = radio.getPayloadSize(); // printf("Payload size: %d", payloadSize); done = radio.read( &tempC, payloadSize); cout << "Received from radio: " << tempC << endl; // Spew it printf("Got payload %s... ",tempC); stringstream ss; string received; ss << tempC; ss >> received; // char mark[] = "mark,a,b"; char *test[sizeof(strtok(tempC, ","))]; test[0] = strtok(tempC, ","); for(int i = 1; i < sizeof(strtok(tempC, ",")); i++) { test[i] = strtok (NULL, ","); // printf ("%s\n",test[i]); // Writes "is" } cout << "App:" << test[0] << "append" << strcmp(test[0],"temp") << endl; if(strcmp(test[0],"temp") == 0) { printf("Got data from temperature sensor, sending to temp server\n"); try { ClientSocket client_socket ( "localhost", 5656 ); std::string reply; try { cout << "received: " << received << endl; client_socket << received; client_socket >> reply; } catch ( SocketException& ) {} std::cout << "We received this response from the server:\n\"" << reply << "\"\n";; } catch ( SocketException& e ) { std::cout << "Exception was caught:" << e.description() << "\n"; } } // Delay just a little bit to let the other unit // make the transition to receiver delay(20); } // First, stop listening so we can talk radio.stopListening(); // Send the final one back. printf("Sent response.\n\r"); radio.write( &got_time, sizeof(unsigned long) ); // Now, resume listening so we catch the next packets. radio.startListening(); }
int start_server(const char *url, const char *rtspport) { int mediafd = -1, listenfd, tempfd, maxfd; int videofd; struct addrinfo *info; struct sockaddr_storage remoteaddr; socklen_t addrlen = sizeof remoteaddr; fd_set readfds, masterfds; struct timeval *timeout, *timeind = NULL, timenow; int nready, i; int videosize, videoleft; int recvd, sent; char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE]; unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE]; char *temp; unsigned char *sps = NULL, *pps = NULL; size_t spslen, ppslen; RTSPMsg rtspmsg; Client streamclient; pthread_t threadid; ThreadInfo *tinfo = NULL; uint16_t rtpseqno_video = (rand() % 1000000); uint16_t rtpseqno_audio = (rand() % 1000000); TimeoutEvent *event; /* The current state of the protocol */ int mediastate = IDLE; int quit = 0; int media_downloaded = 0; timeout = (struct timeval *)malloc(sizeof(struct timeval)); init_client(&streamclient); /* Open the a file where the video is to be stored */ if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { fatal_error("Error opening the temporary videofile"); } /* Create the RTSP listening socket */ resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info); listenfd = server_socket(info); maxfd = listenfd; FD_ZERO(&readfds); FD_ZERO(&masterfds); FD_SET(listenfd, &masterfds); while (!quit) { readfds = masterfds; if ((nready = Select(maxfd + 1, &readfds, timeind)) == -1) { printf("Select interrupted by a signal\n"); } /* Timeout handling, used for packet pacing and other timeouts */ else if (nready == 0) { timeind = NULL; lock_mutex(&queuelock); if ((event = pull_event(&queue)) != NULL) { switch (event->type) { case ENDOFSTREAM: printf("MEDIA FINISHED\n"); break; case FRAME: /* Video frame */ if (event->frame->frametype == VIDEO_FRAME) { rtpseqno_video += send_video_frame(sendbuf, event->frame, streamclient.videofds[0], rtpseqno_video); } /* Audio frame */ else { rtpseqno_audio += send_audio_frame(sendbuf, event->frame, streamclient.audiofds[0], rtpseqno_audio); } free(event->frame->data); free(event->frame); break; case CHECKMEDIASTATE: oma_debug_print("Checking media ready for streaming...\n"); if (mediastate != STREAM) { printf("Sending dummy RTP\n"); send_dummy_rtp(sendbuf, streamclient.videofds[0], &rtpseqno_video); push_timeout(&queue, 1000, CHECKMEDIASTATE); } break; default: oma_debug_print("ERRORENOUS EVENT TYPE!\n"); break; } /* If there are elements left in the queue, calculate next timeout */ if (queue.size > 0) { *timeout = calculate_delta(&event->time, &queue.first->time); timeind = timeout; oma_debug_print("Timeout: %ld secs, %ld usecs\n", timeout->tv_sec, timeout->tv_usec); } else { oma_debug_print("The first entry of the queue is NULL!\n"); } if (queue.size < QUEUESIZE / 2) { oma_debug_print("Signaling thread to start filling the queue"); pthread_cond_signal(&queuecond); } free(event); } unlock_mutex(&queuelock); continue; } /* End of timeout handling */ /* Start to loop through the file descriptors */ for (i = 0; i <= maxfd; i++) { if (FD_ISSET(i, &readfds)) { nready--; /* New connection from a client */ if (i == listenfd) { oma_debug_print("Recieved a new RTSP connection\n"); fflush(stdout); if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) { if (errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) { fatal_error("accept"); } } /* If we are already serving a client, close the new connection. Otherwise, continue. */ if (streamclient.state != NOCLIENT) { printf("Another RTSP client tried to connect. Sorry, we can only serve one client at a time\n"); close (tempfd); } else { streamclient.rtspfd = tempfd; streamclient.state = CLICONNECTED; maxfd = max(2, streamclient.rtspfd, maxfd); FD_SET(streamclient.rtspfd, &masterfds); } } /* Data from the media source */ else if (i == mediafd) { switch (mediastate) { case GETSENT: /* Read ONLY the HTTP message from the socket and store the video size */ recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK); temp = strstr((char *)msgbuf, "\r\n\r\n"); recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0); printf("Received HTTP response\n%s\n", msgbuf); temp = strstr((char *)msgbuf, "Content-Length:"); sscanf(temp, "Content-Length: %d", &videosize); videoleft = videosize; mediastate = RECVTCP; break; case RECVTCP: if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); oma_debug_print("Socket closed\n"); } oma_debug_print("Received data from video source!\n"); writestr(videofd, msgbuf, recvd); videoleft -= recvd; if (videoleft <= 0) { printf("Video download complete.\n"); FD_CLR(mediafd, &masterfds); close(videofd); close(mediafd); media_downloaded = 1; printf("Media socket closed\n"); /* Create the context and the queue filler thread parameter struct */ tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo)); initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx, &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen); /* Launch the queue filler thread */ CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0); pthread_detach(threadid); /* Send the sprop-parameters before any other frames */ send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0), streamclient.videofds[0], rtpseqno_video++); send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0), streamclient.videofds[0], rtpseqno_video++); g_free(sps); g_free(pps); lock_mutex(&queuelock); push_timeout(&queue, 1000, CHECKMEDIASTATE); unlock_mutex(&queuelock); mediastate = STREAM; } break; case STREAM: /* close(videofd); close(mediafd); close(listenfd); quit = 1; */ break; default: break; } } /* Data from a client ( i == streamclient.rtspfd) */ else { oma_debug_print("Received data from rtspfd\n"); fflush(stdout); if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); oma_debug_print("RTSP client closed the connection\n"); streamclient.state = NOCLIENT; } else { oma_debug_print("%s", msgbuf); parse_rtsp(&rtspmsg, msgbuf); } if (rtspmsg.type == TEARDOWN) { /* Kill thread and empty queue */ lock_mutex(&queuelock); pthread_cancel(threadid); empty_queue(&queue); sleep(1); /* Reply with 200 OK */ sent = rtsp_teardown(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); FD_CLR(i, &masterfds); close(i); close(streamclient.videofds[0]); close(streamclient.videofds[1]); close(streamclient.audiofds[0]); close(streamclient.audiofds[1]); printf("Closing AVFormatContext\n"); close_context(tinfo->ctx); free(tinfo); rtpseqno_video = (rand() % 1000000) + 7; rtpseqno_audio = rtpseqno_video + 9; init_client(&streamclient); printf("Closing RTSP client sockets (RTP&RTCP)\n"); streamclient.state = NOCLIENT; unlock_mutex(&queuelock); pthread_cond_signal(&queuecond); } switch (streamclient.state) { case CLICONNECTED: if (rtspmsg.type == OPTIONS) { sent = rtsp_options(&rtspmsg, &streamclient, sendbuf); send_all(i, sendbuf, sent); } else if (rtspmsg.type == DESCRIBE) { if (media_downloaded == 0) { /* Start fetching the file from the server */ parse_url(url, urlhost, urlpath); resolve_host(urlhost, "80", SOCK_STREAM, 0, &info); mediafd = client_socket(info, 0); FD_SET(mediafd, &masterfds); maxfd = max(2, maxfd, mediafd); /* Send the GET message */ http_get(url, msgbuf); send_all(mediafd, msgbuf, strlen((char *)msgbuf)); mediastate = GETSENT; } else { mediastate = STREAM; } /* Send the SDP without sprop-parameter-sets, those are sent * later in-band */ streamclient.state = SDPSENT; sent = rtsp_describe(&streamclient, sendbuf); send_all(i, sendbuf, sent); } break; case SDPSENT: if (rtspmsg.type == SETUP) { streamclient.setupsreceived++; /* Open up the needed ports and bind them locally. The RTCP ports opened here * are not really used by this application. */ write_remote_ip(tempstr, streamclient.rtspfd); oma_debug_print("Remote IP: %s\n", tempstr); if (streamclient.setupsreceived < 2) { resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[0] = client_socket(info, streamclient.server_rtp_audio_port); resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_audio_port); sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf, streamclient.server_rtp_audio_port, streamclient.server_rtcp_audio_port); } else { resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); streamclient.videofds[0] = client_socket(info, streamclient.server_rtp_video_port); resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_video_port); sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf, streamclient.server_rtp_video_port, streamclient.server_rtcp_video_port); streamclient.state = SETUPCOMPLETE; } oma_debug_print("Sending setup response...\n"); send_all(i, sendbuf, sent); } break; case SETUPCOMPLETE: if (rtspmsg.type == PLAY) { /* Respond to the PLAY request, and start sending dummy RTP packets * to disable the client timeout */ sent = rtsp_play(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); if (media_downloaded == 0) { lock_mutex(&queuelock); push_timeout(&queue, 100, CHECKMEDIASTATE); unlock_mutex(&queuelock); } /* Media has already been once downloaded, initialize context and thread */ else { tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo)); initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx, &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen); /* Launch the queue filler thread */ CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0); pthread_detach(threadid); /* Send the sprop-parameters before any other frames */ send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0), streamclient.videofds[0], rtpseqno_video++); send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0), streamclient.videofds[0], rtpseqno_video++); g_free(sps); g_free(pps); /* Dummy timeouts to start queue/timeout mechanism */ push_timeout(&queue, 100, CHECKMEDIASTATE); push_timeout(&queue, 2000, CHECKMEDIASTATE); } } break; default: break; } } } if (nready <= 0) break; } /* Set the timeout value again, since select will mess it up */ lock_mutex(&queuelock); if (queue.size > 0) { CHECK((gettimeofday(&timenow, NULL)) == 0); *timeout = calculate_delta(&timenow, &queue.first->time); /* oma_debug_print("Delta sec: %ld, Delta usec: %ld\n", timeout->tv_sec, timeout->tv_usec); */ if (timeout->tv_sec < 0) { timeout->tv_sec = 0; timeout->tv_usec = 0; } timeind = timeout; } else timeind = NULL; unlock_mutex(&queuelock); } return 1; }
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); }
int32_t client_connect(bthid_server_p srv, int32_t fd) { bthid_session_p s; hid_device_p d; int32_t error; socklen_t len; assert(srv != NULL); assert(fd >= 0); s = session_by_fd(srv, fd); assert(s != NULL); d = get_hid_device(&s->bdaddr); assert(d != NULL); error = 0; len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { syslog(LOG_ERR, "Could not get socket error for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL), strerror(errno), errno); session_close(s); connect_in_progress = 0; return (-1); } if (error != 0) { syslog(LOG_ERR, "Could not connect to %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL), strerror(error), error); session_close(s); connect_in_progress = 0; return (0); } switch (s->state) { case W4CTRL: /* Control channel is open */ assert(s->ctrl == fd); assert(s->intr == -1); /* Open interrupt channel */ s->intr = client_socket(&s->bdaddr, d->interrupt_psm); if (s->intr < 0) { syslog(LOG_ERR, "Could not open interrupt channel " \ "to %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL), strerror(errno), errno); session_close(s); connect_in_progress = 0; return (-1); } s->state = W4INTR; FD_SET(s->intr, &srv->wfdset); if (s->intr > srv->maxfd) srv->maxfd = s->intr; d->new_device = 0; /* reset new device flag */ write_hids_file(); break; case W4INTR: /* Interrupt channel is open */ assert(s->ctrl != -1); assert(s->intr == fd); s->state = OPEN; connect_in_progress = 0; /* Register session's vkbd descriptor (if any) for read */ if (s->state == OPEN && d->keyboard) { assert(s->vkbd != -1); FD_SET(s->vkbd, &srv->rfdset); if (s->vkbd > srv->maxfd) srv->maxfd = s->vkbd; } break; default: assert(0); break; } /* Move fd to from the write fd set into read fd set */ FD_CLR(fd, &srv->wfdset); FD_SET(fd, &srv->rfdset); return (0); }
int main(int argc, char **argv) { int argval; bool quiet = false; bool done_license = false; int sockfd; uint32_t magic, needed; char *line = NULL; ssize_t len, size; char const *file = NULL; char const *name = "radiusd"; char *p, buffer[65536]; char const *input_file = NULL; FILE *inputfp = stdin; char const *output_file = NULL; char const *server = NULL; char const *radius_dir = RADIUS_DIR; char const *dict_dir = DICTDIR; char *commands[MAX_COMMANDS]; int num_commands = -1; #ifndef NDEBUG if (fr_fault_setup(getenv("PANIC_ACTION"), argv[0]) < 0) { fr_perror("radmin"); exit(EXIT_FAILURE); } #endif talloc_set_log_stderr(); outputfp = stdout; /* stdout is not a constant value... */ if ((progname = strrchr(argv[0], FR_DIR_SEP)) == NULL) { progname = argv[0]; } else { progname++; } while ((argval = getopt(argc, argv, "d:D:hi:e:Ef:n:o:qs:S")) != EOF) { switch(argval) { case 'd': if (file) { fprintf(stderr, "%s: -d and -f cannot be used together.\n", progname); exit(1); } if (server) { fprintf(stderr, "%s: -d and -s cannot be used together.\n", progname); exit(1); } radius_dir = optarg; break; case 'D': dict_dir = optarg; break; case 'e': num_commands++; /* starts at -1 */ if (num_commands >= MAX_COMMANDS) { fprintf(stderr, "%s: Too many '-e'\n", progname); exit(1); } commands[num_commands] = optarg; break; case 'E': echo = true; break; case 'f': radius_dir = NULL; file = optarg; break; default: case 'h': usage(0); break; case 'i': if (strcmp(optarg, "-") != 0) { input_file = optarg; } quiet = true; break; case 'n': name = optarg; break; case 'o': if (strcmp(optarg, "-") != 0) { output_file = optarg; } quiet = true; break; case 'q': quiet = true; break; case 's': if (file) { fprintf(stderr, "%s: -s and -f cannot be used together.\n", progname); usage(1); } radius_dir = NULL; server = optarg; break; case 'S': secret = NULL; break; } } /* * Mismatch between the binary and the libraries it depends on */ if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) { fr_perror("radmin"); exit(1); } if (radius_dir) { int rcode; CONF_SECTION *cs, *subcs; file = NULL; /* MUST read it from the conffile now */ snprintf(buffer, sizeof(buffer), "%s/%s.conf", radius_dir, name); /* * Need to read in the dictionaries, else we may get * validation errors when we try and parse the config. */ if (dict_init(dict_dir, RADIUS_DICTIONARY) < 0) { fr_perror("radmin"); exit(64); } if (dict_read(radius_dir, RADIUS_DICTIONARY) == -1) { fr_perror("radmin"); exit(64); } cs = cf_file_read(buffer); if (!cs) { fprintf(stderr, "%s: Errors reading or parsing %s\n", progname, buffer); usage(1); } subcs = NULL; while ((subcs = cf_subsection_find_next(cs, subcs, "listen")) != NULL) { char const *value; CONF_PAIR *cp = cf_pair_find(subcs, "type"); if (!cp) continue; value = cf_pair_value(cp); if (!value) continue; if (strcmp(value, "control") != 0) continue; /* * Now find the socket name (sigh) */ rcode = cf_item_parse(subcs, "socket", FR_ITEM_POINTER(PW_TYPE_STRING, &file), NULL); if (rcode < 0) { fprintf(stderr, "%s: Failed parsing listen section\n", progname); exit(1); } if (!file) { fprintf(stderr, "%s: No path given for socket\n", progname); usage(1); } break; } if (!file) { fprintf(stderr, "%s: Could not find control socket in %s\n", progname, buffer); exit(1); } } if (input_file) { inputfp = fopen(input_file, "r"); if (!inputfp) { fprintf(stderr, "%s: Failed opening %s: %s\n", progname, input_file, strerror(errno)); exit(1); } } if (output_file) { outputfp = fopen(output_file, "w"); if (!outputfp) { fprintf(stderr, "%s: Failed creating %s: %s\n", progname, output_file, strerror(errno)); exit(1); } } if (!file && !server) { fprintf(stderr, "%s: Must use one of '-d' or '-f' or '-s'\n", progname); exit(1); } /* * Check if stdin is a TTY only if input is from stdin */ if (input_file && !quiet && !isatty(STDIN_FILENO)) quiet = true; #ifdef USE_READLINE if (!quiet) { #ifdef USE_READLINE_HISTORY using_history(); #endif rl_bind_key('\t', rl_insert); } #endif reconnect: if (file) { /* * FIXME: Get destination from command line, if possible? */ sockfd = fr_domain_socket(file); if (sockfd < 0) { exit(1); } } else { sockfd = client_socket(server); } /* * Read initial magic && version information. */ for (size = 0; size < 8; size += len) { len = read(sockfd, buffer + size, 8 - size); if (len < 0) { fprintf(stderr, "%s: Error reading initial data from socket: %s\n", progname, strerror(errno)); exit(1); } } memcpy(&magic, buffer, 4); magic = ntohl(magic); if (magic != 0xf7eead15) { fprintf(stderr, "%s: Socket %s is not FreeRADIUS administration socket\n", progname, file); exit(1); } memcpy(&magic, buffer + 4, 4); magic = ntohl(magic); if (!server) { needed = 1; } else { needed = 2; } if (magic != needed) { fprintf(stderr, "%s: Socket version mismatch: Need %d, got %d\n", progname, needed, magic); exit(1); } if (server && secret) do_challenge(sockfd); /* * Run one command. */ if (num_commands >= 0) { int i; for (i = 0; i <= num_commands; i++) { size = run_command(sockfd, commands[i], buffer, sizeof(buffer)); if (size < 0) exit(1); if (buffer[0]) { fputs(buffer, outputfp); fprintf(outputfp, "\n"); fflush(outputfp); } } exit(0); } if (!done_license && !quiet) { printf("%s - FreeRADIUS Server administration tool.\n", radmin_version); printf("Copyright (C) 2008-2014 The FreeRADIUS server project and contributors.\n"); printf("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"); printf("PARTICULAR PURPOSE.\n"); printf("You may redistribute copies of FreeRADIUS under the terms of the\n"); printf("GNU General Public License v2.\n"); done_license = true; } /* * FIXME: Do login? */ while (1) { #ifndef USE_READLINE if (!quiet) { printf("radmin> "); fflush(stdout); } #else if (!quiet) { line = readline("radmin> "); if (!line) break; if (!*line) { free(line); continue; } #ifdef USE_READLINE_HISTORY add_history(line); #endif } else /* quiet, or no readline */ #endif { line = fgets(buffer, sizeof(buffer), inputfp); if (!line) break; p = strchr(buffer, '\n'); if (!p) { fprintf(stderr, "%s: Input line too long\n", progname); exit(1); } *p = '\0'; /* * Strip off leading spaces. */ for (p = line; *p != '\0'; p++) { if ((p[0] == ' ') || (p[0] == '\t')) { line = p + 1; continue; } if (p[0] == '#') { line = NULL; break; } break; } /* * Comments: keep going. */ if (!line) continue; /* * Strip off CR / LF */ for (p = line; *p != '\0'; p++) { if ((p[0] == '\r') || (p[0] == '\n')) { p[0] = '\0'; break; } } } if (strcmp(line, "reconnect") == 0) { close(sockfd); line = NULL; goto reconnect; } if (memcmp(line, "secret ", 7) == 0) { if (!secret) { secret = line + 7; do_challenge(sockfd); } line = NULL; continue; } /* * Exit, done, etc. */ if ((strcmp(line, "exit") == 0) || (strcmp(line, "quit") == 0)) { break; } if (server && !secret) { fprintf(stderr, "ERROR: You must enter 'secret <SECRET>' before running any commands\n"); line = NULL; continue; } size = run_command(sockfd, line, buffer, sizeof(buffer)); if (size <= 0) break; /* error, or clean exit */ if (size == 1) continue; /* no output. */ fputs(buffer, outputfp); fflush(outputfp); fprintf(outputfp, "\n"); } fprintf(outputfp, "\n"); return 0; }