struct request * request_create( struct tcp *conn ) { struct request *r; time_t stoptime = time(0)+300; char line[REQUEST_LINE_MAX]; char url[REQUEST_LINE_MAX]; char action[REQUEST_LINE_MAX]; char path[REQUEST_LINE_MAX]; char hostport[REQUEST_LINE_MAX]; r = malloc(sizeof(*r)); memset(r,0,sizeof(*r)); r->conn = conn; if(!tcp_readline(r->conn,line,sizeof(line),stoptime)) { request_delete(r); return 0; } if(sscanf(line,"%s %s",action,url)!=2) { request_delete(r); return 0; } while(1) { if(!tcp_readline(conn,line,sizeof(line),stoptime)) { request_delete(r); return 0; } if(!line[0]) break; } if(sscanf(url,"http://%[^/]%s",hostport,path)==2) { // continue on } else { strcpy(path,url); } if(!path[1]) { r->filename = strdup("index.html"); } else { r->filename = strdup(&path[1]); } return r; }
int sserver_connect(const struct protocol_interface *protocol, int verify_only) { char crypt_password[64]; char server_version[128]; char tmp_keyname[256]; const char *begin_request = "BEGIN SSL AUTH REQUEST"; const char *end_request = "END SSL AUTH REQUEST"; const char *username = NULL; const char *cert = current_server()->current_root->optional_3; int l; int sserver_version = 0; int strict = 0; CScramble scramble; bool send_client_version = false; if(current_server()->current_root->optional_1) { sserver_version = atoi(current_server()->current_root->optional_1); if(sserver_version != 0 && sserver_version != 1) { server_error(0,"version must be one of:"); server_error(0,"0 - All CVSNT-type servers"); server_error(0,"1 - Unix server using Corey Minards' sserver patches"); server_error(1,"Please specify a valid value"); } } if(!CGlobalSettings::GetUserValue("cvsnt","sserver","StrictChecking",server_version,sizeof(server_version))) { strict = atoi(server_version); } if(!cert && !CGlobalSettings::GetUserValue("cvsnt","sserver","ClientCert",tmp_keyname,sizeof(tmp_keyname))) { cert = tmp_keyname; } if(current_server()->current_root->optional_2) strict = atoi(current_server()->current_root->optional_2); if(sserver_version == 1) /* Old sserver */ { begin_request = verify_only?"BEGIN SSL VERIFICATION REQUEST":"BEGIN SSL REQUEST"; end_request = verify_only?"END SSL VERIFICATION REQUEST":"END SSL REQUEST"; } else if(verify_only) { begin_request = "BEGIN SSL VERIFICATION REQUEST"; end_request = "END SSL VERIFICATION REQUEST"; } username = get_username(current_server()->current_root); if(!username || !current_server()->current_root->hostname || !current_server()->current_root->directory) return CVSPROTO_BADPARMS; if(tcp_connect(current_server()->current_root)) return CVSPROTO_FAIL; if(current_server()->current_root->password) strncpy(crypt_password,scramble.Scramble(current_server()->current_root->password),sizeof(crypt_password)); else { if(sserver_get_user_password(username,current_server()->current_root->hostname,current_server()->current_root->port,current_server()->current_root->directory,crypt_password,sizeof(crypt_password))) { /* Using null password - trace something out here */ server_error(0,"Using an empty password; you may need to do 'cvs login' with a real password\n"); strncpy(crypt_password,scramble.Scramble(""),sizeof(crypt_password)); } } if(sserver_version == 0) /* Pre-CVSNT had no version check */ { if(tcp_printf("%s\n",begin_request)<0) return CVSPROTO_FAIL; for(;;) { *server_version='\0'; if((l=tcp_readline(server_version,sizeof(server_version))<0)) return CVSPROTO_FAIL; if(*server_version) break; #ifdef _WIN32 Sleep(10); #else usleep(10); #endif } if(strncmp(server_version,"SSERVER ",8)) { server_error(0,"%s\n",server_version); return CVSPROTO_FAIL; } if(strncmp(server_version+8,"1.0 ",4)) send_client_version = true; } if(!ClientAuthenticate(cert,current_server()->current_root->hostname)) return CVSPROTO_AUTHFAIL; QueryContextAttributes(&contextHandle,SECPKG_ATTR_STREAM_SIZES,&secSizes); PCERT_CONTEXT sc; PCCERT_CHAIN_CONTEXT pcc; CERT_SIMPLE_CHAIN *psc; CERT_CHAIN_PARA para = { sizeof(CERT_CHAIN_PARA) }; DWORD trust,rc; rc = QueryContextAttributes(&contextHandle,SECPKG_ATTR_REMOTE_CERT_CONTEXT,&sc); if(rc) server_error(1,"Couldn't get server certificate"); if(!CertGetCertificateChain(NULL, sc, NULL, NULL, ¶, 0, NULL, &pcc)) server_error(1,"Couldn't get server certificate chain"); psc = pcc->rgpChain[0]; trust = psc->TrustStatus.dwErrorStatus; if (trust) { if (trust & (CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_IS_UNTRUSTED_ROOT)) ; // Seld signed else if (trust & (CERT_TRUST_IS_NOT_TIME_VALID)) server_error(1,"Server certificate expired"); else server_error(1,"Server certificate verification failed - %08x",trust); } if(strict) { char certname[256]; CertGetNameString(sc, CERT_NAME_DNS_TYPE, 0, NULL, certname, sizeof(certname)); if(strcasecmp(certname,current_server()->current_root->hostname)) server_error(1, "Certificate CommonName '%s' does not match server name '%s'\n",certname,current_server()->current_root->hostname); } CertFreeCertificateChain(pcc); FreeContextBuffer(sc); g_sslBufferInPos=g_sslBufferOutPos=0; g_sslBufferInLen=g_sslBufferOutLen=0; if(sserver_version == 1) { if(sserver_printf("%s\n",begin_request)<0) return CVSPROTO_FAIL; } // For server versions 1.1+ send CLIENT_VERSION_STRING if(send_client_version && sserver_printf(SSERVER_CLIENT_VERSION_STRING)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n%s\n",current_server()->current_root->directory,username)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n",crypt_password)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n",end_request)<0) return CVSPROTO_FAIL; return CVSPROTO_SUCCESS; }
int sspi_connect(const struct protocol_interface *protocol, int verify_only) { char crypt_password[64]; const char *password; char domain_buffer[128],*domain; char user_buffer[128],*p; const char *user; const char *begin_request = "BEGIN SSPI"; char protocols[1024]; const char *proto; CScramble scramble; if(!current_server()->current_root->hostname || !current_server()->current_root->directory) return CVSPROTO_BADPARMS; if(tcp_connect(current_server()->current_root)) return CVSPROTO_FAIL; user = get_username(current_server()->current_root); password = current_server()->current_root->password; domain = NULL; if(!current_server()->current_root->password) { if(!sspi_get_user_password(user,current_server()->current_root->hostname,current_server()->current_root->port,current_server()->current_root->directory,crypt_password,sizeof(crypt_password))) { password = scramble.Unscramble(crypt_password); } } if(strchr(user,'\\')) { strncpy(domain_buffer,user,sizeof(domain_buffer)); domain_buffer[sizeof(domain_buffer)-1]='\0'; domain=strchr(domain_buffer,'\\'); if(domain) { *domain = '\0'; strncpy(user_buffer,domain+1,sizeof(user_buffer)); domain = domain_buffer; user = user_buffer; } } if(tcp_printf("%s\nNTLM\n",begin_request)<0) return CVSPROTO_FAIL; tcp_readline(protocols, sizeof(protocols)); if((p=strstr(protocols,"[server aborted"))!=NULL) { server_error(1, p); } if(strstr(protocols,"NTLM")) proto="NTLM"; else server_error(1, "Can't authenticate - server and client cannot agree on an authentication scheme (got '%s')\n",protocols); if(!ClientAuthenticate(proto,user,password,domain,current_server()->current_root->hostname)) { /* Actually we never get here... NTLM seems to allow the client to authenticate then fails at the server end. Wierd huh? */ if(user) server_error(1, "Can't authenticate - Username, Password or Domain is incorrect\n"); else server_error(1, "Can't authenticate - perhaps you need to login first?\n"); return CVSPROTO_FAIL; } if(tcp_printf("%s\n",current_server()->current_root->directory)<0) return CVSPROTO_FAIL; return CVSPROTO_SUCCESS; }