Modification de propriétés sur . ___________________________________________________________________ Modifié : svnmerge-integrated - /python/trunk:1-61437,61439-61441,61443-61453,61455-61474,61476-61477,61479-61485,61487-61488,61490,61493-61528,61530-61563,61565-61569,61571-61576,61578-61584,61586,61588-61589,61591-61778,61780-61809,61811-61866,61868-61870,61872-61874,61876-61877,61883-61903,61905-61935,61938-61939,61941-62004,62007-62014,62016-62018,62021-62022,62024,62027,62029,62031-62066,62068-62074,62076-62094,62096,62098,62100-62102,62104-62122,62124-62125,62127-62137,62139-62142,62144-62194,62196-62222,62224-62308,62311-62397,62399-62430,62432-62510,62512-62516,62519-62535,62537-62598,62600-62665,62667-62683,62685-62719,62721,62723-62792,62794-62796,62798-62860,62862-62864,62866-62878,62880-62883,62885-62887,62889-62899,62901-62911,62913-62916,62918-62919,62921-62922,62924-62942,62944-62959,62961,62963-62967,62969-62970,62972-62973,62975-62976,62978-62982,62984,62987-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63045,63047-63054,63056-63079,63081-63085,63087-63097,63099,63101-63104,63106-63107,63109-63113,63115-63128,63130-63133,63135-63144,63146-63148,63151-63152,63155-63165,63167-63176,63181-63186,63188-63190,63192-63194,63196-63206,63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63248,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63342,63344-63346,63348-63353,63355-63357,63359-63373,63375,63377-63380,63383,63385-63391,63393-63402,63404-63407,63411-63412,63416-63420,63423-63424,63427,63429,63431-63433,63435-63439,63441-63457,63459-63468,63470-63480,63482-63484,63492,63496-63497,63499-63512,63514-63527,63529-63536,63538-63544,63546,63548,63550-63567,63569-63585,63590-63596,63602,63608-63610,63612-63616,63619-63629,63631-63648,63650-63659,63661-63664,63666-63671,63673-63674,63676,63678,63680-63684,63687-63690,63692-63703,63705-63713,63715-63717,63720,63722-63724,63726-63735,63737,63739-63741,63743-63744,63746-63766,63768-63775,63777-63798,63801-63813,63815-63845,63847,63850-63860,63862,63864-63872,63874-63898,63900-63909,63911-63913,63915-63931,63933-63941,63944,63946-63960,63964,63966,63968-63981,63983-64015,64017,64020-64027,64029-64030,64032-64039,64041-64043,64046-64047,64049-64056,64059-64061,64063-64067,64070-64079,64081-64085,64087-64089,64091-64092,64094-64096,64098-64104,64106-64127,64130-64132,64134-64141,64143-64168,64170-64205,64207-64247,64249,64251-64253,64255-64370,64372-64385,64387-64391,64393-64397,64399,64401-64412,64414-64423,64425-64428,64430,64432-64435,64440-64452,64454-64455,64457-64461,64463-64470,64472-64488,64490-64497,64499-64507,64509-64510,64512-64515,64517-64519,64521-64526,64528-64534,64536-64545,64548-64553,64556-64571,64573-64577,64579,64581-64594,64596-64632,64634,64636-64648,64650-64672,64674-64701,64703-64761,64763-64790,64792-64853,64856-64857,64860,64862-64864,64867-64909,64911-64912,64914-64921,64923-64929,64931-64952,64954-64957,64959-64961,64963-64985,64987-65004,65006-65015,65017-65019,65021-65031,65033-65041,65043,65045,65047-65068,65071-65074,65076-65081,65083-65084,65086-65101,65103-65108,65110,65113-65171,65173-65192,65194-65197,65199-65204,65206-65216,65218-65265,65267-65283,65285-65288,65290-65309,65311,65313-65317,65319-65322,65324-65345,65347-65348,65350,65352,65354,65356-65381,65384-65385,65388-65390,65392,65394,65396-65401,65403-65421,65424,65426-65437,65439,65441,65443,65445,65447-65448,65450,65452,65454,65456,65458-65461,65463,65465-65466,65468-65476,65478-65487,65489-65505,65507,65509,65511,65513,65515,65517-65518,65520-65521,65523,65525-65562,65564-65577,65579-65583,65585,65587,65589-65605,65607-65612,65614,65616,65618,65620-65641,65643-65654,65656-65662,65664,65666-65678,65680-65709,65711-65715,65717-65718,65720,65722-65732,65734-65740,65743-65747,65749-65761,65763-65767,65769-65797,65799-65801,65804-65805,65807-65813,65815-65821,65823-65838,65840-65864,65866-65871,65873,65875-65879,65881-65890,65892,65894-65911,65913,65915-65916,65918-65921,65923-65925,65927-65994,65996-66003,66005-66012,66014-66038,66040-66042,66044-66057,66059-66087,66089-66099,66101-66113,66115-66118,66120-66122,66124-66126,66128-66134,66136,66138-66141,66143-66180,66183-66191,66193-66195,66198-66228,66230-66231,66233-66274,66276-66280,66283,66285-66300,66302-66309,66311-66315,66317-66318,66320-66331,66333-66385,66387-66389,66391-66414,66417-66421,66423-66446,66448-66449,66451-66497,66499-66501,66503,66505,66507-66553,66555-66565,66567,66570-66619,66621-66656,66658-66675,66677-66681,66683-66688,66690-66713,66715-66720,66722-66743,66745-66755,66757-66762,66766-66767,66769-66808,66811-66821,66823-66877,66879-67001,67003-67012,67014-67040,67042-67059,67062-67162,67164-67165,67167-67265,67267-67286,67288-67302,67304-67306,67308-67325,67327-67331,67333-67335,67337-67348,67350-67352,67354-67369,67371-67375,67377-67395,67397-67406,67408-67410,67412-67497,67499-67520,67522-67580,67582,67585-67586,67588-67600,67602-67613,67615-67618,67620-67693,67695-67745,67747,67749-67761,67763-67796,67798-67821,67823-67901,67903-67933,67936-67954,67956-67966,67968-67975,67977-67979,67981-68013,68015-68088,68090-68091,68093-68149,68151-68155,68157,68162,68164-68178,68180-68207,68210-68219,68221-68230,68232-68237,68239,68241-68242,68244-68394,68396-68423,68425,68427-68428,68431,68433-68438,68440-68486,68488-68520,68522-68531,68533-68543,68546-68558,68560-68561,68563-68564,68568,68570-68578,68581-68583,68585-68588,68590-68591,68593-68596,68598-68602,68606-68704,68706-68759,68761-68763,68765,68767-68771,68773-68784,68786-68788,68790-68791,68794-68802,68804,68806,68808-68812,68814-68825,68827-68828,68830,68832-68842,68844,68846-68849,68851-68852,68854-68891,68893-68924,68926,68928-68940,68943-68952,68954-68963,68965-68984,68986-68997,68999-69000,69002-69009,69011,69013,69015-69017,69019-69022,69024-69038,69040-69069,69071-69073,69075-69084,69086,69088-69133,69135-69145,69147-69148,69150-69160,69162-69226,69228-69236,69238-69239,69241,69243-69251,69254-69256,69258-69261,69263-69267,69269-69270,69274-69275,69277-69294,69296-69301,69306-69314,69316-69321,69323-69372,69375-69388,69390-69393,69395-69413,69415-69432,69434-69442,69444-69508,69510-69515,69517-69521,69523-69524,69526-69527,69529,69531-69545,69547-69560,69562-69569,69571-69572,69574-69577,69579-69603,69605-69609,69611-69638,69640-69671,69673-69684,69686-69688,69690-69708,69710-69714,69718-69738,69740-69742,69744-69747,69749-69750,69752-69756,69758-69760,69762-69764,69766-69769,69771,69773-69776,69778-69794,69796-69836,69839-69869,69872-69877,69879-69895,69897-69907,69909-69936,69938-69945,69947-69951,69954,69956-69958,69960-69980,69982,69984-69993,69995-69999,70001-70010,70012-70015,70017-70070,70072-70077,70079-70080,70082-70118,70124-70125,70127-70130,70133-70135,70137-70148,70150-70152,70154-70165,70168,70170-70175,70177,70179-70196,70198-70260,70262-70266,70268-70270,70272,70274-70281,70308,70342-70367,70369-70442,70444-70453,70455-70462,70464-70465,70467-70468,70489,70499,70518-70530,70532,70534-70537,70539-70543,70545-70551,70554-70563,70565-70600,70602-70650,70652-70671,70673-70701,70703-70706,70712,70714-70715,70717-70718,70720-70733,70735-70746,70748-70756,70758-70771,70773-70774,70776-70806,70808-70820,70822-70824,70826-70829,70831-70837,70839-70843,70845-70855,70857,70859-70873,70875,70878-70900,70903-70917,70919-70939,70941-70957,70959-70968,70970-70980,70982-70985,70987-70992,70995-71025,71027-71028,71030,71032-71069,71071-71072,71074,71076-71077,71079-71081,71083-71126,71128-71174,71176-71205,71207-71252,71254-71299,71301,71303-71360,71362-71364,71366,71368-71369,71371-71376,71378-71379,71381-71384,71386-71388,71390-71391,71393-71407,71409-71418,71420-71429,71431-71434,71436-71447,71449-71461,71463-71506,71508-71661,71663-71709,71711-71714,71716-71724,71726-71775,71777-71779,71781-71786,71788-71795,71797-71807,71809-71823,71825-71826,71828-71892,71894-71903,71905-71937,71939-71968,71970-72009,72011-72051,72054-72055,72057-72106,72108-72110,72112-72113,72115-72116,72118,72120-72125,72128-72136,72138-72154,72156-72166,72168-72172,72174-72177,72179,72181-72182,72185-72188,72190-72198,72201,72203-72209,72211-72245,72247-72249,72251-72262,72264-72266,72268,72270-72342,72344-72347,72349-72381,72383-72391,72393-72417,72420-72442,72444-72450,72452-72457,72459-72463,72465-72476,72479,72487-72508,72511,72513-72515,72518-72523,72525-72570,72572-72677,72679-72691,72695,72697-72709,72711-72773,72775-72785,72787-72790,72792-72804,72806-72822,72824-72827,72829-72879,72881,72883-72902,72904-72920,72922-72955,72957-72971,72974-72991,72993-73000,73003-73005,73007-73028,73030-73045,73047,73049-73075,73077-73144,73146-73162,73164-73173,73175-73181,73183,73185-73237,73239,73241-73242,73244-73251,73253-73269,73271,73273-73280,73283-73295,73297-73313,73315-73324,73327-73333,73335-73344,73346-73360,73363-73366,73368-73371,73373-73381,73383-73393,73398-73400,73403-73421,73424-73432,73434-73458,73460-73470,73473-73479,73481-73533,73535,73537-73539,73541-73545,73547-73562,73564-73606,73614-73615,73660,73665-73678,73680-73685,73687-73696,73698-73713,73715-73772,73775,73777-73811,73813-73818,73820,73823-73827,73834,73841,73864,73870-73876,73878-73883,73885-73887,73889-73890,73892-73908,73916,73921,73925-73926,73930-73943,73945-73970,73985-74013,74015-74024,74039-74042,74044,74051-74052,74072,74074-74079,74081-74097,74099,74101-74118,74120-74133,74135-74146,74148-74151,74153-74172,74174-74188,74190-74193,74195-74218,74220-74233,74235-74239,74241-74242,74244-74255,74257-74261,74265,74269,74277-74280,74282-74299,74301-74425,74427-74444,74446-74462,74464-74489,74491-74502,74504-74518,74520-74521,74524-74536,74538-74542,74544-74557,74559-74568,74571-74574,74576-74630,74632-74634,74638-74652,74654-74683,74685-74698,74700-74701,74703-74714,74716-74720,74722-74732,74735-74797,74799-74824,74826-74831,74833-74844,74846-74848,74850-74872,74874-74935,74938-74961,74963,74965-74980,74982-75016,75018-75021,75023-75083,75085-75090,75092-75114,75116-75130,75132-75142,75144-75146,75148-75163,75167-75170,75172-75180,75182-75195,75197-75263,75265-75267,75269-75280,75282-75292,75294-75303,75306-75309,75311-75317,75319-75366,75368-75390,75393-75406,75414,75416,75418,75422,75425-75433,75435,75437,75439-75445,75447-75477,75479-75481,75483-75505,75507-75509,75511-75528,75530-75585,75587-75619,75621-75649,75652,75656-75657,75659,75661-75663,75665,75667-75671,75673-75674,75676-75716,75719,75721,75723-75729,75732-75738,75740-75742,75744,75746-75823,75825-75843,75845,75847-75912,75914-75928,75930,75932-75970,75972-75973,75975-75978,75980-75990,75992-76000,76002,76004-76011,76013-76024,76026-76028,76030-76049,76054-76057,76059-76070,76072-76094,76096-76115,76117-76125,76127-76128,76130-76131,76133-76139,76142-76153,76155-76193,76195-76198,76200-76211,76213,76215-76224,76230,76245,76255,76260,76276,76282,76286-76294,76296-76308,76310-76322,76337 + /python/trunk:1-61437,61439-61441,61443-61453,61455-61474,61476-61477,61479-61485,61487-61488,61490,61493-61528,61530-61563,61565-61569,61571-61576,61578-61584,61586,61588-61589,61591-61778,61780-61809,61811-61866,61868-61870,61872-61874,61876-61877,61883-61903,61905-61935,61938-61939,61941-62004,62007-62014,62016-62018,62021-62022,62024,62027,62029,62031-62066,62068-62074,62076-62094,62096,62098,62100-62102,62104-62122,62124-62125,62127-62137,62139-62142,62144-62194,62196-62222,62224-62308,62311-62397,62399-62430,62432-62510,62512-62516,62519-62535,62537-62598,62600-62665,62667-62683,62685-62719,62721,62723-62792,62794-62796,62798-62860,62862-62864,62866-62878,62880-62883,62885-62887,62889-62899,62901-62911,62913-62916,62918-62919,62921-62922,62924-62942,62944-62959,62961,62963-62967,62969-62970,62972-62973,62975-62976,62978-62982,62984,62987-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63045,63047-63054,63056-63079,63081-63085,63087-63097,63099,63101-63104,63106-63107,63109-63113,63115-63128,63130-63133,63135-63144,63146-63148,63151-63152,63155-63165,63167-63176,63181-63186,63188-63190,63192-63194,63196-63206,63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63248,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63342,63344-63346,63348-63353,63355-63357,63359-63373,63375,63377-63380,63383,63385-63391,63393-63402,63404-63407,63411-63412,63416-63420,63423-63424,63427,63429,63431-63433,63435-63439,63441-63457,63459-63468,63470-63480,63482-63484,63492,63496-63497,63499-63512,63514-63527,63529-63536,63538-63544,63546,63548,63550-63567,63569-63585,63590-63596,63602,63608-63610,63612-63616,63619-63629,63631-63648,63650-63659,63661-63664,63666-63671,63673-63674,63676,63678,63680-63684,63687-63690,63692-63703,63705-63713,63715-63717,63720,63722-63724,63726-63735,63737,63739-63741,63743-63744,63746-63766,63768-63775,63777-63798,63801-63813,63815-63845,63847,63850-63860,63862,63864-63872,63874-63898,63900-63909,63911-63913,63915-63931,63933-63941,63944,63946-63960,63964,63966,63968-63981,63983-64015,64017,64020-64027,64029-64030,64032-64039,64041-64043,64046-64047,64049-64056,64059-64061,64063-64067,64070-64079,64081-64085,64087-64089,64091-64092,64094-64096,64098-64104,64106-64127,64130-64132,64134-64141,64143-64168,64170-64205,64207-64247,64249,64251-64253,64255-64370,64372-64385,64387-64391,64393-64397,64399,64401-64412,64414-64423,64425-64428,64430,64432-64435,64440-64452,64454-64455,64457-64461,64463-64470,64472-64488,64490-64497,64499-64507,64509-64510,64512-64515,64517-64519,64521-64526,64528-64534,64536-64545,64548-64553,64556-64571,64573-64577,64579,64581-64594,64596-64632,64634,64636-64648,64650-64672,64674-64701,64703-64761,64763-64790,64792-64853,64856-64857,64860,64862-64864,64867-64909,64911-64912,64914-64921,64923-64929,64931-64952,64954-64957,64959-64961,64963-64985,64987-65004,65006-65015,65017-65019,65021-65031,65033-65041,65043,65045,65047-65068,65071-65074,65076-65081,65083-65084,65086-65101,65103-65108,65110,65113-65171,65173-65192,65194-65197,65199-65204,65206-65216,65218-65265,65267-65283,65285-65288,65290-65309,65311,65313-65317,65319-65322,65324-65345,65347-65348,65350,65352,65354,65356-65381,65384-65385,65388-65390,65392,65394,65396-65401,65403-65421,65424,65426-65437,65439,65441,65443,65445,65447-65448,65450,65452,65454,65456,65458-65461,65463,65465-65466,65468-65476,65478-65487,65489-65505,65507,65509,65511,65513,65515,65517-65518,65520-65521,65523,65525-65562,65564-65577,65579-65583,65585,65587,65589-65605,65607-65612,65614,65616,65618,65620-65641,65643-65654,65656-65662,65664,65666-65678,65680-65709,65711-65715,65717-65718,65720,65722-65732,65734-65740,65743-65747,65749-65761,65763-65767,65769-65797,65799-65801,65804-65805,65807-65813,65815-65821,65823-65838,65840-65864,65866-65871,65873,65875-65879,65881-65890,65892,65894-65911,65913,65915-65916,65918-65921,65923-65925,65927-65994,65996-66003,66005-66012,66014-66038,66040-66042,66044-66057,66059-66087,66089-66099,66101-66113,66115-66118,66120-66122,66124-66126,66128-66134,66136,66138-66141,66143-66180,66183-66191,66193-66195,66198-66228,66230-66231,66233-66274,66276-66280,66283,66285-66300,66302-66309,66311-66315,66317-66318,66320-66331,66333-66385,66387-66389,66391-66414,66417-66421,66423-66446,66448-66449,66451-66497,66499-66501,66503,66505,66507-66553,66555-66565,66567,66570-66619,66621-66656,66658-66675,66677-66681,66683-66688,66690-66713,66715-66720,66722-66743,66745-66755,66757-66762,66766-66767,66769-66808,66811-66821,66823-66877,66879-67001,67003-67012,67014-67040,67042-67059,67062-67162,67164-67165,67167-67265,67267-67286,67288-67302,67304-67306,67308-67325,67327-67331,67333-67335,67337-67348,67350-67352,67354-67369,67371-67375,67377-67395,67397-67406,67408-67410,67412-67497,67499-67520,67522-67580,67582,67585-67586,67588-67600,67602-67613,67615-67618,67620-67693,67695-67745,67747,67749-67761,67763-67796,67798-67821,67823-67901,67903-67933,67936-67954,67956-67966,67968-67975,67977-67979,67981-68013,68015-68088,68090-68091,68093-68149,68151-68155,68157,68162,68164-68178,68180-68207,68210-68219,68221-68230,68232-68237,68239,68241-68242,68244-68394,68396-68423,68425,68427-68428,68431,68433-68438,68440-68486,68488-68520,68522-68531,68533-68543,68546-68558,68560-68561,68563-68564,68568,68570-68578,68581-68583,68585-68588,68590-68591,68593-68596,68598-68602,68606-68704,68706-68759,68761-68763,68765,68767-68771,68773-68784,68786-68788,68790-68791,68794-68802,68804,68806,68808-68812,68814-68825,68827-68828,68830,68832-68842,68844,68846-68849,68851-68852,68854-68891,68893-68924,68926,68928-68940,68943-68952,68954-68963,68965-68984,68986-68997,68999-69000,69002-69009,69011,69013,69015-69017,69019-69022,69024-69038,69040-69069,69071-69073,69075-69084,69086,69088-69133,69135-69145,69147-69148,69150-69160,69162-69226,69228-69236,69238-69239,69241,69243-69251,69254-69256,69258-69261,69263-69267,69269-69270,69274-69275,69277-69294,69296-69301,69306-69314,69316-69321,69323-69372,69375-69388,69390-69393,69395-69413,69415-69432,69434-69442,69444-69508,69510-69515,69517-69521,69523-69524,69526-69527,69529,69531-69545,69547-69560,69562-69569,69571-69572,69574-69577,69579-69603,69605-69609,69611-69638,69640-69671,69673-69684,69686-69688,69690-69708,69710-69714,69718-69738,69740-69742,69744-69747,69749-69750,69752-69756,69758-69760,69762-69764,69766-69769,69771,69773-69776,69778-69794,69796-69836,69839-69869,69872-69877,69879-69895,69897-69907,69909-69936,69938-69945,69947-69951,69954,69956-69958,69960-69980,69982,69984-69993,69995-69999,70001-70010,70012-70015,70017-70070,70072-70077,70079-70080,70082-70118,70124-70125,70127-70130,70133-70135,70137-70148,70150-70152,70154-70165,70168,70170-70175,70177,70179-70196,70198-70260,70262-70266,70268-70270,70272,70274-70281,70308,70342-70367,70369-70442,70444-70453,70455-70462,70464-70465,70467-70468,70489,70499,70518-70530,70532,70534-70537,70539-70543,70545-70551,70554-70563,70565-70600,70602-70650,70652-70671,70673-70701,70703-70706,70712,70714-70715,70717-70718,70720-70733,70735-70746,70748-70756,70758-70771,70773-70774,70776-70806,70808-70820,70822-70824,70826-70829,70831-70837,70839-70843,70845-70855,70857,70859-70873,70875,70878-70900,70903-70917,70919-70939,70941-70957,70959-70968,70970-70980,70982-70985,70987-70992,70995-71025,71027-71028,71030,71032-71069,71071-71072,71074,71076-71077,71079-71081,71083-71126,71128-71174,71176-71205,71207-71252,71254-71299,71301,71303-71360,71362-71364,71366,71368-71369,71371-71376,71378-71379,71381-71384,71386-71388,71390-71391,71393-71407,71409-71418,71420-71429,71431-71434,71436-71447,71449-71461,71463-71506,71508-71661,71663-71709,71711-71714,71716-71724,71726-71775,71777-71779,71781-71786,71788-71795,71797-71807,71809-71823,71825-71826,71828-71892,71894-71903,71905-71937,71939-71968,71970-72009,72011-72051,72054-72055,72057-72106,72108-72110,72112-72113,72115-72116,72118,72120-72125,72128-72136,72138-72154,72156-72166,72168-72172,72174-72177,72179,72181-72182,72185-72188,72190-72198,72201,72203-72209,72211-72245,72247-72249,72251-72262,72264-72266,72268,72270-72342,72344-72347,72349-72381,72383-72391,72393-72417,72420-72442,72444-72450,72452-72457,72459-72463,72465-72476,72479,72487-72508,72511,72513-72515,72518-72523,72525-72570,72572-72677,72679-72691,72695,72697-72709,72711-72773,72775-72785,72787-72790,72792-72804,72806-72822,72824-72827,72829-72879,72881,72883-72902,72904-72920,72922-72955,72957-72971,72974-72991,72993-73000,73003-73005,73007-73028,73030-73045,73047,73049-73075,73077-73144,73146-73162,73164-73173,73175-73181,73183,73185-73237,73239,73241-73242,73244-73251,73253-73269,73271,73273-73280,73283-73295,73297-73313,73315-73324,73327-73333,73335-73344,73346-73360,73363-73366,73368-73371,73373-73381,73383-73393,73398-73400,73403-73421,73424-73432,73434-73458,73460-73470,73473-73479,73481-73533,73535,73537-73539,73541-73545,73547-73562,73564-73606,73614-73615,73660,73665-73678,73680-73685,73687-73696,73698-73713,73715-73772,73775,73777-73811,73813-73818,73820,73823-73827,73834,73841,73864,73870-73876,73878-73883,73885-73887,73889-73890,73892-73908,73916,73921,73925-73926,73930-73943,73945-73970,73985-74013,74015-74024,74039-74042,74044,74051-74052,74072,74074-74079,74081-74097,74099,74101-74118,74120-74133,74135-74146,74148-74151,74153-74172,74174-74188,74190-74193,74195-74218,74220-74233,74235-74239,74241-74242,74244-74255,74257-74261,74265,74269,74277-74280,74282-74299,74301-74425,74427-74444,74446-74462,74464-74489,74491-74502,74504-74518,74520-74521,74524-74536,74538-74542,74544-74557,74559-74568,74571-74574,74576-74630,74632-74634,74638-74652,74654-74683,74685-74698,74700-74701,74703-74714,74716-74720,74722-74732,74735-74797,74799-74824,74826-74831,74833-74844,74846-74848,74850-74872,74874-74935,74938-74961,74963,74965-74980,74982-75016,75018-75021,75023-75083,75085-75090,75092-75114,75116-75130,75132-75142,75144-75146,75148-75163,75167-75170,75172-75180,75182-75195,75197-75263,75265-75267,75269-75280,75282-75292,75294-75303,75306-75309,75311-75317,75319-75366,75368-75390,75393-75406,75414,75416,75418,75422,75425-75433,75435,75437,75439-75445,75447-75477,75479-75481,75483-75505,75507-75509,75511-75528,75530-75585,75587-75619,75621-75649,75652,75656-75657,75659,75661-75663,75665,75667-75671,75673-75674,75676-75716,75719,75721,75723-75729,75732-75738,75740-75742,75744,75746-75823,75825-75843,75845,75847-75912,75914-75928,75930,75932-75970,75972-75973,75975-75978,75980-75990,75992-76000,76002,76004-76011,76013-76024,76026-76028,76030-76049,76054-76057,76059-76070,76072-76094,76096-76115,76117-76125,76127-76128,76130-76131,76133-76139,76142-76153,76155-76193,76195-76198,76200-76211,76213,76215-76224,76230,76245,76255,76260,76276,76282,76286-76294,76296-76322,76337 Index: Misc/NEWS =================================================================== --- Misc/NEWS (révision 76338) +++ Misc/NEWS (copie de travail) @@ -137,6 +137,9 @@ Library ------- +- Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using + TLS or SSL. Patch by Giampaolo Rodola'. + - Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch - Issue #4969: The mimetypes module now reads the MIME database from Index: Doc/library/ftplib.rst =================================================================== --- Doc/library/ftplib.rst (révision 76338) +++ Doc/library/ftplib.rst (copie de travail) @@ -46,6 +46,42 @@ connection attempt (if is not specified, the global default timeout setting will be used). +.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, timeout]]]) + + A :class:`FTP` subclass which adds TLS support to FTP as described in + :rfc:`4217`. + Connect as usual to port 21 implicitly securing the FTP control connection + before authenticating. Securing the data connection requires user to + explicitly ask for it by calling :exc:`prot_p()` method. + *keyfile* and *certfile* are optional - they can contain a PEM formatted + private key and certificate chain file for the SSL connection. + + .. versionadded:: 3.2 Contributed by Giampaolo Rodola' + + + Here's a sample session using :class:`FTP_TLS` class: + + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + >>> ftps.prot_p() # switch to secure data connection + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + >>> + + + .. attribute:: all_errors The set of all exceptions (as a tuple) that methods of :class:`FTP` @@ -312,3 +348,26 @@ :meth:`close` or :meth:`quit` you cannot reopen the connection by issuing another :meth:`login` method). + +FTP_TLS Objects +--------------- + +:class:`FTP_TLS` class inherits from :class:`FTP`, defining these additional objects: + +.. attribute:: FTP_TLS.ssl_version + + The SSL version to use (defaults to *TLSv1*). + +.. method:: FTP_TLS.auth() + + Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute. + +.. method:: FTP_TLS.prot_p() + + Set up secure data connection. + +.. method:: FTP_TLS.prot_c() + + Set up clear text data connection. + + Index: Lib/ftplib.py =================================================================== --- Lib/ftplib.py (révision 76338) +++ Lib/ftplib.py (copie de travail) @@ -33,6 +33,7 @@ # Modified by Jack to work on the mac. # Modified by Siebren to support docstrings and PASV. # Modified by Phil Schwartz to add storbinary and storlines callbacks. +# Modified by Giampaolo Rodola' to add TLS support. # import os @@ -577,6 +578,181 @@ self.file = self.sock = None +try: + import ssl +except ImportError: + pass +else: + class FTP_TLS(FTP): + '''A FTP subclass which adds TLS support to FTP as described + in RFC-4217. + + Connect as usual to port 21 implicitly securing the FTP control + connection before authenticating. + + Securing the data connection requires user to explicitly ask + for it by calling prot_p() method. + + Usage example: + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + '230 Guest login ok, access restrictions apply.' + >>> ftps.prot_p() # switch to secure data connection + '200 Protection level set to P' + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + '221 Goodbye.' + >>> + ''' + ssl_version = ssl.PROTOCOL_TLSv1 + + def __init__(self, host='', user='', passwd='', acct='', keyfile=None, + certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + self.keyfile = keyfile + self.certfile = certfile + self._prot_p = False + FTP.__init__(self, host, user, passwd, acct, timeout) + + def login(self, user='', passwd='', acct='', secure=True): + if secure and not isinstance(self.sock, ssl.SSLSocket): + self.auth() + return FTP.login(self, user, passwd, acct) + + def auth(self): + '''Set up secure control connection by using TLS/SSL.''' + if isinstance(self.sock, ssl.SSLSocket): + raise ValueError("Already using TLS") + if self.ssl_version == ssl.PROTOCOL_TLSv1: + resp = self.voidcmd('AUTH TLS') + else: + resp = self.voidcmd('AUTH SSL') + self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + self.file = self.sock.makefile(mode='r', encoding=self.encoding) + return resp + + def prot_p(self): + '''Set up secure data connection.''' + # PROT defines whether or not the data channel is to be protected. + # Though RFC-2228 defines four possible protection levels, + # RFC-4217 only recommends two, Clear and Private. + # Clear (PROT C) means that no security is to be used on the + # data-channel, Private (PROT P) means that the data-channel + # should be protected by TLS. + # PBSZ command MUST still be issued, but must have a parameter of + # '0' to indicate that no buffering is taking place and the data + # connection should not be encapsulated. + self.voidcmd('PBSZ 0') + resp = self.voidcmd('PROT P') + self._prot_p = True + return resp + + def prot_c(self): + '''Set up clear text data connection.''' + resp = self.voidcmd('PROT C') + self._prot_p = False + return resp + + # --- Overridden FTP methods + + def ntransfercmd(self, cmd, rest=None): + conn, size = FTP.ntransfercmd(self, cmd, rest) + if self._prot_p: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + return conn, size + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + try: + while 1: + data = conn.recv(blocksize) + if not data: + break + callback(data) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def retrlines(self, cmd, callback = None): + if callback is None: callback = print_line + resp = self.sendcmd('TYPE A') + conn = self.transfercmd(cmd) + fp = conn.makefile('r', encoding=self.encoding) + try: + while 1: + line = fp.readline() + if self.debugging > 2: print('*retr*', repr(line)) + if not line: + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] == '\n': + line = line[:-1] + callback(line) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + fp.close() + conn.close() + return self.voidresp() + + def storbinary(self, cmd, fp, blocksize=8192, callback=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.read(blocksize) + if not buf: break + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def storlines(self, cmd, fp, callback=None): + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.readline() + if not buf: break + if buf[-2:] != B_CRLF: + if buf[-1] in B_CRLF: buf = buf[:-1] + buf = buf + B_CRLF + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + __all__.append('FTP_TLS') + all_errors = (Error, IOError, EOFError, ssl.SSLError) + + _150_re = None def parse150(resp): Index: Lib/asyncore.py =================================================================== --- Lib/asyncore.py (révision 76338) +++ Lib/asyncore.py (copie de travail) @@ -136,6 +136,7 @@ r, w, e = select.select(r, w, e, timeout) except select.error as err: if err.args[0] != EINTR: + print("r, w, e:", r, w, e) raise else: return Index: Lib/test/test_ftplib.py =================================================================== --- Lib/test/test_ftplib.py (révision 76338) +++ Lib/test/test_ftplib.py (copie de travail) @@ -1,6 +1,7 @@ """Test script for ftplib module.""" -# Modified by Giampaolo Rodola' to test FTP class and IPv6 environment +# Modified by Giampaolo Rodola' to test FTP class, IPv6 and TLS +# environment import ftplib import threading @@ -8,6 +9,12 @@ import asynchat import socket import io +import errno +import os +try: + import ssl +except ImportError: + ssl = None from unittest import TestCase from test import support @@ -40,6 +47,8 @@ class DummyFTPHandler(asynchat.async_chat): + dtp_handler = DummyDTPHandler + def __init__(self, conn): asynchat.async_chat.__init__(self, conn) self.set_terminator(b"\r\n") @@ -83,7 +92,7 @@ ip = '%d.%d.%d.%d' %tuple(addr[:4]) port = (addr[4] * 256) + addr[5] s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_pasv(self, arg): @@ -95,13 +104,13 @@ ip = ip.replace('.', ','); p1 = port / 256; p2 = port % 256 self.push('227 entering passive mode (%s,%d,%d)' %(ip, p1, p2)) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_eprt(self, arg): af, ip, port = arg.split(arg[0])[1:-1] port = int(port) s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_epsv(self, arg): @@ -112,7 +121,7 @@ port = sock.getsockname()[1] self.push('229 entering extended passive mode (|||%d|)' %port) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_echo(self, arg): # sends back the received string (used by the test suite) @@ -227,6 +236,128 @@ raise +if ssl is not None: + + CERTFILE = os.path.join(os.path.dirname(__file__), "keycert.pem") + + class SSLConnection(asyncore.dispatcher): + """An asyncore.dispatcher subclass supporting TLS/SSL.""" + + _ssl_accepting = False + + def secure_connection(self): + socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False, + certfile=CERTFILE, server_side=True, + do_handshake_on_connect=False, + ssl_version=ssl.PROTOCOL_SSLv23) + self.del_channel() + self.set_socket(socket) + self._ssl_accepting = True + + def _do_ssl_handshake(self): + try: + self.socket.do_handshake() + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE): + return + elif err.args[0] == ssl.SSL_ERROR_EOF: + return self.handle_close() + raise + except socket.error as err: + if err.args[0] == errno.ECONNABORTED: + return self.handle_close() + else: + self._ssl_accepting = False + + def handle_read_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_read_event() + + def handle_write_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_write_event() + + def send(self, data): + try: + return super(SSLConnection, self).send(data) + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + return 0 + raise + + def recv(self, buffer_size): + try: + return super(SSLConnection, self).recv(buffer_size) + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + self.handle_close() + return b'' + raise + + def handle_error(self): + raise + + def close(self): + try: + if isinstance(self.socket, ssl.SSLSocket): + if self.socket._sslobj is not None: + self.socket.unwrap() + finally: + super(SSLConnection, self).close() + + + class DummyTLS_DTPHandler(SSLConnection, DummyDTPHandler): + """A DummyDTPHandler subclass supporting TLS/SSL.""" + + def __init__(self, conn, baseclass): + DummyDTPHandler.__init__(self, conn, baseclass) + if self.baseclass.secure_data_channel: + self.secure_connection() + + + class DummyTLS_FTPHandler(SSLConnection, DummyFTPHandler): + """A DummyFTPHandler subclass supporting TLS/SSL.""" + + dtp_handler = DummyTLS_DTPHandler + + def __init__(self, conn): + DummyFTPHandler.__init__(self, conn) + self.secure_data_channel = False + + def cmd_auth(self, line): + """Set up secure control channel.""" + self.push('234 AUTH TLS successful') + self.secure_connection() + + def cmd_pbsz(self, line): + """Negotiate size of buffer for secure data transfer. + For TLS/SSL the only valid value for the parameter is '0'. + Any other value is accepted but ignored. + """ + self.push('200 PBSZ=0 successful.') + + def cmd_prot(self, line): + """Setup un/secure data channel.""" + arg = line.upper() + if arg == 'C': + self.push('200 Protection set to Clear') + self.secure_data_channel = False + elif arg == 'P': + self.push('200 Protection set to Private') + self.secure_data_channel = True + else: + self.push("502 Unrecognized PROT type (use C or P).") + + + class DummyTLS_FTPServer(DummyFTPServer): + handler = DummyTLS_FTPHandler + + class TestFTPClass(TestCase): def setUp(self): @@ -404,6 +535,81 @@ retr() +class TestTLS_FTPClassMixin(TestFTPClass): + """Repeat TestFTPClass tests starting the TLS layer for both control + and data connections first. + """ + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + # enable TLS + self.client.auth() + self.client.prot_p() + + +class TestTLS_FTPClass(TestCase): + """Specific TLS_FTP class tests.""" + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + + def tearDown(self): + self.client.close() + self.server.stop() + + def test_control_connection(self): + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.auth() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + + def test_data_connection(self): + # clear text + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # secured, after PROT P + self.client.prot_p() + sock = self.client.transfercmd('list') + self.assertTrue(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # PROT C is issued, the connection must be in cleartext again + self.client.prot_c() + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + def test_login(self): + # login() is supposed to implicitly secure the control connection + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.login() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + # make sure that AUTH TLS doesn't get issued again + self.client.login() + + def test_auth_issued_twice(self): + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + + def test_auth_ssl(self): + try: + self.client.ssl_version = ssl.PROTOCOL_SSLv3 + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + finally: + self.client.ssl_version = ssl.PROTOCOL_TLSv1 + + class TestTimeouts(TestCase): def setUp(self): @@ -505,6 +711,10 @@ pass else: tests.append(TestIPv6Environment) + + if ssl is not None: + tests.extend([TestTLS_FTPClassMixin, TestTLS_FTPClass]) + thread_info = support.threading_setup() try: support.run_unittest(*tests)