/** * selectionne une nouvelle transaction, teste le type de page pour choisir. * * \param * * \return * */ void gsb_data_mix_new_transaction_by_menu ( void ) { gint current_page; current_page = gsb_gui_navigation_get_current_page ( ); if ( current_page == GSB_ACCOUNT_PAGE ) new_transaction (); else if ( current_page == GSB_SCHEDULER_PAGE ) gsb_scheduler_list_edit_transaction ( -1 ); }
/* tries to take care of a redirection */ void handle_3xx(struct sockaddr_in *tadr) { char *uscheme, *uuser, *uhost, *contact; printf("** received redirect "); if (warning_ext == 1) { printf("from "); warning_extract(rec); printf("\n"); } else printf("\n"); /* we'll try to handle 301 and 302 here, other 3xx are to complex */ regcomp(&(regexps.redexp), "^SIP/[0-9]\\.[0-9] 30[125] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); if (regexec(&(regexps.redexp), rec, 0, 0, 0) == REG_NOERROR) { /* try to find the contact in the redirect */ contact = uri_from_contact(rec); if (contact==NULL) { fprintf(stderr, "error: cannot find Contact in this " "redirect:\n%s\n", rec); exit_code(3, __PRETTY_FUNCTION__, "missing Contact header in reply"); } /* correct our request */ uri_replace(req, contact); new_transaction(req, rep); /* extract the needed information*/ rport = 0; address = 0; parse_uri(contact, &uscheme, &uuser, &uhost, &rport); if (!rport) address = getsrvadr(uhost, &rport, &transport); if (!address) address = getaddress(uhost); if (!address){ fprintf(stderr, "error: cannot determine host " "address from Contact of redirect:" "\n%s\n", rec); exit_code(2, __PRETTY_FUNCTION__, "missing host in Contact header"); } if (!rport) { rport = 5060; } free(contact); if (!outbound_proxy) cdata.connected = set_target(tadr, address, rport, cdata.csock, cdata.connected); } else { fprintf(stderr, "error: cannot handle this redirect:" "\n%s\n", rec); exit_code(2, __PRETTY_FUNCTION__, "unsupported redirect reply"); } }
/* this is the main function with the loops and modes */ void shoot(char *buf, int buff_size) { struct timespec sleep_ms_s, sleep_rem; int ret, cseqtmp, rand_tmp; char buf2[BUFSIZE], buf3[BUFSIZE], lport_str[LPORT_STR_LEN]; /* delays.retryAfter = DEFAULT_TIMEOUT; */ if (transport == SIP_UDP_TRANSPORT) { delays.retryAfter = timer_t1; } else { delays.retryAfter = timer_final; } inv_trans = 0; cseq_counter = 1; usrlocstep = REG_REP; /* initalize local vars */ cdata.dontsend=cdata.dontrecv=counters.retrans_r_c=counters.retrans_s_c= 0; delays.big_delay=counters.send_counter=counters.run= 0; timers.delaytime.tv_sec = 0; timers.delaytime.tv_usec = 0; usern = NULL; /* initialize local arrays */ memset(buf2, 0, BUFSIZE); memset(buf3, 0, BUFSIZE); memset(lport_str, 0, LPORT_STR_LEN); cdata.csock = cdata.usock = -1; cdata.connected = 0; cdata.buf_tmp = NULL; cdata.buf_tmp_size = 0; memset(&(timers.sendtime), 0, sizeof(timers.sendtime)); memset(&(timers.recvtime), 0, sizeof(timers.recvtime)); memset(&(timers.firstsendt), 0, sizeof(timers.firstsendt)); memset(&(timers.starttime), 0, sizeof(timers.starttime)); memset(&(timers.delaytime), 0, sizeof(timers.delaytime)); req = buf; rep = buf2; rec = buf3; create_sockets(&cdata); if (sleep_ms != 0) { if (sleep_ms == -2) { rand_tmp = rand(); sleep_ms_s.tv_sec = rand_tmp / 1000; sleep_ms_s.tv_nsec = (rand_tmp % 1000) * 1000000; } else { sleep_ms_s.tv_sec = sleep_ms / 1000; sleep_ms_s.tv_nsec = (sleep_ms % 1000) * 1000000; } } if (replace_b == 1){ replace_string(req, "$dsthost$", domainname); replace_string(req, "$srchost$", fqdn); sprintf(lport_str, "%i", lport); replace_string(req, "$port$", lport_str); if (username) replace_string(req, "$user$", username); } if (replace_str) replace_strings(req, replace_str); /* set all regular expression to simplfy the result code indetification */ regcomp(&(regexps.replyexp), "^SIP/[0-9]\\.[0-9] [1-6][0-9][0-9]", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.proexp), "^SIP/[0-9]\\.[0-9] 1[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.okexp), "^SIP/[0-9]\\.[0-9] 2[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.redexp), "^SIP/[0-9]\\.[0-9] 3[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.authexp), "^SIP/[0-9]\\.[0-9] 40[17] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.errexp), "^SIP/[0-9]\\.[0-9] 4[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); regcomp(&(regexps.tmhexp), "^SIP/[0-9]\\.[0-9] 483 ", REG_EXTENDED|REG_NOSUB|REG_ICASE); if (username) { if (nameend > 0) { usern = str_alloc(strlen(username) + 12); create_usern(usern, username, namebeg); } else { if (*(username + strlen(username) - 1) != '@') { usern = str_alloc(strlen(username) + 2); create_usern(usern, username, -1); } else { usern = username; } } } if (usrloc == 1||invite == 1||message == 1){ /* calculate the number of required steps and create initial mes */ if (usrloc == 1) { create_msg(REQ_REG, req, NULL, usern, cseq_counter); usrlocstep=REG_REP; } else if (invite == 1) { create_msg(REQ_INV, req, rep, usern, cseq_counter); inv_trans = 1; usrlocstep=INV_RECV; } else { create_msg(REQ_MES, req, rep, usern, cseq_counter); if (mes_body) usrlocstep=MES_OK_RECV; else usrlocstep=MES_RECV; } } else if (trace == 1){ /* for trace we need some spezial initis */ namebeg=0; create_msg(REQ_OPT, req, NULL, usern, cseq_counter); set_maxforw(req, namebeg); } else if (flood == 1){ if (nameend<=0) nameend=INT_MAX; namebeg=1; create_msg(REQ_FLOOD, req, NULL, usern, cseq_counter); } else if (randtrash == 1){ counters.randretrys=0; namebeg=1; create_msg(REQ_RAND, req, NULL, usern, cseq_counter); nameend=(int)strlen(req); if (trashchar == 1){ if (trashchar < nameend) nameend=trashchar; else fprintf(stderr, "warning: number of trashed chars to big. setting to " "request length\n"); } trash_random(req); } else { /* for none of the modes we also need some inits */ if (file_b == 0) { namebeg=1; create_msg(REQ_OPT, req, NULL, usern, cseq_counter); } else { if (STRNCASECMP(req, INV_STR, INV_STR_LEN) == 0) { inv_trans = 1; } if(via_ins == 1) add_via(req); } /* delays.retryAfter = delays.retryAfter / 10; */ if(maxforw!=-1) set_maxforw(req, maxforw); } cdata.connected = set_target(&(cdata.adr), address, rport, cdata.csock, cdata.connected); /* here we go until someone decides to exit */ while(1) { before_sending(); if (sleep_ms == -2) { rand_tmp = rand(); sleep_ms_s.tv_sec = rand_tmp / 1000; sleep_ms_s.tv_nsec = (rand_tmp % 1000) * 1000; } if (sleep_ms != 0) { dbg("sleeping for %li s + %li ns\n", sleep_ms_s.tv_sec, sleep_ms_s.tv_nsec); nanosleep(&sleep_ms_s, &sleep_rem); } send_message(req, &cdata, &counters, &timers); /* in flood we are only interested in sending so skip the rest */ if (flood == 0) { ret = recv_message(rec, BUFSIZE, inv_trans, &delays, &timers, &counters, &cdata, ®exps); if(ret > 0) { if (usrlocstep == INV_OK_RECV) { swap_ptr(&rep, &req); } /* send ACK for non-provisional reply on INVITE */ if ((STRNCASECMP(req, "INVITE", 6)==0) && (regexec(&(regexps.replyexp), rec, 0, 0, 0) == REG_NOERROR) && (regexec(&(regexps.proexp), rec, 0, 0, 0) == REG_NOMATCH)) { build_ack(req, rec, rep, ®exps); cdata.dontsend = 0; inv_trans = 0; /* lets fire the ACK to the server */ send_message(rep, &cdata, &counters, &timers); inv_trans = 1; } /* check for old CSeq => ignore retransmission */ cseqtmp = cseq(rec); if ((0 < cseqtmp) && (cseqtmp < cseq_counter)) { if (verbose>0) { printf("ignoring retransmission\n"); } counters.retrans_r_c++; cdata.dontsend = 1; continue; } else if (regexec(&(regexps.authexp), rec, 0, 0, 0) == REG_NOERROR) { if (!username && !auth_username) { if (timing > 0) { timing--; if (timing == 0) { if (counters.run == 0) { counters.run++; } printf("%.3f/%.3f/%.3f ms\n", delays.small_delay, delays.all_delay / counters.run, delays.big_delay); exit_code(0, __PRETTY_FUNCTION__, NULL); } counters.run++; new_transaction(req, rep); delays.retryAfter = timer_t1; continue; } fprintf(stderr, "%s\nerror: received 40[17] but cannot " "authentication without a username or auth username\n", rec); log_message(req); exit_code(2, __PRETTY_FUNCTION__, "missing username for authentication"); } /* prevents a strange error */ regcomp(&(regexps.authexp), "^SIP/[0-9]\\.[0-9] 40[17] ", REG_EXTENDED|REG_NOSUB|REG_ICASE); insert_auth(req, rec); if (verbose > 2) printf("\nreceived:\n%s\n", rec); new_transaction(req, rep); continue; } /* if auth...*/ /* lets see if received a redirect */ if (redirects == 1 && regexec(&(regexps.redexp), rec, 0, 0, 0) == REG_NOERROR) { handle_3xx(&(cdata.adr)); } /* if redircts... */ else if (trace == 1) { trace_reply(); } /* if trace ... */ else if (usrloc == 1||invite == 1||message == 1) { handle_usrloc(); } else if (randtrash == 1) { handle_randtrash(); } else { handle_default(); } /* redirect, auth, and modes */ } /* ret > 0 */ else if (ret == -1) { // we did not got anything back, send again /* no re-transmission on reliable transports */ if (transport != SIP_UDP_TRANSPORT) { cdata.dontsend = 1; } continue; } else if (ret == -2) { // we received non-matching ICMP cdata.dontsend = 1; continue; } else { if (usrloc == 1) { printf("failed\n"); } perror("socket error"); exit_code(3, __PRETTY_FUNCTION__, "internal socket error"); } } /* !flood */ else { if (counters.send_counter == 1) { memcpy(&(timers.firstsendt), &(timers.sendtime), sizeof(struct timeval)); } if (namebeg==nameend) { printf("flood end reached\n"); printf("it took %.3f ms seconds to send %i request.\n", deltaT(&(timers.firstsendt), &(timers.sendtime)), namebeg); printf("we sent %f requests per second.\n", (namebeg/(deltaT(&(timers.firstsendt), &(timers.sendtime)))*1000)); exit_code(0, __PRETTY_FUNCTION__, NULL); } namebeg++; cseq_counter++; create_msg(REQ_FLOOD, req, NULL, usern, cseq_counter); } } /* while 1 */ /* this should never happen any more... */ if (randtrash == 1) { exit_code(0, __PRETTY_FUNCTION__, NULL); } printf("** give up retransmissioning....\n"); if (counters.retrans_r_c>0 && (verbose > 1)) { printf("%i retransmissions received during test\n", counters.retrans_r_c); } if (counters.retrans_s_c>0 && (verbose > 1)) { printf("sent %i retransmissions during test\n", counters.retrans_s_c); } exit_code(3, __PRETTY_FUNCTION__, "got outside of endless messaging loop"); }
/* takes care of replies in the default mode */ void handle_default() { /* in the normal send and reply case anything other then 1xx will be treated as final response*/ if (regexec(&(regexps.proexp), rec, 0, 0, 0) == REG_NOERROR) { if (verbose > 1) { printf("%s\n\n", rec); printf("** reply received "); if ((counters.send_counter == 1) || (STRNCASECMP(req, ACK_STR, ACK_STR_LEN) == 0)) { printf("after %.3f ms **\n", deltaT(&(timers.firstsendt), &(timers.recvtime))); } else { printf("%.3f ms after first send\n and " "%.3f ms after last send **\n", deltaT(&(timers.firstsendt), &(timers.recvtime)), deltaT(&(timers.sendtime), &(timers.recvtime))); } printf(" "); print_message_line(rec); printf(" provisional received; still" " waiting for a final response\n"); } if (inv_trans) { delays.retryAfter = timer_final; } else { delays.retryAfter = timer_t2; } cdata.dontsend = 1; return; } else { if (verbose > 1) { printf("%s\n\n", rec); printf("** reply received "); if ((counters.send_counter == 1) || (STRNCASECMP(req, ACK_STR, ACK_STR_LEN) == 0)){ printf("after %.3f ms **\n", deltaT(&(timers.firstsendt), &(timers.recvtime))); } else { printf("%.3f ms after first send\n and " "%.3f ms after last send **\n", deltaT(&(timers.firstsendt), &(timers.recvtime)), deltaT(&(timers.sendtime), &(timers.recvtime))); } printf(" "); print_message_line(rec); printf(" final received\n"); } else if (verbose>0) { printf("%s\n", rec); } if (timing > 0) { timing--; if (timing == 0) { if (counters.run == 0) { counters.run++; } printf("%.3f/%.3f/%.3f ms\n", delays.small_delay, delays.all_delay / counters.run, delays.big_delay); } else { counters.run++; new_transaction(req, rep); delays.retryAfter = timer_t1; } } if (timing == 0) { if (regexec(&(regexps.okexp), rec, 0, 0, 0) == REG_NOERROR) { on_success(rec); } else { log_message(req); exit_code(1, __PRETTY_FUNCTION__, "received final non-2xx reply"); } } } }
int main(int argc, char **argv) { //ENGINE *e = NULL; int c, host_port = 80, count = 1; char *host_name, *p, *dir_name = NULL; char http_string[16384]; struct http_reply reply; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; struct scep scep_t; FILE *fp = NULL; BIO *bp; STACK_OF(X509) *nextcara = NULL; X509 *cert=NULL; PKCS7 p7; int i; int required_option_space; #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; //printf("Starting sscep\n"); //fprintf(stdout, "%s: starting sscep on WIN32, sscep version %s\n", pname, VERSION); wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return; } #endif /* Initialize scep layer */ init_scep(); /* Set program name */ pname = argv[0]; /* Set timeout */ timeout = TIMEOUT; /* Check operation parameter */ if (!argv[1]) { usage(); } else if (!strncmp(argv[1], "getca", 5)) { operation_flag = SCEP_OPERATION_GETCA; } else if (!strncmp(argv[1], "enroll", 6)) { operation_flag = SCEP_OPERATION_ENROLL; } else if (!strncmp(argv[1], "getcert", 7)) { operation_flag = SCEP_OPERATION_GETCERT; } else if (!strncmp(argv[1], "getcrl", 6)) { operation_flag = SCEP_OPERATION_GETCRL; } else if (!strncmp(argv[1], "getnextca", 9)) { operation_flag = SCEP_OPERATION_GETNEXTCA; } else { fprintf(stderr, "%s: missing or illegal operation parameter\n", argv[0]); usage(); } /* Skip first parameter and parse the rest of the command */ optind++; while ((c = getopt(argc, argv, "c:C:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:HM:")) != -1) switch(c) { case 'c': c_flag = 1; c_char = optarg; break; case 'C': C_flag = 1; C_char = optarg; break; case 'd': d_flag = 1; break; case 'e': e_flag = 1; e_char = optarg; break; case 'E': E_flag = 1; E_char = optarg; break; case 'F': F_flag = 1; F_char = optarg; break; case 'f': f_flag = 1; f_char = optarg; break; case 'g': g_flag = 1; g_char = optarg; break; case 'h'://TODO change to eg. ID --inform=ID h_flag = 1; break; case 'H': H_flag = 1; break; case 'i': i_flag = 1; i_char = optarg; break; case 'k': k_flag = 1; k_char = optarg; break; case 'K': K_flag = 1; K_char = optarg; break; case 'l': l_flag = 1; l_char = optarg; break; case 'L': L_flag = 1; L_char = optarg; break; case 'm': m_flag = 1; m_char = optarg; break; case 'M': if(!M_flag) { /* if this is the first time the option appears, create a * new string. */ required_option_space = strlen(optarg) + 1; M_char = malloc(required_option_space); if(!M_char) error_memory(); strncpy(M_char, optarg, required_option_space); // set the flag, so we already have a string M_flag = 1; } else { /* we already have a string, just extend it. */ // old part + new part + &-sign + null byte required_option_space = strlen(M_char) + strlen(optarg) + 2; M_char = realloc(M_char, required_option_space); if(!M_char) error_memory(); strncat(M_char, "&", 1); strncat(M_char, optarg, strlen(optarg)); } break; case 'n': n_flag = 1; n_num = atoi(optarg); break; case 'O': O_flag = 1; O_char = optarg; break; case 'p': p_flag = 1; p_char = optarg; break; case 'r': r_flag = 1; r_char = optarg; break; case 'R': R_flag = 1; break; case 's': s_flag = 1; /*s_char = optarg;*/ s_char = handle_serial(optarg); break; case 'S': S_flag = 1; S_char = optarg; break; case 't': t_flag = 1; t_num = atoi(optarg); break; case 'T': T_flag = 1; T_num = atoi(optarg); break; case 'u': u_flag = 1; url_char = optarg; break; case 'v': v_flag = 1; break; case 'w': w_flag = 1; w_char = optarg; break; default: printf("argv: %s\n", argv[optind]); usage(); } argc -= optind; argv += optind; /* If we debug, include verbose messages also */ if (d_flag) v_flag = 1; if(f_char){ scep_conf_init(f_char); }else{ scep_conf = NULL; //moved init to here otherwise compile error on windows } /* Read in the configuration file: */ /*if (f_char) { #ifdef WIN32 if ((fopen_s(&fp, f_char, "r"))) #else if (!(fp = fopen(f_char, "r"))) #endif fprintf(stderr, "%s: cannot open %s\n", pname, f_char); else { init_config(fp); (void)fclose(fp); } }*/ if (v_flag) fprintf(stdout, "%s: starting sscep, version %s\n", pname, VERSION); /* * Create a new SCEP transaction and self-signed * certificate based on cert request */ if (v_flag) fprintf(stdout, "%s: new transaction\n", pname); new_transaction(&scep_t); /*enable Engine Support */ if (g_flag) { scep_t.e = scep_engine_init(scep_t.e); } /* * Check argument logic. */ if (!c_flag) { if (operation_flag == SCEP_OPERATION_GETCA) { fprintf(stderr, "%s: missing CA certificate filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing CA certificate (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate target filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing nextCA certificate target filename(-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (!C_flag) { if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate chain filename (-C)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_ENROLL) { if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!r_flag) { fprintf(stderr, "%s: missing request (-r)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } /* Set polling limits */ if (!n_flag) n_num = MAX_POLL_COUNT; if (!t_flag) t_num = POLL_TIME; if (!T_flag) T_num = MAX_POLL_TIME; } if (operation_flag == SCEP_OPERATION_GETCERT) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!s_flag) { fprintf(stderr, "%s: missing serial no (-s)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing cert file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_GETCRL) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing crl file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } #ifdef WIN32 else if (!(host_name = _strdup(url_char + 7))) #else else if (!(host_name = strdup(url_char + 7))) #endif error_memory(); p = host_name; c = 0; while (*p != '\0') { if (*p == '/' && !p_flag && !c) { *p = '\0'; if (*(p+1)) dir_name = p + 1; c = 1; } if (*p == ':') { *p = '\0'; if (*(p+1)) host_port = atoi(p+1); } p++; } if (!dir_name) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (host_port < 1 || host_port > 65550) { fprintf(stderr, "%s: illegal port number %d\n", pname, host_port); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) { fprintf(stdout, "%s: hostname: %s\n", pname, host_name); fprintf(stdout, "%s: directory: %s\n", pname, dir_name); fprintf(stdout, "%s: port: %d\n", pname, host_port); } /* Check algorithms */ if (!E_flag) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "blowfish", 8)) { enc_alg = (EVP_CIPHER *)EVP_bf_cbc(); } else if (!strncmp(E_char, "des", 3)) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "3des", 4)) { enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc(); } else if (!strncmp(E_char, "aes", 3)) { enc_alg = (EVP_CIPHER *)EVP_aes_256_cbc(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, E_char); exit (SCEP_PKISTATUS_ERROR); } if (!S_flag) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "md5", 3)) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "sha1", 4)) { sig_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, S_char); exit (SCEP_PKISTATUS_ERROR); } /* Fingerprint algorithm */ if (!F_flag) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "md5", 3)) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "sha1", 4)) { fp_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, F_char); exit (SCEP_PKISTATUS_ERROR); } /* * Switch to operation specific code */ switch(operation_flag) { case SCEP_OPERATION_GETCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting CA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "should define CA identifier (-i)\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if (v_flag){ printf("%s: valid response from server\n", pname); } if (reply.type == SCEP_MIME_GETCA_RA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ write_ca_ra(&reply); } /* Read payload as DER X.509 object: */ bp = BIO_new_mem_buf(reply.payload, reply.bytes); cacert = d2i_X509_bio(bp, NULL); /* Read and print certificate information */ if (!X509_digest(cacert, fp_alg, md, &n)) { ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag){ printf("%s: %s fingerprint: ", pname, OBJ_nid2sn(EVP_MD_type(fp_alg))); for (c = 0; c < (int)n; c++) { printf("%02X%c",md[c], (c + 1 == (int)n) ?'\n':':'); } } /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp,c_char , "w"))) #else if (!(fp = fopen(c_char, "w"))) #endif { fprintf(stderr, "%s: cannot open CA file for " "writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp, c_char) != 1) { fprintf(stderr, "%s: error while writing CA " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) printf("%s: CA certificate written as %s\n", pname, c_char); (void)fclose(fp); pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETNEXTCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETNEXTCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting nextCA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { if(v_flag){ fprintf(stderr, "%s: error while sending " "message\n", pname); fprintf(stderr, "%s: getnextCA might be not available" "\n", pname); } exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "there is no nextCA available\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if(d_flag) printf("%s: valid response from server\n", pname); if (reply.type == SCEP_MIME_GETNEXTCA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ //write_ca_ra(&reply); /* Set the whole struct as 0 */ memset(&scep_t, 0, sizeof(scep_t)); scep_t.reply_payload = reply.payload; scep_t.reply_len = reply.bytes; scep_t.request_type = SCEP_MIME_GETNEXTCA; pkcs7_verify_unwrap(&scep_t , C_char); //pkcs7_unwrap(&scep_t); } /* Get certs */ p7 = *(scep_t.reply_p7); nextcara = scep_t.reply_p7->d.sign->cert; if (v_flag) { printf ("verify and unwrap: found %d cert(s)\n", sk_X509_num(nextcara)); } for (i = 0; i < sk_X509_num(nextcara); i++) { char buffer[1024]; char name[1024]; memset(buffer, 0, 1024); memset(name, 0, 1024); cert = sk_X509_value(nextcara, i); if (v_flag) { printf("%s: found certificate with\n" " subject: '%s'\n", pname, X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer))); printf(" issuer: %s\n", X509_NAME_oneline(X509_get_issuer_name(cert), buffer, sizeof(buffer))); } /* Create name */ snprintf(name, 1024, "%s-%d", c_char, i); /* Write PEM-formatted file: */ if (!(fp = fopen(name, "w"))) { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); } if (v_flag) printf("%s: writing cert\n", pname); if (d_flag) PEM_write_X509(stdout, cert); if (PEM_write_X509(fp, cert) != 1) { fprintf(stderr, "%s: error while writing certificate " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } if(v_flag) printf("%s: certificate written as %s\n", pname, name); (void)fclose(fp); } pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETCERT: case SCEP_OPERATION_GETCRL: /* Read local certificate */ if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n", pname); exit (SCEP_PKISTATUS_FILE); } read_cert(&localcert, l_char); case SCEP_OPERATION_ENROLL: /* * Read in CA cert, private key and certificate * request in global variables. */ read_ca_cert(); if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n", pname); exit (SCEP_PKISTATUS_FILE); } if(scep_conf != NULL) { sscep_engine_read_key_new(&rsa, k_char, scep_t.e); } else { read_key(&rsa, k_char); } if ((K_flag && !O_flag) || (!K_flag && O_flag)) { fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname); exit (SCEP_PKISTATUS_FILE); } if (K_flag) { //TODO auf hwcrhk prfen? if(scep_conf != NULL) { sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e); } else { read_key(&renewal_key, K_char); } } if (O_flag) { read_cert(&renewal_cert, O_char); } if (operation_flag == SCEP_OPERATION_ENROLL) { read_request(); scep_t.transaction_id = key_fingerprint(request); if (v_flag) { printf("%s: Read request with transaction id: %s\n", pname, scep_t.transaction_id); } } if (operation_flag != SCEP_OPERATION_ENROLL) goto not_enroll; if (! O_flag) { if (v_flag) fprintf(stdout, "%s: generating selfsigned " "certificate\n", pname); new_selfsigned(&scep_t); } else { /* Use existing certificate */ scep_t.signercert = renewal_cert; scep_t.signerkey = renewal_key; } /* Write the selfsigned certificate if requested */ if (L_flag) { /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp, L_char, "w"))) { #else if (!(fp = fopen(L_char, "w"))) { #endif fprintf(stderr, "%s: cannot open " "file for writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp,scep_t.signercert) != 1) { fprintf(stderr, "%s: error while " "writing certificate file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } printf("%s: selfsigned certificate written " "as %s\n", pname, L_char); (void)fclose(fp); } /* Write issuer name and subject (GetCertInitial): */ if (!(scep_t.ias_getcertinit->subject = X509_REQ_get_subject_name(request))) { fprintf(stderr, "%s: error getting subject " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } not_enroll: if (!(scep_t.ias_getcertinit->issuer = X509_get_issuer_name(cacert))) { fprintf(stderr, "%s: error getting issuer " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* Write issuer name and serial (GETC{ert,rl}): */ scep_t.ias_getcert->issuer = scep_t.ias_getcertinit->issuer; scep_t.ias_getcrl->issuer = scep_t.ias_getcertinit->issuer; if (!(scep_t.ias_getcrl->serial = X509_get_serialNumber(cacert))) { fprintf(stderr, "%s: error getting serial " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* User supplied serial number */ if (s_flag) { BIGNUM *bn; ASN1_INTEGER *ai; int len = BN_dec2bn(&bn , s_char); if (!len || !(ai = BN_to_ASN1_INTEGER(bn, NULL))) { fprintf(stderr, "%s: error converting serial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_SS); } scep_t.ias_getcert->serial = ai; } break; } switch(operation_flag) { case SCEP_OPERATION_ENROLL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_ENROLL\n", pname); /* Resum mode: set GetCertInitial */ if (R_flag) { if (n_num == 0) exit (SCEP_PKISTATUS_SUCCESS); printf("%s: requesting certificate (#1)\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERTINIT; count++; } else { printf("%s: sending certificate request\n", pname); scep_t.request_type = SCEP_REQUEST_PKCSREQ; } break; case SCEP_OPERATION_GETCERT: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCERT\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERT; printf("%s: requesting certificate\n",pname); break; case SCEP_OPERATION_GETCRL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCRL\n", pname); scep_t.request_type = SCEP_REQUEST_GETCRL; printf("%s: requesting crl\n",pname); break; } /* Enter polling loop */ while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) { /* create payload */ pkcs7_wrap(&scep_t); /* URL-encode */ p = url_encode((char *)scep_t.request_payload, scep_t.request_len); /*Test mode print SCEP request and don't send it*/ if(m_flag){ /* Write output file : */ #ifdef WIN32 if ((fopen_s(&fp, m_char, "w"))) #else if (!(fp = fopen(m_char, "w"))) #endif { fprintf(stderr, "%s: cannot open output file for " "writing\n", m_char); }else { printf("%s: writing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(fp, scep_t.request_p7); } //printf("Print SCEP Request:\n %s\n",scep_t.request_payload); return 0; } /* Forge the HTTP message */ /* snprintf(http_string, sizeof(http_string), "GET %s%s?operation=" "PKIOperation&message=" "%s HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p);*/ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,p, M_char); } if (d_flag) fprintf(stdout, "%s: scep msg: %s", pname, http_string); /* send http */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } /* Verisign Onsite returns strange reply... * XXXXXXXXXXXXXXXXXXX */ if ((reply.status == 200) && (reply.payload == NULL)) { /* scep_t.pki_status = SCEP_PKISTATUS_PENDING; break; */ exit (SCEP_PKISTATUS_ERROR); } printf("%s: valid response from server\n", pname); /* Check payload */ scep_t.reply_len = reply.bytes; scep_t.reply_payload = (unsigned char *)reply.payload; pkcs7_unwrap(&scep_t); pkistatus = scep_t.pki_status; switch(scep_t.pki_status) { case SCEP_PKISTATUS_SUCCESS: break; case SCEP_PKISTATUS_PENDING: /* Check time limits */ if (((t_num * count) >= T_num) || (count > n_num)) { exit (pkistatus); } scep_t.request_type = SCEP_REQUEST_GETCERTINIT; /* Wait for poll interval */ if (v_flag) printf("%s: waiting for %d secs\n", pname, t_num); sleep(t_num); printf("%s: requesting certificate " "(#%d)\n", pname, count); /* Add counter */ count++; break; case SCEP_PKISTATUS_FAILURE: /* Handle failure */ switch (scep_t.fail_info) { case SCEP_FAILINFO_BADALG: exit (SCEP_PKISTATUS_BADALG); case SCEP_FAILINFO_BADMSGCHK: exit (SCEP_PKISTATUS_BADMSGCHK); case SCEP_FAILINFO_BADREQ: exit (SCEP_PKISTATUS_BADREQ); case SCEP_FAILINFO_BADTIME: exit (SCEP_PKISTATUS_BADTIME); case SCEP_FAILINFO_BADCERTID: exit (SCEP_PKISTATUS_BADCERTID); /* Shouldn't be there... */ default: exit (SCEP_PKISTATUS_ERROR); } default: fprintf(stderr, "%s: unknown " "pkiStatus\n", pname); exit (SCEP_PKISTATUS_ERROR); } } /* We got SUCCESS, analyze the reply */ switch (scep_t.request_type) { /* Local certificate */ case SCEP_REQUEST_PKCSREQ: case SCEP_REQUEST_GETCERTINIT: write_local_cert(&scep_t); break; /* Other end entity certificate */ case SCEP_REQUEST_GETCERT: write_other_cert(&scep_t); break; break; /* CRL */ case SCEP_REQUEST_GETCRL: write_crl(&scep_t); break; } //TODO //richtiger ort für disable?? // if(e){ // ENGINE_finish(*e); // ENGINE_free(*e); // hwEngine = NULL; // ENGINE_cleanup(); // } // return (pkistatus); } void usage() { fprintf(stdout, "\nsscep version %s\n\n" , VERSION); fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n" "\nAvailable OPERATIONs are\n" " getca Get CA/RA certificate(s)\n" " getnextca Get next CA/RA certificate(s)\n" " enroll Enroll certificate\n" " getcert Query certificate\n" " getcrl Query CRL\n" "\nGeneral OPTIONS\n" " -u <url> SCEP server URL\n" " -p <host:port> Use proxy server at host:port\n" " -M <string> Monitor Information String name=value&name=value ...\n" " -g Enable Engine support\n" " -h Keyforme=ID. \n"//TODO " -f <file> Use configuration file\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -E <name> PKCS#7 encryption algorithm (des|3des|blowfish|aes)\n" " -S <name> PKCS#7 signature algorithm (md5|sha1)\n" " -v Verbose operation\n" " -d Debug (even more verbose operation)\n" "\nOPTIONS for OPERATION getca are\n" " -i <string> CA identifier string\n" " -F <name> Fingerprint algorithm\n" "\nOPTIONS for OPERATION getnextca are\n" " -C <file> Local certificate chain file for signature verification in PEM format \n" " -F <name> Fingerprint algorithm\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -w <file> Write signer certificate in file (optional) \n" "\nOPTIONS for OPERATION enroll are\n" " -k <file> Private key file\n" " -r <file> Certificate request file\n" " -K <file> Signature private key file, use with -O\n" " -O <file> Signature certificate (used instead of self-signed)\n" " -l <file> Write enrolled certificate in file\n" " -e <file> Use different CA cert for encryption\n" " -L <file> Write selfsigned certificate in file\n" " -t <secs> Polling interval in seconds\n" " -T <secs> Max polling time in seconds\n" " -n <count> Max number of GetCertInitial requests\n" " -R Resume interrupted enrollment\n" "\nOPTIONS for OPERATION getcert are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -s <number> Certificate serial number\n" " -w <file> Write certificate in file\n" "\nOPTIONS for OPERATION getcrl are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -w <file> Write CRL in file\n\n", pname); exit(0); }
int check_for_message(char *recv, int size, struct sipsak_con_data *cd, struct sipsak_sr_time *srt, struct sipsak_counter *count, struct sipsak_delay *sd) { fd_set fd; struct timezone tz; struct timeval tv; double senddiff; int ret = 0; if (cd->dontrecv == 0) { /* set the timeout and wait for a response */ tv.tv_sec = sd->retryAfter/1000; tv.tv_usec = (sd->retryAfter % 1000) * 1000; FD_ZERO(&fd); if (cd->usock != -1) FD_SET(cd->usock, &fd); if (cd->csock != -1) FD_SET(cd->csock, &fd); #ifdef RAW_SUPPORT if (rawsock != -1) FD_SET(rawsock, &fd); #endif ret = select(FD_SETSIZE, &fd, NULL, NULL, &tv); (void)gettimeofday(&(srt->recvtime), &tz); } else { cd->dontrecv = 0; } /* store the time of our first send */ if (count->send_counter==1) { memcpy(&(srt->firstsendt), &(srt->sendtime), sizeof(struct timeval)); } if (sd->retryAfter == SIP_T1) { memcpy(&(srt->starttime), &(srt->sendtime), sizeof(struct timeval)); } if (ret == 0) { /* lets see if we at least received an icmp error */ if (cd->csock == -1) check_socket_error(cd->usock, size); else check_socket_error(cd->csock, size); /* printout that we did not received anything */ if (trace == 1) { printf("%i: timeout after %i ms\n", namebeg, sd->retryAfter); } else if (usrloc == 1||invite == 1||message == 1) { printf("timeout after %i ms\n", sd->retryAfter); } else if (verbose>0) printf("** timeout after %i ms**\n", sd->retryAfter); if (randtrash == 1) { printf("did not get a response on this request:\n%s\n", req); if (cseq_counter < nameend) { if (count->randretrys == 2) { printf("sended the following message three " "times without getting a response:\n%s\n" "give up further retransmissions...\n", req); exit_code(3); } else { printf("resending it without additional " "random changes...\n\n"); (count->randretrys)++; } } } senddiff = deltaT(&(srt->starttime), &(srt->recvtime)); if (senddiff > inv_final) { if (timing == 0) { if (verbose>0) printf("*** giving up, no final response after %.3f ms\n", senddiff); exit_code(3); } else { timing--; count->run++; sd->all_delay += senddiff; sd->big_delay = senddiff; new_transaction(req); sd->retryAfter = SIP_T1; if (timing == 0) { printf("%.3f/%.3f/%.3f ms\n", sd->small_delay, sd->all_delay / count->run, sd->big_delay); exit_code(3); } } } else { /* set retry time according to RFC3261 */ if ((inv_trans) || (sd->retryAfter *2 < SIP_T2)) { sd->retryAfter = sd->retryAfter * 2; } else { sd->retryAfter = SIP_T2; } } (count->retrans_s_c)++; if (srt->delaytime.tv_sec == 0) memcpy(&(srt->delaytime), &(srt->sendtime), sizeof(struct timeval)); /* if we did not exit until here lets try another send */ return -1; } else if ( ret == -1 ) { perror("select error"); exit_code(2); } else if (((cd->usock != -1) && FD_ISSET(cd->usock, &fd)) || ((cd->csock != -1) && FD_ISSET(cd->csock, &fd))) { if ((cd->usock != -1) && FD_ISSET(cd->usock, &fd)) ret = cd->usock; else if ((cd->csock != -1) && FD_ISSET(cd->csock, &fd)) ret = cd->csock; else { printf("unable to determine the socket which received something\n"); exit_code(2); } /* no timeout, no error ... something has happened :-) */ if (trace == 0 && usrloc ==0 && invite == 0 && message == 0 && randtrash == 0 && (verbose > 1)) printf ("\nmessage received"); } #ifdef RAW_SUPPORT else if ((rawsock != -1) && FD_ISSET(rawsock, &fd)) { if (verbose > 1) printf("\nreceived ICMP message"); ret = rawsock; } #endif else { printf("\nselect returned succesfuly, nothing received\n"); return -1; } return ret; }