int pserver_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string) { char *tmp; CScramble scramble; if (!strcmp (auth_string, "BEGIN VERIFICATION REQUEST")) pserver_protocol_interface.verify_only = 1; else if (!strcmp (auth_string, "BEGIN AUTH REQUEST")) pserver_protocol_interface.verify_only = 0; else return CVSPROTO_NOTME; /* Get the three important pieces of information in order. */ /* See above comment about error handling. */ server_getline (protocol, &pserver_protocol_interface.auth_repository, PATH_MAX); server_getline (protocol, &pserver_protocol_interface.auth_username, PATH_MAX); server_getline (protocol, &pserver_protocol_interface.auth_password, PATH_MAX); /* ... and make sure the protocol ends on the right foot. */ /* See above comment about error handling. */ server_getline(protocol, &tmp, PATH_MAX); if (strcmp (tmp, pserver_protocol_interface.verify_only ? "END VERIFICATION REQUEST" : "END AUTH REQUEST") != 0) { server_error (1, "bad auth protocol end: %s", tmp); free(tmp); } const char *unscrambled_password = scramble.Unscramble(pserver_protocol_interface.auth_password); if(!unscrambled_password || !*unscrambled_password) { CServerIo::trace(1,"PROTOCOL VIOLATION: Invalid scrambled password sent by client. Assuming blank for compatibility. Report bug to client vendor."); unscrambled_password=""; } strcpy(pserver_protocol_interface.auth_password, unscrambled_password); free(tmp); return CVSPROTO_SUCCESS; }
int sserver_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string) { CScramble scramble; char *tmp; int certonly; char *client_version = NULL; char keyfile[256]; const char *hostname = NULL; if (!strcmp (auth_string, "BEGIN SSL VERIFICATION REQUEST")) sserver_protocol_interface.verify_only = 1; else if (!strcmp (auth_string, "BEGIN SSL AUTH REQUEST")) sserver_protocol_interface.verify_only = 0; else return CVSPROTO_NOTME; write(current_server()->out_fd,SSERVER_INIT_STRING,sizeof(SSERVER_INIT_STRING)-1); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","CertificatesOnly",keyfile,sizeof(keyfile))) certonly = atoi(keyfile); if(!CGlobalSettings::GetGlobalValue("cvsnt","PServer","ServerDnsName",keyfile,sizeof(keyfile))) hostname = keyfile; if(!ServerAuthenticate(hostname)) return CVSPROTO_AUTHFAIL; QueryContextAttributes(&contextHandle,SECPKG_ATTR_STREAM_SIZES,&secSizes); g_sslBufferInPos=g_sslBufferOutPos=0; g_sslBufferInLen=g_sslBufferOutLen=0; set_encrypted_channel(1); /* Error must go through us now */ PCERT_CONTEXT sc; PCCERT_CHAIN_CONTEXT pcc; CERT_SIMPLE_CHAIN *psc; CERT_CHAIN_PARA para = { sizeof(CERT_CHAIN_PARA) }; DWORD trust,rc; BOOL cert = FALSE; rc = QueryContextAttributes(&contextHandle,SECPKG_ATTR_REMOTE_CERT_CONTEXT,&sc); if(rc && rc!=SEC_E_NO_CREDENTIALS) server_error(1,"Couldn't get client certificate"); if(rc!=SEC_E_NO_CREDENTIALS) /* The client doesn't have to send us a cert. as cvs uses passwords normally */ { if(!CertGetCertificateChain(NULL, sc, NULL, NULL, ¶, 0, NULL, &pcc)) server_error(1,"Couldn't get client certificate chain"); psc = pcc->rgpChain[0]; trust = psc->TrustStatus.dwErrorStatus; if (trust) { if (trust & (CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_IS_UNTRUSTED_ROOT)) server_error(1,"Client sent self signed certificate"); else if (trust & (CERT_TRUST_IS_NOT_TIME_VALID)) server_error(1,"Client certificate expired"); else server_error(1,"Client certificate verification failed - %08x",trust); } CertFreeCertificateChain(pcc); FreeContextBuffer(sc); cert = TRUE; } /* Get the three important pieces of information in order. */ /* See above comment about error handling. */ /* get version, if sent. 1.0 clients didn't have this handshake so we have to handle that. */ server_getline (protocol, &client_version, MAX_PATH); if(strncmp(client_version,"SSERVER-CLIENT ",15)) { sserver_protocol_interface.auth_repository = client_version; client_version = NULL; } else server_getline (protocol, &sserver_protocol_interface.auth_repository, MAX_PATH); server_getline (protocol, &sserver_protocol_interface.auth_username, MAX_PATH); server_getline (protocol, &sserver_protocol_interface.auth_password, MAX_PATH); if(client_version) free(client_version); client_version = NULL; /* ... and make sure the protocol ends on the right foot. */ /* See above comment about error handling. */ server_getline(protocol, &tmp, MAX_PATH); if (strcmp (tmp, sserver_protocol_interface.verify_only ? "END SSL VERIFICATION REQUEST" : "END SSL AUTH REQUEST") != 0) { server_printf ("bad auth protocol end: %s\n", tmp); free(tmp); return CVSPROTO_FAIL; } strcpy(sserver_protocol_interface.auth_password, scramble.Unscramble(sserver_protocol_interface.auth_password)); free(tmp); switch(certonly) { case 0: break; case 1: if(!cert) { server_error(0,"E Login requires a valid client certificate.\n"); return CVSPROTO_AUTHFAIL; } free(sserver_protocol_interface.auth_password); sserver_protocol_interface.auth_password = NULL; break; case 2: if(!cert) { server_error(0,"E Login requires a valid client certificate.\n"); return CVSPROTO_AUTHFAIL; } break; }; return CVSPROTO_SUCCESS; }
int read_command( char **args ) { int n=0, p=0; char *c; if( s_mode ) { if (server_getline( cline, MAX_COMMAND_LEN ) <= 0) { args[0] = ""; return 0; } } else { if( g_getline( cline, MAX_COMMAND_LEN ) < 0) setRun( "=", "EXIT" ); if( ! strlen( cline) > 0) return 0; } c = cline; /* to skip space */ while( *c==' ' || *c=='\t' ) { ++c; }; /* to get a command name */ *(args++) = c; while( *c!=' ' && *c!='\t' && *c!='\n' && *c!= EOF ) { c++; } *(c++) = '\0'; ++n; /* to skip space */ while( *c==' ' || *c=='\t' ) { ++c; }; /* to get a slot name */ *(args++) = c; while( *c!=' ' && *c!='\t' && *c!='=' && *c!='<' && *c!='\n' && *c!= EOF ) { c++; }; *(c++) = '\0'; ++n; /* to skip space */ while( *c==' ' || *c=='\t' ) { ++c; }; /* to get relation */ *(args++) = c; if( *c=='=' || *c=='<' ) { c++; if( *(c-1)=='<' && *c=='<' ) { c++; } *(c++) = '\0'; ++n; } /* to skip space */ while( *c==' ' || *c=='\t' ) { ++c; }; /* to get a value */ *(args++) = c; while( *c!='\n' && *c!='\0' && *c!= EOF ) { c++; }; *c = '\0'; ++n; return n; }
int sspi_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string) { char *protocols; const char *proto; int fdin, fdout, fderr; int l; short len; char line[1024]; char buf[1024]; int first; if (!strcmp (auth_string, "BEGIN SSPI")) sspi_protocol_interface.verify_only = 0; else return CVSPROTO_NOTME; server_getline(protocol, &protocols, 1024); if(!protocols) { server_printf("Nope!\n"); return CVSPROTO_FAIL; } else if(strstr(protocols,"Negotiate")) proto="Negotiate"; else if(strstr(protocols,"NTLM")) proto="NTLM"; else { server_printf("Nope!\n"); return CVSPROTO_FAIL; } free(protocols); server_printf("%s\n",proto); /* We have negotiated NTLM */ if(run_command(winbindwrapper, &fdin, &fdout, &fderr)) return CVSPROTO_FAIL; first=1; do { read(current_server()->in_fd,&len,2); len=ntohs(len); l=read(current_server()->in_fd,buf,len); if(l<0) return CVSPROTO_FAIL; if(first) strcpy(line,"YR "); else strcpy(line,"KK "); first = 0; l=base64enc((unsigned char *)buf,(unsigned char *)line+3,len); strcat(line,"\n"); write(fdin, line, strlen(line)); l=read(fdout, line, sizeof(line)); if(l<0) return CVSPROTO_FAIL; line[l]='\0'; if(line[0]=='T' && line[1]=='T') { len=base64dec((unsigned char *)line+3,(unsigned char *)buf,l-4); base64enc((unsigned char *)buf,(unsigned char *)line+3,len); len=htons(len); write(current_server()->out_fd,&len,2); write(current_server()->out_fd,buf,ntohs(len)); } } while(line[0]=='T' && line[1]=='T'); if(line[0]!='A' || line[1]!='F') return CVSPROTO_FAIL; close(fdin); close(fdout); close(fderr); line[strlen(line)-1]='\0'; sspi_protocol_interface.auth_username = strdup(line+3); /* Get the repository details for checking */ server_getline (protocol, &sspi_protocol_interface.auth_repository, 4096); return CVSPROTO_SUCCESS; }